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.22 - (show annotations) (download) (as text)
Wed Mar 31 08:57:08 2004 UTC (20 years ago) by h677
Branch: MAIN
Changes since 1.21: +18 -1 lines
File MIME type: text/x-pascal
ItemDownload関係のメモリリークの解消

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

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