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.21 - (hide annotations) (download) (as text)
Sun Mar 7 12:56:13 2004 UTC (20 years, 1 month ago) by yoffy
Branch: MAIN
Changes since 1.20: +0 -34 lines
File MIME type: text/x-pascal
・google テストコードを削除。

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 yoffy 1.17 if Pos( '://', URL ) = 0 then begin
458     if Pos('../', URL) = 1 then
459     URL := Copy(URL, 4, MaxInt );
460     if Pos( '/', URL ) = 1 then
461     URL := Copy( URL, 2, MaxInt );
462     URL := GikoSys.UrlToServer(Item.ThreadItem.ParentBoard.URL) + URL;
463     end;
464 hi_ 1.1 Modified := Item.ThreadItem.LastModified;
465     RangeStart := 0;
466     AdjustLen := 0;
467     if not DatDownload(Item.DownType, URL, Modified, RangeStart, AdjustLen) then
468     Item.State := gdsError;
469     {$IFDEF DEBUG}
470     Writeln('ResponseCode: ' + IntToStr(Item.ResponseCode));
471     {$ENDIF}
472     end;
473     end;
474     end;
475     end else begin
476     if (Item.DownType = gdtThread) and (Item.ResponseCode = 302) and (FSessionID = '') then begin
477     {$IFDEF DEBUG}
478     Writeln('鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃?鐃緒申');
479     {$ENDIF}
480     ATitle := Item.ThreadItem.Title;
481     if ATitle = '' then
482     ATitle := '鐃?鐃緒申鐃緒申鐃?鐃緒申鐃?';
483     FMsg := '鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃緒申 - [' + ATitle + ']';
484     FIcon := gmiSAD;
485     if Assigned(OnDownloadMsg) then
486     Synchronize(FireDownloadMsg);
487     end;
488     end;
489    
490     case Item.ResponseCode of
491     200: Item.State := gdsComplete;
492     206: Item.State := gdsDiffComplete;
493     304: Item.State := gdsNotModify;
494     else
495     Item.State := gdsError;
496     end;
497     {
498     //鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃?鐃?鐃?
499     if (Item.ResponseCode in [200, 206]) and (Item.Content = '') then
500     Item.State := gdsError;
501     Item.LastModified := FIndy.Response.LastModified;
502     //鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃?鐃?鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃?/span>C鐃?/span>i鐃?/span>X鐃緒申鐃緒申
503     Item.ContentLength := FIndy.Response.ContentLength + AdjustLen;
504     try
505     ResStream.Clear;
506     FIndy.Get(URL, ResStream);
507     Item.Content := GikoSys.GzipDecompress(ResStream, FIndy.Response.ContentEncoding);
508     if (Item.DownType = gdtThread) and (AdjustLen = -1) and (Item.Content[1] <> #10) then begin
509     //鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃?鐃?鐃?鐃緒申鐃緒申LF鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃?鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申
510     //鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃?鐃?鐃?鐃?鐃緒申鐃?鐃?鐃緒申鐃?
511     //event
512     FMsg := '鐃?鐃緒申鐃緒申鐃?鐃緒申鐃?鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申';
513     if Assigned(OnDownloadMsg) then
514     Synchronize(FireDownloadMsg);
515     FIndy.Request.ContentRangeStart := 0;
516     FIndy.Request.ContentRangeEnd := 0;
517     AdjustLen := 0;
518     ResStream.Clear;
519     FIndy.Get(URL, ResStream);
520     Item.Content := GikoSys.GzipDecompress(ResStream, FIndy.Response.ContentEncoding);
521     end else if (Item.DownType = gdtThread) and (AdjustLen = -1) and (Item.Content[1] = #10) then begin
522     //鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃?鐃?鐃?鐃緒申鐃緒申LF鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申LF鐃緒申鐃緒申鐃緒申
523     Item.Content := Copy(Item.Content, 2, Length(Item.Content));
524     end;
525     except
526     Item.State := gdsError;
527     end;
528     Item.ResponseCode := FIndy.ResponseCode;
529     }
530     {
531     try
532     ResStream.Clear;
533     FIndy.Get(URL, ResStream);
534     Item.Content := GikoSys.GzipDecompress(ResStream, FIndy.Response.ContentEncoding);
535     except
536     Item.State := gdsError;
537     end;
538    
539     CgiStatus := ParseCgiStatus(Item.Content);
540     if CgiStatus.FStatus = gcsOK then begin
541     if CgiStatus.FSize = 0 then
542     Item.State := gdsNotModify
543     else if Item.DownType = gdtBoard then
544     Item.State := gdsComplete
545     else
546     Item.State := gdsDiffComplete;
547     end else if CgiStatus.FStatus = gcsINCR then begin
548     Item.State := gdsComplete;
549     end else if CgiStatus.FStatus = gcsERR then begin
550     Item.State := gdsError;
551     Item.ErrText := CgiStatus.FErrText;
552     end;
553     Item.ContentLength := CgiStatus.FSize;
554     }
555     except
556     Item.State := gdsError;
557     end;
558     //Item.ResponseCode := FIndy.ResponseCode;
559     if FAbort then
560     Item.State := gdsAbort;
561     finally
562     if Assigned(OnDownloadEnd) then
563     Synchronize(FireDownloadEnd);
564     ResStream.Free;
565     end;
566     if Terminated then Break;
567     Suspend;
568 yoffy 1.5 end;
569     end;
570    
571     function TDownloadThread.CgiDownload(ItemType: TGikoDownloadType; URL: string; Modified: TDateTime): Boolean;
572     var
573     ResponseCode: Integer;
574     ResStream: TMemoryStream;
575     begin
576     ResponseCode := -1;
577     FIndy.Request.ContentRangeStart := 0;
578     FIndy.Request.ContentRangeEnd := 0;
579    
580     FIndy.Request.CustomHeaders.Clear;
581     if (Modified <> 0) and (Modified <> ZERO_DATE) then begin
582     FIndy.Request.LastModified := modified - OffsetFromUTC;
583     end;
584     FIndy.Request.AcceptEncoding := '';
585 yoffy 1.13 FIndy.Request.Accept := 'text/html';
586 yoffy 1.5 ResStream := TMemoryStream.Create;
587     try
588     try
589     ResStream.Clear;
590     {$IFDEF DEBUG}
591     Writeln('URL: ' + URL);
592     {$ENDIF}
593     FIndy.Get(URL, ResStream);
594     Item.Content := GikoSys.GzipDecompress(ResStream, FIndy.Response.ContentEncoding);
595     Item.LastModified := FIndy.Response.LastModified;
596     //鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃?鐃?鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃?鐃?鐃?鐃緒申鐃緒申
597     Item.ContentLength := Length(Item.Content);
598     //鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃?鐃?鐃?
599     if Item.Content = '' then
600     Result := False
601     else
602     Result := True;
603     {$IFDEF DEBUG}
604     Writeln('鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃緒申');
605     {$ENDIF}
606     ResponseCode := FIndy.ResponseCode;
607     except
608     on E: EIdSocketError do begin
609     Item.Content := '';
610     Item.LastModified := ZERO_DATE;
611     Item.ContentLength := 0;
612     Item.ErrText := E.Message;
613     Result := False;
614     ResponseCode := -1;
615 yoffy 1.13 Screen.Cursor := crDefault;
616 yoffy 1.5 end;
617     on E: EIdConnectException do begin
618     Item.Content := '';
619     Item.LastModified := ZERO_DATE;
620     Item.ContentLength := 0;
621     Item.ErrText := E.Message;
622     Result := False;
623     ResponseCode := -1;
624 yoffy 1.13 Screen.Cursor := crDefault;
625 yoffy 1.5 end;
626     on E: Exception do begin
627     {$IFDEF DEBUG}
628     Writeln('鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃緒申');
629     Writeln('E.Message: ' + E.Message);
630     {$ENDIF}
631     Item.Content := '';
632     Item.LastModified := ZERO_DATE;
633     Item.ContentLength := 0;
634     Item.ErrText := E.Message;
635     ResponseCode := FIndy.ResponseCode;
636     Result := False;
637 yoffy 1.13 Screen.Cursor := crDefault;
638 yoffy 1.5 end;
639     end;
640     finally
641     if (Item.ContentLength = 0) and (ResponseCode = 206) then
642     Item.ResponseCode := 304
643     else
644     Item.ResponseCode := ResponseCode;
645     ResStream.Free;
646 hi_ 1.1 end;
647     end;
648    
649     function TDownloadThread.DatDownload(ItemType: TGikoDownloadType; URL: string; Modified: TDateTime; RangeStart: Integer; AdjustLen: Integer): Boolean;
650     var
651     ResponseCode: Integer;
652     ResStream: TMemoryStream;
653     begin
654     ResponseCode := -1;
655     if (ItemType = gdtThread) and (RangeStart > 0) then begin
656     // if (ItemType = gdtThread) and (Item.ThreadItem.Size > 0) then begin
657     // FIndy.Request.ContentRangeStart := Item.ThreadItem.Size + AdjustLen;
658     FIndy.Request.ContentRangeStart := RangeStart + AdjustLen;
659     FIndy.Request.ContentRangeEnd := 0;
660     end else begin
661     FIndy.Request.ContentRangeStart := 0;
662     FIndy.Request.ContentRangeEnd := 0;
663     end;
664    
665     FIndy.Request.CustomHeaders.Clear;
666     FIndy.Request.CacheControl := 'no-cache';
667     FIndy.Request.CustomHeaders.Add('Pragma: no-cache');
668     if (Modified <> 0) and (Modified <> ZERO_DATE) then begin
669     FIndy.Request.LastModified := modified - OffsetFromUTC;
670     //FIndy.Request.CustomHeaders.Add('If-Modified-Since: ' + RFC1123_Date(modified - OffsetFromUTC) + ' GMT');
671     end;
672     // FIndy.Request.AcceptEncoding := 'gzip';
673     if RangeStart = 0 then
674     FIndy.Request.AcceptEncoding := 'gzip'
675     else
676     FIndy.Request.AcceptEncoding := '';
677     ResStream := TMemoryStream.Create;
678     try
679     try
680     ResStream.Clear;
681     {$IFDEF DEBUG}
682     Writeln('URL: ' + URL);
683     {$ENDIF}
684     FIndy.Get(URL, ResStream);
685     Item.Content := GikoSys.GzipDecompress(ResStream, FIndy.Response.ContentEncoding);
686     Item.LastModified := FIndy.Response.LastModified;
687     //鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃?鐃?鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃?鐃?鐃?鐃緒申鐃緒申
688     // Item.ContentLength := FIndy.Response.ContentLength + AdjustLen;
689     Item.ContentLength := Length(Item.Content) + AdjustLen;
690     //鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃?鐃?鐃?
691     // if (FIndy.ResponseCode in [200, 206]) and (Item.Content = '') then
692     // Result := False
693     if Item.Content = '' then
694     Result := False
695     else
696     Result := True;
697     {$IFDEF DEBUG}
698     Writeln('鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃緒申');
699     {$ENDIF}
700     ResponseCode := FIndy.ResponseCode;
701     except
702     on E: EIdSocketError do begin
703     Item.Content := '';
704     Item.LastModified := ZERO_DATE;
705     Item.ContentLength := 0;
706     Item.ErrText := E.Message;
707     Result := False;
708     ResponseCode := -1;
709 yoffy 1.13 Screen.Cursor := crDefault;
710 hi_ 1.1 end;
711     on E: EIdConnectException do begin
712     Item.Content := '';
713     Item.LastModified := ZERO_DATE;
714     Item.ContentLength := 0;
715     Item.ErrText := E.Message;
716     Result := False;
717     ResponseCode := -1;
718 yoffy 1.13 Screen.Cursor := crDefault;
719 hi_ 1.1 end;
720     on E: Exception do begin
721     {$IFDEF DEBUG}
722     Writeln('鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃緒申');
723     Writeln('E.Message: ' + E.Message);
724     {$ENDIF}
725     Item.Content := '';
726     Item.LastModified := ZERO_DATE;
727     Item.ContentLength := 0;
728     Item.ErrText := E.Message;
729     ResponseCode := FIndy.ResponseCode;
730     Result := False;
731 yoffy 1.13 Screen.Cursor := crDefault;
732 hi_ 1.1 end;
733     end;
734     finally
735     if (Item.ContentLength = 0) and (ResponseCode = 206) then
736     Item.ResponseCode := 304
737     else
738     Item.ResponseCode := ResponseCode;
739     ResStream.Free;
740     end;
741     end;
742    
743     procedure TDownloadThread.FireDownloadEnd;
744     begin
745     OnDownloadEnd(self, Item);
746     end;
747    
748     procedure TDownloadThread.FireDownloadMsg;
749     begin
750     OnDownloadMsg(Self, Item, FMsg, FIcon);
751     end;
752    
753     procedure TDownloadThread.GetSessionID;
754     begin
755     FSessionID := GikoSys.Dolib.SessionID;
756     end;
757    
758     procedure TDownloadThread.Abort;
759     begin
760     FAbort := True;
761     FIndy.DisconnectSocket;
762     end;
763    
764     procedure TDownloadThread.WorkBegin(Sender: TObject; AWorkMode: TWorkMode; const AWorkCountMax: Integer);
765     begin
766     if Assigned(OnWorkBegin) then
767     OnWorkBegin(Sender, AWorkMode, AWorkCountMax, FNumber);
768     end;
769    
770     procedure TDownloadThread.WorkEnd(Sender: TObject; AWorkMode: TWorkMode);
771     begin
772     if Assigned(OnWorkEnd) then
773     OnWorkEnd(Sender, AWorkMode, FNumber);
774     end;
775    
776     procedure TDownloadThread.Work(Sender: TObject; AWorkMode: TWorkMode; const AWorkCount: Integer);
777     begin
778     if Assigned(OnWork) then
779     OnWork(Sender, AWorkMode, AWorkCount, FNumber);
780     end;
781    
782     function TDownloadThread.ParseCgiStatus(Content: string): TCgiStatus;
783     var
784     StatusLine: string;
785     Line: string;
786     Idx: Integer;
787     Status: string;
788     Size: string;
789     Msg: string;
790     begin
791     // [+OK] 鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申
792     // [-INCR] (Incorrect)鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃?鐃?
793     // [-ERR (鐃?鐃?鐃?鐃?)]鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃?
794     // 鐃緒申鐃?+OK 23094/512K
795 yoffy 1.13 // -INCR 23094/512K
796     // -ERR 鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申
797 hi_ 1.1 Idx := AnsiPos(#10, Content);
798     StatusLine := Copy(Content, 0, Idx);
799    
800     Idx := AnsiPos(' ', Content);
801     Status := Copy(StatusLine, 0, Idx - 1);
802     Line := Copy(StatusLine, Idx + 1, Length(StatusLine));
803    
804     // Idx := AnsiPos('/', Line);
805     if Trim(Status) = '-ERR' then
806     Msg := Trim(Line)
807     else
808     Size := Copy(Line, 0, Idx - 1);
809    
810     if Trim(Status) = '+OK' then
811     Result.FStatus := gcsOK
812     else if Trim(Status) = '-INCR' then
813     Result.FStatus := gcsINCR
814     else if Trim(Status) = '-ERR' then begin
815     Result.FStatus := gcsERR;
816     Result.FErrText := Msg;
817     Result.FSize := 0;
818     Exit;
819     end else begin
820     {$IFDEF DEBUG}
821     Writeln(Status);
822     {$ENDIF}
823     Result.FStatus := gcsERR;
824     Result.FErrText := '鐃?鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃?';
825     Result.FSize := 0;
826     Exit;
827     end;
828    
829     if GikoSys.IsNumeric(Size) then
830     Result.FSize := StrToInt(Size)
831     else begin
832     Result.FSize := 0;
833     Result.FStatus := gcsERR;
834     Result.FErrText := '鐃?鐃?鐃?鐃?鐃?鐃緒申鐃緒申鐃緒申鐃?[' + StatusLine + ']';
835     end;
836     end;
837    
838     //鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申1鐃?鐃緒申鐃緒申鐃緒申鐃緒申
839     function TDownloadThread.DeleteStatusLine(Content: string): string;
840     var
841     SList: TStringList;
842     begin
843     SList := TStringList.Create;
844     try
845     SList.Text := Content;
846     if SList.Count > 1 then
847     SList.Delete(0);
848     Result := SList.Text;
849     finally
850     SList.Free;
851     end;
852     end;
853    
854     procedure TDownloadItem.SaveListFile;
855     var
856     i: Integer;
857     index: Integer;
858     NewItem: TThreadItem;
859     // SaveCount: Integer;
860     NumCount: Integer;
861     Body: TStringList;
862     Rec: TSubjectRec;
863 yoffy 1.9 function MakeThreadCallBack(
864 yoffy 1.13 inInstance : DWORD; // TBoardItem 鐃緒申鐃?鐃緒申鐃?鐃?鐃緒申鐃?
865 yoffy 1.10 inURL : PChar; // 鐃?鐃緒申鐃?鐃?鐃緒申 URL
866     inTitle : PChar; // 鐃?鐃緒申鐃?鐃?
867     inCount : DWORD // 鐃緒申鐃?鐃緒申鐃緒申
868     ) : Boolean; stdcall; // 鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申 True
869 yoffy 1.13 var
870 yoffy 1.18 _ThreadItem : TThreadItem; // '_' 鐃緒申鐃?鐃緒申鐃?鐃緒申鐃?鐃緒申鐃?鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申
871 yoffy 1.13 boardItem : TBoard;
872     begin
873     Result := True;
874     boardItem := TBoard( inInstance );
875    
876     boardItem.IntData := boardItem.IntData + 1;
877     index := boardItem.GetIndexFromURL( string( inURL ) );
878     if index = -1 then begin
879     //鐃?鐃緒申鐃緒申鐃?鐃緒申鐃?鐃?
880 yoffy 1.18 _ThreadItem := TThreadItem.Create( boardItem.BoardPlugIn, string( inURL ) );
881 yoffy 1.9
882 yoffy 1.18 _ThreadItem.Title := string( inTitle );
883     _ThreadItem.AllResCount := inCount;
884     _ThreadItem.ParentBoard := Board;
885     _ThreadItem.No := boardItem.IntData;
886     _ThreadItem.RoundDate := ZERO_DATE;
887     _ThreadItem.LastModified := ZERO_DATE;
888     _ThreadItem.AgeSage := gasNew;
889     boardItem.ListData.Add( _ThreadItem );
890 yoffy 1.13 end else begin
891     if boardItem.Items[index].No > boardItem.IntData then
892     boardItem.Items[index].AgeSage := gasAge
893     else if boardItem.Items[index].AllResCount < inCount then
894     boardItem.Items[index].AgeSage := gasSage
895     else
896     boardItem.Items[index].AgeSage := gasNone;
897 yoffy 1.9
898 yoffy 1.13 boardItem.Items[index].No := boardItem.IntData;
899     boardItem.Items[index].AllResCount := inCount;
900     boardItem.ListData.Add( boardItem.Items[index] );
901     boardItem.DeleteList( index );
902     end;
903     end;
904 hi_ 1.1 begin
905 yoffy 1.10 Board.ListData := TList.Create;
906 hi_ 1.1 Body := TStringList.Create;
907     try
908     //鐃?鐃?鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申鐃?
909     Board.RoundDate := Now;
910     //鐃?鐃?鐃?鐃緒申鐃?鐃?鐃?鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申
911     Board.LastModified := LastModified;
912    
913 yoffy 1.13 if Board.IsBoardPlugInAvailable then begin
914     // 鐃?鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申
915     // 鐃?鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申
916     // 鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃?鐃緒申鐃?鐃?鐃?鐃?鐃?鐃?鐃緒申鐃緒申鐃緒申
917     Board.IntData := 0;
918     Board.BoardPlugIn.EnumThread( DWORD( Board ), @MakeThreadCallBack );
919    
920     // 鐃?鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃?鐃?鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申
921     for i := 0 to Board.Count - 1 do begin
922     if Board.Items[i].IsLogFile then begin
923     Board.IntData := Board.IntData + 1;
924     Board.Items[i].No := Board.IntData;
925     Board.Items[i].AllResCount := Board.Items[i].Count;
926     Board.Items[i].NewResCount := 0;
927     Board.Items[i].AgeSage := gasNone;
928     Board.ListData.Add( Board.Items[i] );
929     end;
930     end;
931    
932     // 鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃?鐃?鐃緒申鐃緒申鐃?鐃?鐃緒申鐃?鐃?鐃?鐃?鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?
933     for i := Board.Count - 1 downto 0 do
934     Board.DeleteList( i );
935    
936     // 鐃?鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃?鐃?鐃?鐃?鐃?鐃?鐃?鐃?鐃?鐃緒申鐃緒申鐃緒申
937     for i := 0 to Board.ListData.Count - 1 do
938     Board.Add( TThreadItem(Board.ListData[i]) );
939     end else begin
940     //鐃?鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申
941     //鐃?鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申
942     //鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃?鐃緒申鐃?鐃?鐃?鐃?鐃?鐃?鐃緒申鐃緒申鐃緒申
943     Body.Text := Content;
944     NumCount := 0;
945     for i := 0 to Body.Count - 1 do begin
946     //if i = 0 then Continue; //鐃?鐃?鐃緒申鐃緒申鐃?鐃?鐃?鐃?鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申
947    
948     Rec := GikoSys.DivideSubject(Body[i]);
949     Rec.FFileName := Trim(Rec.FFileName);
950     if (Rec.FTitle = '') and (Rec.FCount = 0) then Continue;
951     Inc(NumCount);
952     index := Board.GetIndex(Rec.FFileName);
953     if index = -1 then begin
954     //鐃?鐃緒申鐃緒申鐃?鐃緒申鐃?鐃?
955 yoffy 1.16 NewItem := TThreadItem.Create(
956     nil, GikoSys.Get2chBoard2ThreadURL( Board, ChangeFileExt( Rec.FFileName, '' ) ) );
957 yoffy 1.13 NewItem.Title := Rec.FTitle;
958     NewItem.AllResCount := Rec.FCount;
959     NewItem.ParentBoard := Board;
960     NewItem.No := NumCount;
961     NewItem.RoundDate := ZERO_DATE;
962     NewItem.LastModified := ZERO_DATE;
963     NewItem.AgeSage := gasNew;
964     Board.ListData.Add(NewItem);
965     end else begin
966     if Board.Items[index].No > NumCount then
967     Board.Items[index].AgeSage := gasAge
968     else if Board.Items[index].AllResCount < Rec.FCount then
969     Board.Items[index].AgeSage := gasSage
970     else
971     Board.Items[index].AgeSage := gasNone;
972    
973     Board.Items[index].No := NumCount;
974     Board.Items[index].AllResCount := Rec.FCount;
975     Board.ListData.Add(Board.Items[index]);
976     Board.DeleteList(index);
977     end;
978     end;
979    
980     //鐃?鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃?鐃?鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申
981     for i := 0 to Board.Count - 1 do begin
982     if Board.Items[i].IsLogFile then begin
983     inc(NumCount);
984     Board.Items[i].No := NumCount;
985     Board.Items[i].AllResCount := Board.Items[i].Count;
986     Board.Items[i].NewResCount := 0;
987     Board.Items[i].AgeSage := gasNone;
988     Board.ListData.Add(Board.Items[i]);
989     end;
990     end;
991    
992     //鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃?鐃?鐃緒申鐃緒申鐃?鐃?鐃緒申鐃?鐃?鐃?鐃?鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?
993     for i := Board.Count - 1 downto 0 do
994     Board.DeleteList(i);
995    
996     //鐃?鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃?鐃?鐃?鐃?鐃?鐃?鐃?鐃?鐃?鐃緒申鐃緒申鐃緒申
997     for i := 0 to Board.ListData.Count - 1 do
998     Board.Add(TThreadItem(Board.ListData[i]));
999    
1000     //鐃緒申鐃?鐃?(subject.txt)鐃緒申鐃緒申鐃緒申
1001     // GikoSys.ForceDirectoriesEx(GikoSys.GetLogDir + Board.BBSID);
1002     // Body.SaveToFile(GikoSys.GetSubjectFileName(Board.BBSID));
1003     GikoSys.ForceDirectoriesEx(ExtractFilePath(Board.GetSubjectFileName));
1004     Body.SaveToFile(Board.GetSubjectFileName);
1005     end;
1006 hi_ 1.1 finally
1007     Body.Free;
1008 yoffy 1.10 Board.ListData.Free;
1009 hi_ 1.1 end;
1010     end;
1011    
1012     {procedure TDownloadItem.SaveListFile;
1013     var
1014     i: Integer;
1015     index: Integer;
1016     NewItem: TThreadItem;
1017     NewList: TList;
1018     // SaveCount: Integer;
1019     NumCount: Integer;
1020     Body: TStringList;
1021     Rec: TSubjectRec;
1022     begin
1023     NewList := TList.Create;
1024     Body := TStringList.Create;
1025     try
1026     //鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申
1027     Board.RoundDate := Now;
1028     //鐃?鐃?鐃?鐃緒申鐃?鐃?鐃?鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申
1029     Board.LastModified := LastModified;
1030    
1031     //鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申
1032     //SaveCount := MaxInt;
1033    
1034     //鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃?鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申
1035     for i := Board.Count - 1 downto 0 do
1036     if not Board.Items[i].IsLogFile then
1037     Board.Delete(i);
1038    
1039     //鐃?鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申
1040     //鐃?鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申
1041     //鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃?鐃緒申鐃?鐃?鐃?鐃?鐃?鐃?鐃緒申鐃緒申鐃緒申
1042     Body.Text := Content;
1043     // Loop := Min(Body.Count, SaveCount);
1044     NumCount := 0;
1045     // for i := 0 to Loop - 1 do begin
1046     for i := 0 to Body.Count - 1 do begin
1047     if i = 0 then Continue; //鐃?鐃?鐃緒申鐃緒申鐃?鐃?鐃?鐃?鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申
1048    
1049     Rec := GikoSys.DivideSubject(Body[i]);
1050     if (Rec.FTitle = '') and (Rec.FCount = 0) then Continue;
1051     Inc(NumCount);
1052     index := Board.GetIndex(Rec.FFileName);
1053     if index = -1 then begin
1054     NewItem := TThreadItem.Create;
1055     NewItem.FileName := Rec.FFileName;
1056     NewItem.Title := Rec.FTitle;
1057     NewItem.Count := Rec.FCount;
1058     NewItem.ParentBoard := Board;
1059     NewItem.No := NumCount;
1060     NewItem.RoundDate := ZERO_DATE;
1061     NewItem.LastModified := ZERO_DATE;
1062     NewList.Add(NewItem);
1063     end else begin
1064     //Board.Items[index].Count := Count;
1065     Board.Items[index].No := NumCount;
1066     NewList.Add(Board.Items[index]);
1067     Board.DeleteList(index);
1068     end;
1069     end;
1070    
1071     //鐃?鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃?鐃?鐃?鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申
1072     for i := 0 to Board.Count - 1 do begin
1073     inc(NumCount);
1074     Board.Items[i].No := NumCount;
1075     NewList.Add(Board.Items[i]);
1076     end;
1077    
1078     //鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃?鐃?鐃緒申鐃緒申鐃?鐃?鐃緒申鐃?鐃?鐃?鐃?鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?
1079     for i := Board.Count - 1 downto 0 do
1080     Board.DeleteList(i);
1081    
1082     //鐃?鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃?鐃?鐃?鐃?鐃?鐃?鐃?鐃?鐃?鐃緒申鐃緒申鐃緒申
1083     for i := 0 to NewList.Count - 1 do
1084     Board.Add(TThreadItem(NewList[i]));
1085    
1086     //鐃緒申鐃?鐃?(subject.txt)鐃緒申鐃緒申鐃緒申
1087     // GikoSys.ForceDirectoriesEx(GikoSys.GetLogDir + Board.BBSID);
1088     // Body.SaveToFile(GikoSys.GetSubjectFileName(Board.BBSID));
1089     GikoSys.ForceDirectoriesEx(ExtractFilePath(Board.GetSubjectFileName));
1090     Body.SaveToFile(Board.GetSubjectFileName);
1091     finally
1092     Body.Free;
1093     NewList.Free;
1094     end;
1095     end;
1096     }
1097     procedure TDownloadItem.SaveItemFile;
1098     var
1099     Body: TStringList;
1100     Cnt: Integer;
1101     OldCnt: Integer;
1102     FileName: string;
1103     ini: TMemIniFile;
1104     Res: TResRec;
1105     NewRes: Integer;
1106 h677 1.19 finish : Boolean;
1107     loopCnt : Integer;
1108 hi_ 1.1 begin
1109     FileName := ThreadItem.GetThreadFileName;
1110    
1111 yoffy 1.15 if not ThreadItem.IsBoardPlugInAvailable then begin
1112     if Trim(Content) = '' then
1113     Exit;
1114     GikoSys.ForceDirectoriesEx(ExtractFilePath(FileName));
1115    
1116     // Cnt := 0;
1117     Body := TStringList.Create;
1118 h677 1.20 NewRes := 0;
1119     OldCnt := 0;
1120 yoffy 1.15 try
1121     // if FileExists(FileName) and (ResponseCode = 206) then begin
1122     if FileExists(FileName) and (State = gdsDiffComplete) then begin
1123     // Body.Text := Content;
1124     // if Body.Count > 0 then
1125     // Body.Delete(0);
1126     // Content := Body.Text;
1127 h677 1.19 loopCnt := 10;
1128     repeat
1129     finish := true;
1130     try
1131     Body.LoadFromFile(FileName);
1132     OldCnt := Body.Count;
1133     Body.Text := Body.Text + Content;
1134     Body.SaveToFile(FileName);
1135     NewRes := Body.Count - OldCnt;
1136     except
1137     on E:EFOpenError do begin
1138     sleep(10);
1139     finish := false;
1140     Dec(loopCnt);
1141     end;
1142     end;
1143     until finish and ( loopCnt > 0 );
1144     //Cnt := Body.Count;
1145 yoffy 1.15 end else begin
1146     Body.Text := Content;
1147     // if Body.Count > 0 then
1148     // Body.Delete(0);
1149     Body.SaveToFile(FileName);
1150 hi_ 1.1
1151 yoffy 1.15 if ThreadItem.Title = '' then begin
1152     Res := GikoSys.DivideStrLine(Body[0]);
1153     ThreadItem.Title := Res.FTitle;
1154     end;
1155     ThreadItem.Size := 0;
1156     //ThreadItem.Count := 0;
1157     ThreadItem.AllResCount := 0;
1158     ThreadItem.NewResCount := 0;
1159     OldCnt := 0;
1160     NewRes := Body.Count;
1161 h677 1.19 //Cnt := Body.Count;
1162 hi_ 1.1 end;
1163     Cnt := Body.Count;
1164 yoffy 1.15 finally
1165     Body.Free;
1166 hi_ 1.1 end;
1167 h677 1.19
1168 yoffy 1.15 ThreadItem.Size := ThreadItem.Size + ContentLength;
1169     ThreadItem.LastModified := LastModified;
1170     ThreadItem.Count := Cnt;
1171 h677 1.19 //ThreadItem.AllResCount := Cnt;
1172 yoffy 1.15 ThreadItem.NewResCount := NewRes;
1173     ThreadItem.NewReceive := OldCnt + 1;
1174 hi_ 1.1 end;
1175 h677 1.19 ThreadItem.AllResCount := ThreadItem.Count;
1176 yoffy 1.15 ThreadItem.IsLogFile := True;
1177 hi_ 1.1 ThreadItem.RoundDate := Now;
1178     ThreadItem.UnRead := True;
1179     ThreadItem.ParentBoard.UnRead := ThreadItem.ParentBoard.UnRead + 1;
1180     // if ThreadItem.RoundNo = 6 then
1181     // ThreadItem.RoundNo := 0;
1182    
1183     //鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃?鐃?鐃?鐃?鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?
1184     //鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申
1185     //鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃?
1186     ini := TMemIniFile.Create(ChangeFileExt(FileName, '.tmp'));
1187     try
1188     ini.WriteDateTime('Setting', 'RoundDate', ThreadItem.RoundDate);
1189     ini.WriteDateTime('Setting', 'LastModified', ThreadItem.LastModified);
1190     ini.WriteInteger('Setting', 'Size', ThreadItem.Size);
1191     ini.WriteInteger('Setting', 'Count', ThreadItem.Count);
1192     ini.WriteInteger('Setting', 'AllResCount', ThreadItem.AllResCount);
1193     ini.WriteInteger('Setting', 'NewResCount', ThreadItem.NewResCount);
1194     ini.WriteInteger('Setting', 'NewReceive', ThreadItem.NewReceive);
1195     // ini.WriteInteger('Setting', 'RoundNo', ThreadItem.RoundNo);
1196     ini.WriteBool('Setting', 'Round', ThreadItem.Round);
1197     ini.WriteBool('Setting', 'UnRead', ThreadItem.UnRead);
1198 h677 1.19 ini.UpdateFile;
1199 hi_ 1.1 finally
1200     ini.Free;
1201     end;
1202     end;
1203    
1204     end.

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