Develop and Download Open Source Software

Browse CVS Repository

Annotation of /gikonavigoeson/gikonavi/ItemDownload.pas

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.16 - (hide annotations) (download) (as text)
Fri Nov 21 17:24:50 2003 UTC (20 years, 5 months ago) by yoffy
Branch: MAIN
Changes since 1.15: +2 -1 lines
File MIME type: text/x-pascal
・今まで 1 つ固定であった BBS が複数持てるようになった。
 これにより、多くの2ちゃんねる特有の処理が排除され使えなくなった可能性がある。

以下注意。
 お気に入りファイルのフォーマットが変更になった(確定)。
 巡回ファイルのフォーマットが変更になったかもしれない(不明)。
 他にもあるかも。

1 hi_ 1.1 unit ItemDownload;
2    
3     interface
4    
5     uses
6 yoffy 1.7 Windows, SysUtils, Classes, ComCtrls, Controls, Forms, IdHTTP,
7 yoffy 1.2 {HTTPApp,} YofUtils, IdGlobal, IdException, IdComponent, IniFiles, {DateUtils,}
8 yoffy 1.7 GikoSystem, BoardGroup, MonaUtils, ExternalBoardManager;
9 hi_ 1.1
10     type
11     TDownloadItem = class;
12     TGikoDownloadType = (gdtBoard, gdtThread);
13     TGikoDownloadState = (gdsWait, gdsWork, gdsComplete, gdsDiffComplete, gdsNotModify, gdsAbort, gdsError);
14     TGikoCgiStatus = (gcsOK, gcsINCR, gcsERR);
15     TGikoDLProgress = (gdpStd, gdpAll, gdpDatOchi, gdpOfflaw);
16    
17     TGikoWorkEvent = procedure(Sender: TObject; AWorkMode: TWorkMode; const AWorkCount: Integer; ID: Integer) of object;
18     TGikoWorkBeginEvent = procedure(Sender: TObject; AWorkMode: TWorkMode; const AWorkCountMax: Integer; ID: Integer) of object;
19     TGikoWorkEndEvent = procedure(Sender: TObject; AWorkMode: TWorkMode; ID: Integer) of object;
20     TDownloadEndEvent = procedure(Sender: TObject; Item: TDownloadItem) of object;
21     TDownloadMsgEvent = procedure(Sender: TObject; Item: TDownloadItem; Msg: string; Icon: TGikoMessageIcon) of object;
22    
23     TCgiStatus = record
24     FStatus: TGikoCgiStatus;
25     FSize: Integer;
26     FErrText: string;
27     end;
28    
29    
30     TDownloadThread = class(TThread)
31     private
32     FIndy: TIdHttp;
33     FItem: TDownloadItem;
34     FNumber: Integer;
35     FAbort: Boolean;
36     FMsg: string;
37     FIcon: TGikoMessageIcon;
38     FSessionID: string;
39     FOnWork: TGikoWorkEvent;
40     FOnWorkBegin: TGikoWorkBeginEvent;
41     FOnWorkEnd: TGikoWorkEndEvent;
42     FOnDownloadEnd: TDownloadEndEvent;
43     FOnDownloadMsg: TDownloadMsgEvent;
44    
45     procedure FireDownloadEnd;
46     procedure FireDownloadMsg;
47     procedure GetSessionID;
48     procedure WorkBegin(Sender: TObject; AWorkMode: TWorkMode; const AWorkCountMax: Integer);
49     procedure WorkEnd(Sender: TObject; AWorkMode: TWorkMode);
50     procedure Work(Sender: TObject; AWorkMode: TWorkMode; const AWorkCount: Integer);
51     function ParseCgiStatus(Content: string): TCgiStatus;
52 yoffy 1.13 function CgiDownload(ItemType: TGikoDownloadType; URL: string; Modified: TDateTime): Boolean;
53 hi_ 1.1 function DatDownload(ItemType: TGikoDownloadType; URL: string; Modified: TDateTime; RangeStart: Integer; AdjustLen: Integer): Boolean;
54     function DeleteStatusLine(Content: string): string;
55     protected
56     procedure Execute; override;
57     public
58     property Item: TDownloadItem read FItem write FItem;
59     property Number: Integer read FNumber write FNumber;
60     constructor Create(CreateSuspended: Boolean);
61     destructor Destroy; override;
62     procedure Abort;
63     property OnWork: TGikoWorkEvent read FOnWork write FOnWork;
64     property OnWorkBegin: TGikoWorkBeginEvent read FOnWorkBegin write FOnWorkBegin;
65     property OnWorkEnd: TGikoWorkEndEvent read FOnWorkEnd write FOnWorkEnd;
66     property OnDownloadEnd: TDownloadEndEvent read FOnDownloadEnd write FOnDownloadEnd;
67     property OnDownloadMsg: TDownloadMsgEvent read FOnDownloadMsg write FOnDownloadMsg;
68     end;
69    
70     TDownloadItem = class(TObject)
71     private
72     FDownType: TGikoDownloadType;
73     FBoard: TBoard;
74     FThreadItem: TThreadItem;
75    
76     FContentLength: Integer;
77     FLastModified: TDateTime;
78     FContent: string;
79     FResponseCode: Smallint;
80     FState: TGikoDownloadState;
81     FErrText: string;
82     public
83     procedure SaveListFile;
84     procedure SaveItemFile;
85    
86     property DownType: TGikoDownloadType read FDownType write FDownType;
87     property Board: TBoard read FBoard write FBoard;
88     property ThreadItem: TThreadItem read FThreadItem write FThreadItem;
89    
90     property ContentLength: Integer read FContentLength write FContentLength;
91     property LastModified: TDateTime read FLastModified write FLastModified;
92     property Content: string read FContent write FContent;
93     property ResponseCode: Smallint read FResponseCode write FResponseCode;
94     property State: TGikoDownloadState read FState write FState;
95     property ErrText: string read FErrText write FErrText;
96     end;
97    
98     implementation
99    
100     constructor TDownloadThread.Create(CreateSuspended: Boolean);
101     begin
102     inherited Create(CreateSuspended);
103     FIndy := TIdHttp.Create(nil);
104    
105     FIndy.OnWorkBegin := WorkBegin;
106     FIndy.OnWorkEnd := WorkEnd;
107     FIndy.OnWork := Work;
108     end;
109    
110     destructor TDownloadThread.Destroy;
111     begin
112     FIndy.Free;
113     inherited;
114     end;
115    
116     function RFC1123_Date(aDate : TDateTime) : String;
117     const
118     StrWeekDay : String = 'MonTueWedThuFriSatSun';
119 yoffy 1.13 StrMonth : String = 'JanFebMarAprMayJunJulAugSepOctNovDec';
120 hi_ 1.1 var
121 yoffy 1.13 Year, Month, Day : Word;
122     Hour, Min, Sec, MSec : Word;
123     DayOfWeek : Word;
124 hi_ 1.1 begin
125     DecodeDate(aDate, Year, Month, Day);
126 yoffy 1.13 DecodeTime(aDate, Hour, Min, Sec, MSec);
127 hi_ 1.1 DayOfWeek := ((Trunc(aDate) - 2) mod 7);
128     Result := Copy(StrWeekDay, 1 + DayOfWeek * 3, 3) + ', ' +
129     Format('%2.2d %s %4.4d %2.2d:%2.2d:%2.2d',
130     [Day, Copy(StrMonth, 1 + 3 * (Month - 1), 3),
131     Year, Hour, Min, Sec]);
132     end;
133    
134     procedure TDownloadThread.Execute;
135     var
136     ResStream: TMemoryStream;
137    
138     URL: string;
139     CgiStatus: TCgiStatus;
140     Modified: TDateTime;
141     RangeStart: Integer;
142     AdjustLen: Integer;
143     Idx: Integer;
144     ATitle: string;
145     DownloadResult: Boolean;
146     Abone: Boolean;
147 yoffy 1.13 foundPos: Integer;
148     boardPlugIn : TBoardPlugIn;
149     listContent : string;
150 hi_ 1.1 begin
151     while not Terminated do begin
152 yoffy 1.9 //===== 鐃?鐃緒申鐃?鐃?鐃緒申
153 yoffy 1.13 boardPlugIn := nil;
154     ExternalBoardManager.OnWork := Work;
155     ExternalBoardManager.OnWorkBegin := WorkBegin;
156     ExternalBoardManager.OnWorkEnd := WorkEnd;
157    
158     case FItem.FDownType of
159     gdtBoard:
160     begin
161     if FItem.FBoard <> nil then begin
162     if FItem.FBoard.IsBoardPlugInAvailable then begin
163     boardPlugIn := FItem.FBoard.BoardPlugIn;
164     Item.State := TGikoDownloadState( boardPlugIn.DownloadBoard( DWORD( FItem.FBoard ) ) );
165     end;
166     end;
167     end;
168     gdtThread:
169     begin
170     if FItem.FThreadItem <> nil then begin
171     if FItem.FThreadItem.IsBoardPlugInAvailable then begin
172     boardPlugIn := FItem.FThreadItem.BoardPlugIn;
173     Item.State := TGikoDownloadState( boardPlugIn.DownloadThread( DWORD( FItem.FThreadItem ) ) );
174     end;
175     end;
176     end;
177     end;
178    
179     if boardPlugIn <> nil then begin
180     if FAbort then
181     Item.State := gdsAbort;
182     if Assigned( OnDownloadEnd ) then
183     Synchronize( FireDownloadEnd );
184     if Terminated then
185     Break;
186    
187     Suspend;
188     Continue;
189     end;
190 yoffy 1.9
191     //===== 鐃?鐃緒申鐃?鐃?鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申
192 hi_ 1.1 FAbort := False;
193     FIndy.Request.CustomHeaders.Clear;
194     FIndy.Response.Clear;
195     FIndy.Request.Clear;
196 yoffy 1.14 FIndy.ProxyParams.Clear;
197     FIndy.Disconnect;
198 hi_ 1.1 FIndy.Request.UserAgent := GikoSys.GetUserAgent;
199     FIndy.RecvBufferSize := Gikosys.Setting.RecvBufferSize;
200     FIndy.ProxyParams.BasicAuthentication := False;
201     {$IFDEF DEBUG}
202     Writeln('------------------------------------------------------------');
203     {$ENDIF}
204     //FIndy.AllowCookies := False;
205     if GikoSys.Setting.ReadProxy then begin
206     if GikoSys.Setting.ProxyProtocol then
207     FIndy.ProtocolVersion := pv1_1
208     else
209     FIndy.ProtocolVersion := pv1_0;
210     FIndy.ProxyParams.ProxyServer := GikoSys.Setting.ReadProxyAddress;
211     FIndy.ProxyParams.ProxyPort := GikoSys.Setting.ReadProxyPort;
212     FIndy.ProxyParams.ProxyUsername := GikoSys.Setting.ReadProxyUserID;
213     FIndy.ProxyParams.ProxyPassword := GikoSys.Setting.ReadProxyPassword;
214     if GikoSys.Setting.ReadProxyUserID <> '' then
215     FIndy.ProxyParams.BasicAuthentication := True;
216     {$IFDEF DEBUG}
217     Writeln('鐃?鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申');
218     Writeln('鐃?鐃?鐃?: ' + GikoSys.Setting.ReadProxyAddress);
219     Writeln('鐃?鐃?鐃?: ' + IntToStr(GikoSys.Setting.ReadProxyPort));
220     {$ENDIF}
221     end else begin
222     if GikoSys.Setting.Protocol then
223     FIndy.ProtocolVersion := pv1_1
224     else
225     FIndy.ProtocolVersion := pv1_0;
226     FIndy.ProxyParams.ProxyServer := '';
227     FIndy.ProxyParams.ProxyPort := 80;
228     FIndy.ProxyParams.ProxyUsername := '';
229     FIndy.ProxyParams.ProxyPassword := '';
230     {$IFDEF DEBUG}
231     Writeln('鐃?鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申');
232     {$ENDIF}
233     end;
234    
235     FIndy.Request.ContentRangeStart := 0;
236     FIndy.Request.LastModified := ZERO_DATE;
237     ResStream := TMemoryStream.Create;
238     try
239     try
240     //********************
241     //DAT or Subject鐃緒申鐃緒申
242     //********************
243     Item.ResponseCode := 0;
244     RangeStart := 0;
245     AdjustLen := 0;
246     Modified := 0;
247     if Item.DownType = gdtBoard then begin
248     {$IFDEF DEBUG}
249     Writeln('Subject鐃緒申鐃緒申');
250     Writeln('URL: ' + Item.Board.GetReadCgiURL);
251     Writeln('Modified: ' + FloatToStr(Item.Board.LastModified));
252     {$ENDIF}
253     URL := Item.Board.GetReadCgiURL;
254     Modified := Item.Board.LastModified;
255     end else if Item.DownType = gdtThread then begin
256     {$IFDEF DEBUG}
257     Writeln('DAT鐃緒申鐃緒申');
258     Writeln('URL: ' + Item.ThreadItem.GetDatURL);
259     Writeln('Modified: ' + FloatToStr(Item.ThreadItem.LastModified));
260     {$ENDIF}
261     URL := Item.ThreadItem.GetDatURL;
262     Modified := Item.ThreadItem.LastModified;
263     if Item.ThreadItem.Size > 0 then begin
264     {$IFDEF DEBUG}
265     Writeln('RangeStart: ' + IntToStr(Item.ThreadItem.Size));
266     {$ENDIF}
267     //鐃緒申鐃緒申鐃?鐃緒申鐃?鐃?鐃?鐃?鐃緒申鐃緒申鐃緒申鐃?鐃?鐃?鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申
268     RangeStart := Item.ThreadItem.Size;
269     AdjustLen := -1;
270     end;
271     end;
272     Abone := False;
273     DownloadResult := DatDownload(Item.DownType, URL, Modified, RangeStart, AdjustLen);
274     {$IFDEF DEBUG}
275     Writeln('ResponseCode: ' + IntToStr(FIndy.ResponseCode));
276     {$ENDIF}
277     if Item.DownType = gdtThread then begin
278     if Item.ResponseCode = 416 then begin
279     Abone := True;
280     DownloadResult := True;
281     end else if DownloadResult and (AdjustLen = -1) and (Item.Content[1] <> #10) then
282     Abone := True;
283     end;
284    
285     if Trim(FIndy.Response.RawHeaders.Values['Date']) <> '' then begin
286     if Item.DownType = gdtBoard then
287     Item.Board.LastGetTime := MonaUtils.DateStrToDateTime(FIndy.Response.RawHeaders.Values['Date'])
288     else
289     Item.ThreadItem.ParentBoard.LastGetTime := MonaUtils.DateStrToDateTime(FIndy.Response.RawHeaders.Values['Date']);
290     end;
291    
292     if DownloadResult then begin
293     {$IFDEF DEBUG}
294     Writeln('Date:' + FIndy.Response.RawHeaders.Values['Date']);
295     {$ENDIF}
296     if Abone then begin
297     {$IFDEF DEBUG}
298     Writeln('鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃?');
299     {$ENDIF}
300     ATitle := Item.ThreadItem.Title;
301     if ATitle = '' then
302     ATitle := '鐃?鐃緒申鐃緒申鐃?鐃緒申鐃?';
303     //鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃?鐃?鐃?鐃緒申鐃緒申LF鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃?鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申
304     RangeStart := 0;
305     AdjustLen := 0;
306     FMsg := '鐃緒申鐃?鐃緒申鐃緒申鐃?鐃緒申鐃?鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申 - [' + ATitle + ']';
307     FIcon := gmiWhat;
308 yoffy 1.13 if FileExists(ChangeFileExt(Item.FThreadItem.GetThreadFileName,'.NG')) = true then
309     DeleteFile(ChangeFileExt(Item.FThreadItem.GetThreadFileName,'.NG'));
310 hi_ 1.1 if Assigned(OnDownloadMsg) then
311     Synchronize(FireDownloadMsg);
312     if not DatDownload(Item.DownType, URL, ZERO_DATE, RangeStart, AdjustLen) then
313     Item.State := gdsError;
314     {$IFDEF DEBUG}
315     Writeln('鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申');
316     Writeln('ResponseCode: ' + IntToStr(Item.ResponseCode));
317     {$ENDIF}
318     end else if (Item.DownType = gdtThread) and (AdjustLen = -1) and (Item.Content[1] = #10) then begin
319     //鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃?鐃?鐃?鐃緒申鐃緒申LF鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申LF鐃緒申鐃緒申鐃緒申
320     Item.Content := Copy(Item.Content, 2, Length(Item.Content));
321     end;
322     end else begin
323     Item.State := gdsError;
324     if (Item.DownType = gdtBoard) and (Item.ResponseCode = 302) then begin
325     FMsg := '鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申';
326     FIcon := gmiNG;
327     if Assigned(OnDownloadMsg) then
328     Synchronize(FireDownloadMsg);
329     end;
330     end;
331    
332     //********************
333     //dat.gz鐃緒申鐃緒申(1)
334     //********************
335     if (Item.DownType = gdtThread) and (Item.ResponseCode = 302) then begin
336     {$IFDEF DEBUG}
337     Writeln('dat.gz鐃緒申鐃緒申');
338     {$ENDIF}
339     ATitle := Item.ThreadItem.Title;
340     if ATitle = '' then
341     ATitle := '鐃?鐃緒申鐃緒申鐃?鐃緒申鐃?';
342     FMsg := '鐃緒申dat鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?(dat.gz)鐃緒申鐃?鐃緒申鐃緒申鐃緒申 - [' + ATitle + ']';
343     FIcon := gmiWhat;
344     if Assigned(OnDownloadMsg) then
345     Synchronize(FireDownloadMsg);
346     URL := Item.ThreadItem.GetDatgzURL;
347     Modified := Item.ThreadItem.LastModified;
348     RangeStart := 0;
349     AdjustLen := 0;
350     if not DatDownload(Item.DownType, URL, Modified, RangeStart, AdjustLen) then
351     Item.State := gdsError;
352     {$IFDEF DEBUG}
353     Writeln('ResponseCode: ' + IntToStr(Item.ResponseCode));
354     {$ENDIF}
355     end;
356    
357     //********************
358     //dat.gz鐃緒申鐃緒申(2)
359     //********************
360     {
361     if (Item.DownType = gdtThread) and (Item.ResponseCode = 302) then begin
362     ATitle := Item.ThreadItem.Title;
363     if ATitle = '' then
364     ATitle := '鐃?鐃緒申鐃緒申鐃?鐃緒申鐃?';
365     FMsg := '鐃緒申鐃緒申鐃緒申鐃緒申鐃?(1)鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?(2)鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申 - [' + ATitle + ']';
366     FIcon := gmiWhat;
367     if Assigned(OnDownloadMsg) then
368     Synchronize(FireDownloadMsg);
369     URL := Item.ThreadItem.GetOldDatgzURL;
370     Modified := Item.ThreadItem.LastModified;
371     RangeStart := 0;
372     AdjustLen := 0;
373     if not DatDownload(Item.DownType, URL, Modified, RangeStart, AdjustLen) then
374     Item.State := gdsError;
375     end;
376     }
377    
378     //********************
379     //offlaw.cgi鐃緒申鐃緒申鐃緒申
380     //********************
381     FSessionID := '';
382     Synchronize(GetSessionID);
383     if (Item.DownType = gdtThread) and (Item.ResponseCode = 302) and (FSessionID <> '') then begin
384     {$IFDEF DEBUG}
385     Writeln('offlaw.cgi鐃緒申鐃緒申鐃緒申');
386     {$ENDIF}
387     ATitle := Item.ThreadItem.Title;
388     if ATitle = '' then
389     ATitle := '鐃?鐃緒申鐃緒申鐃?鐃緒申鐃?';
390     FMsg := '鐃緒申dat.gz鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申offlaw.cgi鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申 - [' + ATitle + ']';
391     FIcon := gmiWhat;
392     if Assigned(OnDownloadMsg) then
393     Synchronize(FireDownloadMsg);
394     URL := Item.ThreadItem.GetOfflawCgiURL(FSessionID);
395     Modified := Item.ThreadItem.LastModified;
396     RangeStart := 0;
397     AdjustLen := 0;
398     if not DatDownload(Item.DownType, URL, Modified, RangeStart, AdjustLen) then begin
399     {$IFDEF DEBUG}
400     Writeln('ResponseCode: ' + IntToStr(Item.ResponseCode));
401     {$ENDIF}
402     Item.State := gdsError;
403    
404     if (Item.DownType = gdtThread) and (Item.ResponseCode = 302) then begin
405     FMsg := '鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?';
406     FIcon := gmiNG;
407     if Assigned(OnDownloadMsg) then
408     Synchronize(FireDownloadMsg);
409     end;
410    
411     end else begin
412     CgiStatus := ParseCgiStatus(Item.Content);
413     {$IFDEF DEBUG}
414     Writeln('ResponseCode: ' + IntToStr(Item.ResponseCode));
415     {$ENDIF}
416     case CgiStatus.FStatus of
417     gcsOK: begin
418     {$IFDEF DEBUG}
419     Writeln('CGIStatus: OK');
420     {$ENDIF}
421     Item.ResponseCode := 200;
422     Item.Content := DeleteStatusLine(Item.Content);
423     Item.ContentLength := CgiStatus.FSize;
424     end;
425     gcsINCR: begin
426     //鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申
427     {$IFDEF DEBUG}
428     Writeln('CGIStatus: 206');
429     {$ENDIF}
430     Item.ResponseCode := 206;
431     Item.Content := DeleteStatusLine(Item.Content);
432     Item.ContentLength := CgiStatus.FSize;
433     end;
434     gcsERR: begin
435     {$IFDEF DEBUG}
436     Writeln('CGIStatus: 404(ERROR)');
437     {$ENDIF}
438     Item.ResponseCode := 404;
439     Item.State := gdsError;
440     Item.ErrText := CgiStatus.FErrText;
441     end;
442     end;
443     if (Item.ResponseCode = 404) and (AnsiPos('鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申', Item.ErrText) <> 0) then begin
444     {$IFDEF DEBUG}
445     Writeln('鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃緒申');
446     {$ENDIF}
447     ATitle := Item.ThreadItem.Title;
448     if ATitle = '' then
449     ATitle := '鐃?鐃緒申鐃緒申鐃?鐃緒申鐃?';
450     FMsg := '鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申 - [' + ATitle + ']';
451     FIcon := gmiWhat;
452     if Assigned(OnDownloadMsg) then
453     Synchronize(FireDownloadMsg);
454     Idx := Pos(' ', Item.ErrText);
455     if Idx <> 0 then begin
456     URL := Copy(Item.ErrText, Idx + 1, Length(Item.ErrText));
457     if Pos('../', URL) = 1 then
458     URL := Copy(URL, 4, Length(URL));
459     URL := GikoSys.UrlToServer(Item.ThreadItem.ParentBoard.URL) + URL;
460     Modified := Item.ThreadItem.LastModified;
461     RangeStart := 0;
462     AdjustLen := 0;
463     if not DatDownload(Item.DownType, URL, Modified, RangeStart, AdjustLen) then
464     Item.State := gdsError;
465     {$IFDEF DEBUG}
466     Writeln('ResponseCode: ' + IntToStr(Item.ResponseCode));
467     {$ENDIF}
468     end;
469     end;
470     end;
471     end else begin
472     if (Item.DownType = gdtThread) and (Item.ResponseCode = 302) and (FSessionID = '') then begin
473     {$IFDEF DEBUG}
474     Writeln('鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃?鐃緒申');
475     {$ENDIF}
476     ATitle := Item.ThreadItem.Title;
477     if ATitle = '' then
478     ATitle := '鐃?鐃緒申鐃緒申鐃?鐃緒申鐃?';
479     FMsg := '鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃緒申 - [' + ATitle + ']';
480     FIcon := gmiSAD;
481     if Assigned(OnDownloadMsg) then
482     Synchronize(FireDownloadMsg);
483     end;
484     end;
485    
486 yoffy 1.5 {$IFDEF DEBUG}
487     if (Item.DownType = gdtThread) and (Item.ResponseCode = 302) then begin
488     ATitle := Item.ThreadItem.Title;
489     if ATitle = '' then
490     ATitle := '鐃?鐃緒申鐃緒申鐃?鐃緒申鐃?';
491     FMsg := '鐃緒申鐃緒申鐃緒申鐃緒申鐃?(1)鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申google鐃?鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申 - [' + ATitle + ']';
492     FIcon := gmiWhat;
493     if Assigned(OnDownloadMsg) then
494     Synchronize(FireDownloadMsg);
495 yoffy 1.13 URL := 'http://www.google.co.jp/search?q=cache:' + Item.ThreadItem.URL;
496 yoffy 1.5 URL := StringReplace( URL, 'l50', '', [rfReplaceAll] );
497     Modified := Item.ThreadItem.LastModified;
498 yoffy 1.13 Repeat
499     if not CgiDownload(Item.DownType, URL, Modified) then
500     Item.State := gdsError;
501     URL := FIndy.Response.Location;
502     Until Item.ResponseCode <> 301;
503     if Item.ResponseCode = 200 then begin
504     foundPos := Pos( '<dt>', Item.Content ) + Length( '<dt>' );
505     Item.Content := Copy( Item.Content, foundPos, Length( Item.Content ) );
506     foundPos := Pos( '</dl>', Item.Content );
507     If foundPos > 0 Then
508     Item.Content := Copy( Item.Content, 1, foundPos - 1 );
509     Item.Content := StringReplace( Item.Content, '<dt>', '<>' + #13#10, [rfReplaceAll] );
510     Item.Content := StringReplace( Item.Content, '<a href="mailto:', '', [rfReplaceAll] );
511     Item.Content := StringReplace( Item.Content, '"><b>', '<>', [rfReplaceAll] );
512     Item.Content := StringReplace( Item.Content, '<b>', '<>', [rfReplaceAll] );
513     Item.Content := StringReplace( Item.Content, '</b></a>', '<>', [rfReplaceAll] );
514     Item.Content := StringReplace( Item.Content, '</b>', '<>', [rfReplaceAll] );
515     Item.Content := StringReplace( Item.Content, '<dd>', '<>', [rfReplaceAll] );
516     end;
517 yoffy 1.5 end;
518     {$ENDIF}
519    
520 hi_ 1.1 case Item.ResponseCode of
521     200: Item.State := gdsComplete;
522     206: Item.State := gdsDiffComplete;
523     304: Item.State := gdsNotModify;
524     else
525     Item.State := gdsError;
526     end;
527     {
528     //鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃?鐃?鐃?
529     if (Item.ResponseCode in [200, 206]) and (Item.Content = '') then
530     Item.State := gdsError;
531     Item.LastModified := FIndy.Response.LastModified;
532     //鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃?鐃?鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃?/span>C鐃?/span>i鐃?/span>X鐃緒申鐃緒申
533     Item.ContentLength := FIndy.Response.ContentLength + AdjustLen;
534     try
535     ResStream.Clear;
536     FIndy.Get(URL, ResStream);
537     Item.Content := GikoSys.GzipDecompress(ResStream, FIndy.Response.ContentEncoding);
538     if (Item.DownType = gdtThread) and (AdjustLen = -1) and (Item.Content[1] <> #10) then begin
539     //鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃?鐃?鐃?鐃緒申鐃緒申LF鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃?鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申
540     //鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃?鐃?鐃?鐃?鐃緒申鐃?鐃?鐃緒申鐃?
541     //event
542     FMsg := '鐃?鐃緒申鐃緒申鐃?鐃緒申鐃?鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申';
543     if Assigned(OnDownloadMsg) then
544     Synchronize(FireDownloadMsg);
545     FIndy.Request.ContentRangeStart := 0;
546     FIndy.Request.ContentRangeEnd := 0;
547     AdjustLen := 0;
548     ResStream.Clear;
549     FIndy.Get(URL, ResStream);
550     Item.Content := GikoSys.GzipDecompress(ResStream, FIndy.Response.ContentEncoding);
551     end else if (Item.DownType = gdtThread) and (AdjustLen = -1) and (Item.Content[1] = #10) then begin
552     //鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃?鐃?鐃?鐃緒申鐃緒申LF鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申LF鐃緒申鐃緒申鐃緒申
553     Item.Content := Copy(Item.Content, 2, Length(Item.Content));
554     end;
555     except
556     Item.State := gdsError;
557     end;
558     Item.ResponseCode := FIndy.ResponseCode;
559     }
560     {
561     try
562     ResStream.Clear;
563     FIndy.Get(URL, ResStream);
564     Item.Content := GikoSys.GzipDecompress(ResStream, FIndy.Response.ContentEncoding);
565     except
566     Item.State := gdsError;
567     end;
568    
569     CgiStatus := ParseCgiStatus(Item.Content);
570     if CgiStatus.FStatus = gcsOK then begin
571     if CgiStatus.FSize = 0 then
572     Item.State := gdsNotModify
573     else if Item.DownType = gdtBoard then
574     Item.State := gdsComplete
575     else
576     Item.State := gdsDiffComplete;
577     end else if CgiStatus.FStatus = gcsINCR then begin
578     Item.State := gdsComplete;
579     end else if CgiStatus.FStatus = gcsERR then begin
580     Item.State := gdsError;
581     Item.ErrText := CgiStatus.FErrText;
582     end;
583     Item.ContentLength := CgiStatus.FSize;
584     }
585     except
586     Item.State := gdsError;
587     end;
588     //Item.ResponseCode := FIndy.ResponseCode;
589     if FAbort then
590     Item.State := gdsAbort;
591     finally
592     if Assigned(OnDownloadEnd) then
593     Synchronize(FireDownloadEnd);
594     ResStream.Free;
595     end;
596     if Terminated then Break;
597     Suspend;
598 yoffy 1.5 end;
599     end;
600    
601     function TDownloadThread.CgiDownload(ItemType: TGikoDownloadType; URL: string; Modified: TDateTime): Boolean;
602     var
603     ResponseCode: Integer;
604     ResStream: TMemoryStream;
605     begin
606     ResponseCode := -1;
607     FIndy.Request.ContentRangeStart := 0;
608     FIndy.Request.ContentRangeEnd := 0;
609    
610     FIndy.Request.CustomHeaders.Clear;
611     if (Modified <> 0) and (Modified <> ZERO_DATE) then begin
612     FIndy.Request.LastModified := modified - OffsetFromUTC;
613     end;
614     FIndy.Request.AcceptEncoding := '';
615 yoffy 1.13 FIndy.Request.Accept := 'text/html';
616 yoffy 1.5 ResStream := TMemoryStream.Create;
617     try
618     try
619     ResStream.Clear;
620     {$IFDEF DEBUG}
621     Writeln('URL: ' + URL);
622     {$ENDIF}
623     FIndy.Get(URL, ResStream);
624     Item.Content := GikoSys.GzipDecompress(ResStream, FIndy.Response.ContentEncoding);
625     Item.LastModified := FIndy.Response.LastModified;
626     //鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃?鐃?鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃?鐃?鐃?鐃緒申鐃緒申
627     Item.ContentLength := Length(Item.Content);
628     //鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃?鐃?鐃?
629     if Item.Content = '' then
630     Result := False
631     else
632     Result := True;
633     {$IFDEF DEBUG}
634     Writeln('鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃緒申');
635     {$ENDIF}
636     ResponseCode := FIndy.ResponseCode;
637     except
638     on E: EIdSocketError do begin
639     Item.Content := '';
640     Item.LastModified := ZERO_DATE;
641     Item.ContentLength := 0;
642     Item.ErrText := E.Message;
643     Result := False;
644     ResponseCode := -1;
645 yoffy 1.13 Screen.Cursor := crDefault;
646 yoffy 1.5 end;
647     on E: EIdConnectException do begin
648     Item.Content := '';
649     Item.LastModified := ZERO_DATE;
650     Item.ContentLength := 0;
651     Item.ErrText := E.Message;
652     Result := False;
653     ResponseCode := -1;
654 yoffy 1.13 Screen.Cursor := crDefault;
655 yoffy 1.5 end;
656     on E: Exception do begin
657     {$IFDEF DEBUG}
658     Writeln('鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃緒申');
659     Writeln('E.Message: ' + E.Message);
660     {$ENDIF}
661     Item.Content := '';
662     Item.LastModified := ZERO_DATE;
663     Item.ContentLength := 0;
664     Item.ErrText := E.Message;
665     ResponseCode := FIndy.ResponseCode;
666     Result := False;
667 yoffy 1.13 Screen.Cursor := crDefault;
668 yoffy 1.5 end;
669     end;
670     finally
671     if (Item.ContentLength = 0) and (ResponseCode = 206) then
672     Item.ResponseCode := 304
673     else
674     Item.ResponseCode := ResponseCode;
675     ResStream.Free;
676 hi_ 1.1 end;
677     end;
678    
679     function TDownloadThread.DatDownload(ItemType: TGikoDownloadType; URL: string; Modified: TDateTime; RangeStart: Integer; AdjustLen: Integer): Boolean;
680     var
681     ResponseCode: Integer;
682     ResStream: TMemoryStream;
683     begin
684     ResponseCode := -1;
685     if (ItemType = gdtThread) and (RangeStart > 0) then begin
686     // if (ItemType = gdtThread) and (Item.ThreadItem.Size > 0) then begin
687     // FIndy.Request.ContentRangeStart := Item.ThreadItem.Size + AdjustLen;
688     FIndy.Request.ContentRangeStart := RangeStart + AdjustLen;
689     FIndy.Request.ContentRangeEnd := 0;
690     end else begin
691     FIndy.Request.ContentRangeStart := 0;
692     FIndy.Request.ContentRangeEnd := 0;
693     end;
694    
695     FIndy.Request.CustomHeaders.Clear;
696     FIndy.Request.CacheControl := 'no-cache';
697     FIndy.Request.CustomHeaders.Add('Pragma: no-cache');
698     if (Modified <> 0) and (Modified <> ZERO_DATE) then begin
699     FIndy.Request.LastModified := modified - OffsetFromUTC;
700     //FIndy.Request.CustomHeaders.Add('If-Modified-Since: ' + RFC1123_Date(modified - OffsetFromUTC) + ' GMT');
701     end;
702     // FIndy.Request.AcceptEncoding := 'gzip';
703     if RangeStart = 0 then
704     FIndy.Request.AcceptEncoding := 'gzip'
705     else
706     FIndy.Request.AcceptEncoding := '';
707     ResStream := TMemoryStream.Create;
708     try
709     try
710     ResStream.Clear;
711     {$IFDEF DEBUG}
712     Writeln('URL: ' + URL);
713     {$ENDIF}
714     FIndy.Get(URL, ResStream);
715     Item.Content := GikoSys.GzipDecompress(ResStream, FIndy.Response.ContentEncoding);
716     Item.LastModified := FIndy.Response.LastModified;
717     //鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃?鐃?鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃?鐃?鐃?鐃緒申鐃緒申
718     // Item.ContentLength := FIndy.Response.ContentLength + AdjustLen;
719     Item.ContentLength := Length(Item.Content) + AdjustLen;
720     //鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃?鐃?鐃?
721     // if (FIndy.ResponseCode in [200, 206]) and (Item.Content = '') then
722     // Result := False
723     if Item.Content = '' then
724     Result := False
725     else
726     Result := True;
727     {$IFDEF DEBUG}
728     Writeln('鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃緒申');
729     {$ENDIF}
730     ResponseCode := FIndy.ResponseCode;
731     except
732     on E: EIdSocketError do begin
733     Item.Content := '';
734     Item.LastModified := ZERO_DATE;
735     Item.ContentLength := 0;
736     Item.ErrText := E.Message;
737     Result := False;
738     ResponseCode := -1;
739 yoffy 1.13 Screen.Cursor := crDefault;
740 hi_ 1.1 end;
741     on E: EIdConnectException do begin
742     Item.Content := '';
743     Item.LastModified := ZERO_DATE;
744     Item.ContentLength := 0;
745     Item.ErrText := E.Message;
746     Result := False;
747     ResponseCode := -1;
748 yoffy 1.13 Screen.Cursor := crDefault;
749 hi_ 1.1 end;
750     on E: Exception do begin
751     {$IFDEF DEBUG}
752     Writeln('鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃緒申');
753     Writeln('E.Message: ' + E.Message);
754     {$ENDIF}
755     Item.Content := '';
756     Item.LastModified := ZERO_DATE;
757     Item.ContentLength := 0;
758     Item.ErrText := E.Message;
759     ResponseCode := FIndy.ResponseCode;
760     Result := False;
761 yoffy 1.13 Screen.Cursor := crDefault;
762 hi_ 1.1 end;
763     end;
764     finally
765     if (Item.ContentLength = 0) and (ResponseCode = 206) then
766     Item.ResponseCode := 304
767     else
768     Item.ResponseCode := ResponseCode;
769     ResStream.Free;
770     end;
771     end;
772    
773     procedure TDownloadThread.FireDownloadEnd;
774     begin
775     OnDownloadEnd(self, Item);
776     end;
777    
778     procedure TDownloadThread.FireDownloadMsg;
779     begin
780     OnDownloadMsg(Self, Item, FMsg, FIcon);
781     end;
782    
783     procedure TDownloadThread.GetSessionID;
784     begin
785     FSessionID := GikoSys.Dolib.SessionID;
786     end;
787    
788     procedure TDownloadThread.Abort;
789     begin
790     FAbort := True;
791     FIndy.DisconnectSocket;
792     end;
793    
794     procedure TDownloadThread.WorkBegin(Sender: TObject; AWorkMode: TWorkMode; const AWorkCountMax: Integer);
795     begin
796     if Assigned(OnWorkBegin) then
797     OnWorkBegin(Sender, AWorkMode, AWorkCountMax, FNumber);
798     end;
799    
800     procedure TDownloadThread.WorkEnd(Sender: TObject; AWorkMode: TWorkMode);
801     begin
802     if Assigned(OnWorkEnd) then
803     OnWorkEnd(Sender, AWorkMode, FNumber);
804     end;
805    
806     procedure TDownloadThread.Work(Sender: TObject; AWorkMode: TWorkMode; const AWorkCount: Integer);
807     begin
808     if Assigned(OnWork) then
809     OnWork(Sender, AWorkMode, AWorkCount, FNumber);
810     end;
811    
812     function TDownloadThread.ParseCgiStatus(Content: string): TCgiStatus;
813     var
814     StatusLine: string;
815     Line: string;
816     Idx: Integer;
817     Status: string;
818     Size: string;
819     Msg: string;
820     begin
821     // [+OK] 鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申
822     // [-INCR] (Incorrect)鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃?鐃?
823     // [-ERR (鐃?鐃?鐃?鐃?)]鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃?
824     // 鐃緒申鐃?+OK 23094/512K
825 yoffy 1.13 // -INCR 23094/512K
826     // -ERR 鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申
827 hi_ 1.1 Idx := AnsiPos(#10, Content);
828     StatusLine := Copy(Content, 0, Idx);
829    
830     Idx := AnsiPos(' ', Content);
831     Status := Copy(StatusLine, 0, Idx - 1);
832     Line := Copy(StatusLine, Idx + 1, Length(StatusLine));
833    
834     // Idx := AnsiPos('/', Line);
835     if Trim(Status) = '-ERR' then
836     Msg := Trim(Line)
837     else
838     Size := Copy(Line, 0, Idx - 1);
839    
840     if Trim(Status) = '+OK' then
841     Result.FStatus := gcsOK
842     else if Trim(Status) = '-INCR' then
843     Result.FStatus := gcsINCR
844     else if Trim(Status) = '-ERR' then begin
845     Result.FStatus := gcsERR;
846     Result.FErrText := Msg;
847     Result.FSize := 0;
848     Exit;
849     end else begin
850     {$IFDEF DEBUG}
851     Writeln(Status);
852     {$ENDIF}
853     Result.FStatus := gcsERR;
854     Result.FErrText := '鐃?鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃?';
855     Result.FSize := 0;
856     Exit;
857     end;
858    
859     if GikoSys.IsNumeric(Size) then
860     Result.FSize := StrToInt(Size)
861     else begin
862     Result.FSize := 0;
863     Result.FStatus := gcsERR;
864     Result.FErrText := '鐃?鐃?鐃?鐃?鐃?鐃緒申鐃緒申鐃緒申鐃?[' + StatusLine + ']';
865     end;
866     end;
867    
868     //鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申1鐃?鐃緒申鐃緒申鐃緒申鐃緒申
869     function TDownloadThread.DeleteStatusLine(Content: string): string;
870     var
871     SList: TStringList;
872     begin
873     SList := TStringList.Create;
874     try
875     SList.Text := Content;
876     if SList.Count > 1 then
877     SList.Delete(0);
878     Result := SList.Text;
879     finally
880     SList.Free;
881     end;
882     end;
883    
884     procedure TDownloadItem.SaveListFile;
885     var
886     i: Integer;
887     index: Integer;
888     NewItem: TThreadItem;
889     // SaveCount: Integer;
890     NumCount: Integer;
891     Body: TStringList;
892     Rec: TSubjectRec;
893 yoffy 1.9 function MakeThreadCallBack(
894 yoffy 1.13 inInstance : DWORD; // TBoardItem 鐃緒申鐃?鐃緒申鐃?鐃?鐃緒申鐃?
895 yoffy 1.10 inURL : PChar; // 鐃?鐃緒申鐃?鐃?鐃緒申 URL
896     inTitle : PChar; // 鐃?鐃緒申鐃?鐃?
897     inCount : DWORD // 鐃緒申鐃?鐃緒申鐃緒申
898     ) : Boolean; stdcall; // 鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申 True
899 yoffy 1.13 var
900     threadItem : TThreadItem;
901     boardItem : TBoard;
902     begin
903     Result := True;
904     boardItem := TBoard( inInstance );
905    
906     boardItem.IntData := boardItem.IntData + 1;
907     index := boardItem.GetIndexFromURL( string( inURL ) );
908     if index = -1 then begin
909     //鐃?鐃緒申鐃緒申鐃?鐃緒申鐃?鐃?
910     threadItem := TThreadItem.Create( boardItem.BoardPlugIn, string( inURL ) );
911 yoffy 1.9
912 yoffy 1.13 threadItem.Title := string( inTitle );
913 yoffy 1.10 // threadItem.Count := inCount;
914 yoffy 1.12 threadItem.AllResCount := inCount;
915 yoffy 1.13 threadItem.ParentBoard := Board;
916     threadItem.No := boardItem.IntData;
917     threadItem.RoundDate := ZERO_DATE;
918     threadItem.LastModified := ZERO_DATE;
919     threadItem.AgeSage := gasNew;
920     boardItem.ListData.Add( threadItem );
921     end else begin
922     //boardItem.Items[index].Count := Count;
923     //boardItem.Items[index].Count := Rec.FCount;
924     if boardItem.Items[index].No > boardItem.IntData then
925     boardItem.Items[index].AgeSage := gasAge
926     else if boardItem.Items[index].AllResCount < inCount then
927     boardItem.Items[index].AgeSage := gasSage
928     else
929     boardItem.Items[index].AgeSage := gasNone;
930 yoffy 1.9
931 yoffy 1.13 boardItem.Items[index].No := boardItem.IntData;
932     boardItem.Items[index].AllResCount := inCount;
933 yoffy 1.10 // if not boardItem.Items[index].IsLogFile then
934     // boardItem.Items[index].Count := inCountt;
935 yoffy 1.13 boardItem.ListData.Add( boardItem.Items[index] );
936     boardItem.DeleteList( index );
937     end;
938     end;
939 hi_ 1.1 begin
940 yoffy 1.10 Board.ListData := TList.Create;
941 hi_ 1.1 Body := TStringList.Create;
942     try
943     //鐃?鐃?鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申鐃?
944     Board.RoundDate := Now;
945     //鐃?鐃?鐃?鐃緒申鐃?鐃?鐃?鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申
946     Board.LastModified := LastModified;
947    
948 yoffy 1.13 if Board.IsBoardPlugInAvailable then begin
949     // 鐃?鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申
950     // 鐃?鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申
951     // 鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃?鐃緒申鐃?鐃?鐃?鐃?鐃?鐃?鐃緒申鐃緒申鐃緒申
952     Board.IntData := 0;
953     Board.BoardPlugIn.EnumThread( DWORD( Board ), @MakeThreadCallBack );
954    
955     // 鐃?鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃?鐃?鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申
956     for i := 0 to Board.Count - 1 do begin
957     if Board.Items[i].IsLogFile then begin
958     Board.IntData := Board.IntData + 1;
959     Board.Items[i].No := Board.IntData;
960     Board.Items[i].AllResCount := Board.Items[i].Count;
961     Board.Items[i].NewResCount := 0;
962     Board.Items[i].AgeSage := gasNone;
963     Board.ListData.Add( Board.Items[i] );
964     end;
965     end;
966    
967     // 鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃?鐃?鐃緒申鐃緒申鐃?鐃?鐃緒申鐃?鐃?鐃?鐃?鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?
968     for i := Board.Count - 1 downto 0 do
969     Board.DeleteList( i );
970    
971     // 鐃?鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃?鐃?鐃?鐃?鐃?鐃?鐃?鐃?鐃?鐃緒申鐃緒申鐃緒申
972     for i := 0 to Board.ListData.Count - 1 do
973     Board.Add( TThreadItem(Board.ListData[i]) );
974     end else begin
975     //鐃?鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申
976     //鐃?鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申
977     //鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃?鐃緒申鐃?鐃?鐃?鐃?鐃?鐃?鐃緒申鐃緒申鐃緒申
978     Body.Text := Content;
979     NumCount := 0;
980     for i := 0 to Body.Count - 1 do begin
981     //if i = 0 then Continue; //鐃?鐃?鐃緒申鐃緒申鐃?鐃?鐃?鐃?鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申
982    
983     Rec := GikoSys.DivideSubject(Body[i]);
984     Rec.FFileName := Trim(Rec.FFileName);
985     if (Rec.FTitle = '') and (Rec.FCount = 0) then Continue;
986     Inc(NumCount);
987     index := Board.GetIndex(Rec.FFileName);
988     if index = -1 then begin
989     //鐃?鐃緒申鐃緒申鐃?鐃緒申鐃?鐃?
990 yoffy 1.16 NewItem := TThreadItem.Create(
991     nil, GikoSys.Get2chBoard2ThreadURL( Board, ChangeFileExt( Rec.FFileName, '' ) ) );
992 yoffy 1.13 NewItem.FileName := Rec.FFileName;
993     NewItem.Title := Rec.FTitle;
994     // NewItem.Count := Rec.FCount;
995     NewItem.AllResCount := Rec.FCount;
996     NewItem.ParentBoard := Board;
997     NewItem.No := NumCount;
998     NewItem.RoundDate := ZERO_DATE;
999     NewItem.LastModified := ZERO_DATE;
1000     NewItem.AgeSage := gasNew;
1001     Board.ListData.Add(NewItem);
1002     end else begin
1003     //Board.Items[index].Count := Count;
1004     //Board.Items[index].Count := Rec.FCount;
1005     if Board.Items[index].No > NumCount then
1006     Board.Items[index].AgeSage := gasAge
1007     else if Board.Items[index].AllResCount < Rec.FCount then
1008     Board.Items[index].AgeSage := gasSage
1009     else
1010     Board.Items[index].AgeSage := gasNone;
1011    
1012    
1013     Board.Items[index].No := NumCount;
1014     Board.Items[index].AllResCount := Rec.FCount;
1015     // if not Board.Items[index].IsLogFile then
1016     // Board.Items[index].Count := Rec.FCount;
1017     Board.ListData.Add(Board.Items[index]);
1018     Board.DeleteList(index);
1019     end;
1020     end;
1021    
1022     //鐃?鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃?鐃?鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申
1023     for i := 0 to Board.Count - 1 do begin
1024     if Board.Items[i].IsLogFile then begin
1025     inc(NumCount);
1026     Board.Items[i].No := NumCount;
1027     Board.Items[i].AllResCount := Board.Items[i].Count;
1028     Board.Items[i].NewResCount := 0;
1029     Board.Items[i].AgeSage := gasNone;
1030     Board.ListData.Add(Board.Items[i]);
1031     end;
1032     end;
1033    
1034     //鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃?鐃?鐃緒申鐃緒申鐃?鐃?鐃緒申鐃?鐃?鐃?鐃?鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?
1035     for i := Board.Count - 1 downto 0 do
1036     Board.DeleteList(i);
1037    
1038     //鐃?鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃?鐃?鐃?鐃?鐃?鐃?鐃?鐃?鐃?鐃緒申鐃緒申鐃緒申
1039     for i := 0 to Board.ListData.Count - 1 do
1040     Board.Add(TThreadItem(Board.ListData[i]));
1041    
1042     //鐃緒申鐃?鐃?(subject.txt)鐃緒申鐃緒申鐃緒申
1043     // GikoSys.ForceDirectoriesEx(GikoSys.GetLogDir + Board.BBSID);
1044     // Body.SaveToFile(GikoSys.GetSubjectFileName(Board.BBSID));
1045     GikoSys.ForceDirectoriesEx(ExtractFilePath(Board.GetSubjectFileName));
1046     Body.SaveToFile(Board.GetSubjectFileName);
1047     end;
1048 hi_ 1.1 finally
1049     Body.Free;
1050 yoffy 1.10 Board.ListData.Free;
1051 hi_ 1.1 end;
1052     end;
1053    
1054     {procedure TDownloadItem.SaveListFile;
1055     var
1056     i: Integer;
1057     index: Integer;
1058     NewItem: TThreadItem;
1059     NewList: TList;
1060     // SaveCount: Integer;
1061     NumCount: Integer;
1062     Body: TStringList;
1063     Rec: TSubjectRec;
1064     begin
1065     NewList := TList.Create;
1066     Body := TStringList.Create;
1067     try
1068     //鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申
1069     Board.RoundDate := Now;
1070     //鐃?鐃?鐃?鐃緒申鐃?鐃?鐃?鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申
1071     Board.LastModified := LastModified;
1072    
1073     //鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申
1074     //SaveCount := MaxInt;
1075    
1076     //鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃?鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申
1077     for i := Board.Count - 1 downto 0 do
1078     if not Board.Items[i].IsLogFile then
1079     Board.Delete(i);
1080    
1081     //鐃?鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申
1082     //鐃?鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申
1083     //鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃?鐃緒申鐃?鐃?鐃?鐃?鐃?鐃?鐃緒申鐃緒申鐃緒申
1084     Body.Text := Content;
1085     // Loop := Min(Body.Count, SaveCount);
1086     NumCount := 0;
1087     // for i := 0 to Loop - 1 do begin
1088     for i := 0 to Body.Count - 1 do begin
1089     if i = 0 then Continue; //鐃?鐃?鐃緒申鐃緒申鐃?鐃?鐃?鐃?鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申
1090    
1091     Rec := GikoSys.DivideSubject(Body[i]);
1092     if (Rec.FTitle = '') and (Rec.FCount = 0) then Continue;
1093     Inc(NumCount);
1094     index := Board.GetIndex(Rec.FFileName);
1095     if index = -1 then begin
1096     NewItem := TThreadItem.Create;
1097     NewItem.FileName := Rec.FFileName;
1098     NewItem.Title := Rec.FTitle;
1099     NewItem.Count := Rec.FCount;
1100     NewItem.ParentBoard := Board;
1101     NewItem.No := NumCount;
1102     NewItem.RoundDate := ZERO_DATE;
1103     NewItem.LastModified := ZERO_DATE;
1104     NewList.Add(NewItem);
1105     end else begin
1106     //Board.Items[index].Count := Count;
1107     Board.Items[index].No := NumCount;
1108     NewList.Add(Board.Items[index]);
1109     Board.DeleteList(index);
1110     end;
1111     end;
1112    
1113     //鐃?鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃?鐃?鐃?鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申
1114     for i := 0 to Board.Count - 1 do begin
1115     inc(NumCount);
1116     Board.Items[i].No := NumCount;
1117     NewList.Add(Board.Items[i]);
1118     end;
1119    
1120     //鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃?鐃?鐃緒申鐃緒申鐃?鐃?鐃緒申鐃?鐃?鐃?鐃?鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?
1121     for i := Board.Count - 1 downto 0 do
1122     Board.DeleteList(i);
1123    
1124     //鐃?鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃?鐃?鐃?鐃?鐃?鐃?鐃?鐃?鐃?鐃緒申鐃緒申鐃緒申
1125     for i := 0 to NewList.Count - 1 do
1126     Board.Add(TThreadItem(NewList[i]));
1127    
1128     //鐃緒申鐃?鐃?(subject.txt)鐃緒申鐃緒申鐃緒申
1129     // GikoSys.ForceDirectoriesEx(GikoSys.GetLogDir + Board.BBSID);
1130     // Body.SaveToFile(GikoSys.GetSubjectFileName(Board.BBSID));
1131     GikoSys.ForceDirectoriesEx(ExtractFilePath(Board.GetSubjectFileName));
1132     Body.SaveToFile(Board.GetSubjectFileName);
1133     finally
1134     Body.Free;
1135     NewList.Free;
1136     end;
1137     end;
1138     }
1139     procedure TDownloadItem.SaveItemFile;
1140     var
1141     Body: TStringList;
1142     Cnt: Integer;
1143     OldCnt: Integer;
1144     FileName: string;
1145     ini: TMemIniFile;
1146     Res: TResRec;
1147     NewRes: Integer;
1148     begin
1149     FileName := ThreadItem.GetThreadFileName;
1150    
1151 yoffy 1.15 if not ThreadItem.IsBoardPlugInAvailable then begin
1152     if Trim(Content) = '' then
1153     Exit;
1154     GikoSys.ForceDirectoriesEx(ExtractFilePath(FileName));
1155    
1156     // Cnt := 0;
1157     Body := TStringList.Create;
1158     try
1159     // if FileExists(FileName) and (ResponseCode = 206) then begin
1160     if FileExists(FileName) and (State = gdsDiffComplete) then begin
1161     // Body.Text := Content;
1162     // if Body.Count > 0 then
1163     // Body.Delete(0);
1164     // Content := Body.Text;
1165     Body.LoadFromFile(FileName);
1166     OldCnt := Body.Count;
1167     Body.Text := Body.Text + Content;
1168     Body.SaveToFile(FileName);
1169     NewRes := Body.Count - OldCnt;
1170     Cnt := Body.Count;
1171     end else begin
1172     Body.Text := Content;
1173     // if Body.Count > 0 then
1174     // Body.Delete(0);
1175     Body.SaveToFile(FileName);
1176 hi_ 1.1
1177 yoffy 1.15 if ThreadItem.Title = '' then begin
1178     Res := GikoSys.DivideStrLine(Body[0]);
1179     ThreadItem.Title := Res.FTitle;
1180     end;
1181     ThreadItem.Size := 0;
1182     //ThreadItem.Count := 0;
1183     ThreadItem.AllResCount := 0;
1184     ThreadItem.NewResCount := 0;
1185     OldCnt := 0;
1186     NewRes := Body.Count;
1187     Cnt := Body.Count;
1188 hi_ 1.1 end;
1189     Cnt := Body.Count;
1190 yoffy 1.15 finally
1191     Body.Free;
1192 hi_ 1.1 end;
1193 yoffy 1.15 ThreadItem.Size := ThreadItem.Size + ContentLength;
1194     ThreadItem.LastModified := LastModified;
1195     ThreadItem.Count := Cnt;
1196     ThreadItem.AllResCount := Cnt;
1197     ThreadItem.NewResCount := NewRes;
1198     ThreadItem.NewReceive := OldCnt + 1;
1199 hi_ 1.1 end;
1200 yoffy 1.15
1201     ThreadItem.IsLogFile := True;
1202 hi_ 1.1 ThreadItem.RoundDate := Now;
1203     ThreadItem.UnRead := True;
1204     ThreadItem.ParentBoard.UnRead := ThreadItem.ParentBoard.UnRead + 1;
1205     // if ThreadItem.RoundNo = 6 then
1206     // ThreadItem.RoundNo := 0;
1207    
1208     //鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃?鐃?鐃?鐃?鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?
1209     //鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申
1210     //鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃?
1211     ini := TMemIniFile.Create(ChangeFileExt(FileName, '.tmp'));
1212     try
1213     ini.WriteDateTime('Setting', 'RoundDate', ThreadItem.RoundDate);
1214     ini.WriteDateTime('Setting', 'LastModified', ThreadItem.LastModified);
1215     ini.WriteInteger('Setting', 'Size', ThreadItem.Size);
1216     ini.WriteInteger('Setting', 'Count', ThreadItem.Count);
1217     ini.WriteInteger('Setting', 'AllResCount', ThreadItem.AllResCount);
1218     ini.WriteInteger('Setting', 'NewResCount', ThreadItem.NewResCount);
1219     ini.WriteInteger('Setting', 'NewReceive', ThreadItem.NewReceive);
1220     // ini.WriteInteger('Setting', 'RoundNo', ThreadItem.RoundNo);
1221     ini.WriteBool('Setting', 'Round', ThreadItem.Round);
1222     ini.WriteBool('Setting', 'UnRead', ThreadItem.UnRead);
1223     ini.UpdateFile;
1224     finally
1225     ini.Free;
1226     end;
1227     end;
1228    
1229     end.

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26