Develop and Download Open Source Software

Browse CVS Repository

Contents of /gikonavigoeson/gikonavi/ItemDownload.pas

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


Revision 1.26 - (show annotations) (download) (as text)
Thu May 6 14:09:42 2004 UTC (19 years, 11 months ago) by h677
Branch: MAIN
Changes since 1.25: +11 -37 lines
File MIME type: text/x-pascal
スレッド一覧を更新すると大量のメモリリークがでる不具合の修正。

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

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