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.19 - (hide annotations) (download) (as text)
Fri Dec 5 10:19:26 2003 UTC (20 years, 4 months ago) by h677
Branch: MAIN
CVS Tags: b44
Changes since 1.18: +25 -10 lines
File MIME type: text/x-pascal
スレッド一覧取得後に、スレッドを取得したときに、レス数と取得数がずれるときがあるバグの修正

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

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