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.19 - (show 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 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.Free;
113 inherited;
114 end;
115
116 function RFC1123_Date(aDate : TDateTime) : String;
117 const
118 StrWeekDay : String = 'MonTueWedThuFriSatSun';
119 StrMonth : String = 'JanFebMarAprMayJunJulAugSepOctNovDec';
120 var
121 Year, Month, Day : Word;
122 Hour, Min, Sec, MSec : Word;
123 DayOfWeek : Word;
124 begin
125 DecodeDate(aDate, Year, Month, Day);
126 DecodeTime(aDate, Hour, Min, Sec, MSec);
127 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 foundPos: Integer;
148 boardPlugIn : TBoardPlugIn;
149 listContent : string;
150 begin
151 while not Terminated do begin
152 //===== 鐃?鐃緒申鐃?鐃?鐃緒申
153 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
191 //===== 鐃?鐃緒申鐃?鐃?鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申
192 FAbort := False;
193 FIndy.Request.CustomHeaders.Clear;
194 FIndy.Response.Clear;
195 FIndy.Request.Clear;
196 FIndy.ProxyParams.Clear;
197 FIndy.Disconnect;
198 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 if FileExists(ChangeFileExt(Item.FThreadItem.GetThreadFileName,'.NG')) = true then
309 DeleteFile(ChangeFileExt(Item.FThreadItem.GetThreadFileName,'.NG'));
310 if Assigned(OnDownloadMsg) then
311 Synchronize(FireDownloadMsg);
312 if not DatDownload(Item.DownType, URL, ZERO_DATE, RangeStart, AdjustLen) then
313 Item.State := gdsError;
314 {$IFDEF DEBUG}
315 Writeln('鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申');
316 Writeln('ResponseCode: ' + IntToStr(Item.ResponseCode));
317 {$ENDIF}
318 end else if (Item.DownType = gdtThread) and (AdjustLen = -1) and (Item.Content[1] = #10) then begin
319 //鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃?鐃?鐃?鐃緒申鐃緒申LF鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申LF鐃緒申鐃緒申鐃緒申
320 Item.Content := Copy(Item.Content, 2, Length(Item.Content));
321 end;
322 end else begin
323 Item.State := gdsError;
324 if (Item.DownType = gdtBoard) and (Item.ResponseCode = 302) then begin
325 FMsg := '鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申';
326 FIcon := gmiNG;
327 if Assigned(OnDownloadMsg) then
328 Synchronize(FireDownloadMsg);
329 end;
330 end;
331
332 //********************
333 //dat.gz鐃緒申鐃緒申(1)
334 //********************
335 if (Item.DownType = gdtThread) and (Item.ResponseCode = 302) then begin
336 {$IFDEF DEBUG}
337 Writeln('dat.gz鐃緒申鐃緒申');
338 {$ENDIF}
339 ATitle := Item.ThreadItem.Title;
340 if ATitle = '' then
341 ATitle := '鐃?鐃緒申鐃緒申鐃?鐃緒申鐃?';
342 FMsg := '鐃緒申dat鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?(dat.gz)鐃緒申鐃?鐃緒申鐃緒申鐃緒申 - [' + ATitle + ']';
343 FIcon := gmiWhat;
344 if Assigned(OnDownloadMsg) then
345 Synchronize(FireDownloadMsg);
346 URL := Item.ThreadItem.GetDatgzURL;
347 Modified := Item.ThreadItem.LastModified;
348 RangeStart := 0;
349 AdjustLen := 0;
350 if not DatDownload(Item.DownType, URL, Modified, RangeStart, AdjustLen) then
351 Item.State := gdsError;
352 {$IFDEF DEBUG}
353 Writeln('ResponseCode: ' + IntToStr(Item.ResponseCode));
354 {$ENDIF}
355 end;
356
357 //********************
358 //dat.gz鐃緒申鐃緒申(2)
359 //********************
360 {
361 if (Item.DownType = gdtThread) and (Item.ResponseCode = 302) then begin
362 ATitle := Item.ThreadItem.Title;
363 if ATitle = '' then
364 ATitle := '鐃?鐃緒申鐃緒申鐃?鐃緒申鐃?';
365 FMsg := '鐃緒申鐃緒申鐃緒申鐃緒申鐃?(1)鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?(2)鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申 - [' + ATitle + ']';
366 FIcon := gmiWhat;
367 if Assigned(OnDownloadMsg) then
368 Synchronize(FireDownloadMsg);
369 URL := Item.ThreadItem.GetOldDatgzURL;
370 Modified := Item.ThreadItem.LastModified;
371 RangeStart := 0;
372 AdjustLen := 0;
373 if not DatDownload(Item.DownType, URL, Modified, RangeStart, AdjustLen) then
374 Item.State := gdsError;
375 end;
376 }
377
378 //********************
379 //offlaw.cgi鐃緒申鐃緒申鐃緒申
380 //********************
381 FSessionID := '';
382 Synchronize(GetSessionID);
383 if (Item.DownType = gdtThread) and (Item.ResponseCode = 302) and (FSessionID <> '') then begin
384 {$IFDEF DEBUG}
385 Writeln('offlaw.cgi鐃緒申鐃緒申鐃緒申');
386 {$ENDIF}
387 ATitle := Item.ThreadItem.Title;
388 if ATitle = '' then
389 ATitle := '鐃?鐃緒申鐃緒申鐃?鐃緒申鐃?';
390 FMsg := '鐃緒申dat.gz鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申offlaw.cgi鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申 - [' + ATitle + ']';
391 FIcon := gmiWhat;
392 if Assigned(OnDownloadMsg) then
393 Synchronize(FireDownloadMsg);
394 URL := Item.ThreadItem.GetOfflawCgiURL(FSessionID);
395 Modified := Item.ThreadItem.LastModified;
396 RangeStart := 0;
397 AdjustLen := 0;
398 if not DatDownload(Item.DownType, URL, Modified, RangeStart, AdjustLen) then begin
399 {$IFDEF DEBUG}
400 Writeln('ResponseCode: ' + IntToStr(Item.ResponseCode));
401 {$ENDIF}
402 Item.State := gdsError;
403
404 if (Item.DownType = gdtThread) and (Item.ResponseCode = 302) then begin
405 FMsg := '鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃?';
406 FIcon := gmiNG;
407 if Assigned(OnDownloadMsg) then
408 Synchronize(FireDownloadMsg);
409 end;
410
411 end else begin
412 CgiStatus := ParseCgiStatus(Item.Content);
413 {$IFDEF DEBUG}
414 Writeln('ResponseCode: ' + IntToStr(Item.ResponseCode));
415 {$ENDIF}
416 case CgiStatus.FStatus of
417 gcsOK: begin
418 {$IFDEF DEBUG}
419 Writeln('CGIStatus: OK');
420 {$ENDIF}
421 Item.ResponseCode := 200;
422 Item.Content := DeleteStatusLine(Item.Content);
423 Item.ContentLength := CgiStatus.FSize;
424 end;
425 gcsINCR: begin
426 //鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申
427 {$IFDEF DEBUG}
428 Writeln('CGIStatus: 206');
429 {$ENDIF}
430 Item.ResponseCode := 206;
431 Item.Content := DeleteStatusLine(Item.Content);
432 Item.ContentLength := CgiStatus.FSize;
433 end;
434 gcsERR: begin
435 {$IFDEF DEBUG}
436 Writeln('CGIStatus: 404(ERROR)');
437 {$ENDIF}
438 Item.ResponseCode := 404;
439 Item.State := gdsError;
440 Item.ErrText := CgiStatus.FErrText;
441 end;
442 end;
443 if (Item.ResponseCode = 404) and (AnsiPos('鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申', Item.ErrText) <> 0) then begin
444 {$IFDEF DEBUG}
445 Writeln('鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃緒申');
446 {$ENDIF}
447 ATitle := Item.ThreadItem.Title;
448 if ATitle = '' then
449 ATitle := '鐃?鐃緒申鐃緒申鐃?鐃緒申鐃?';
450 FMsg := '鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申 - [' + ATitle + ']';
451 FIcon := gmiWhat;
452 if Assigned(OnDownloadMsg) then
453 Synchronize(FireDownloadMsg);
454 Idx := Pos(' ', Item.ErrText);
455 if Idx <> 0 then begin
456 URL := Copy(Item.ErrText, Idx + 1, Length(Item.ErrText));
457 if Pos( '://', URL ) = 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 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 {$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 URL := 'http://www.google.co.jp/search?q=cache:' + Item.ThreadItem.URL;
500 URL := StringReplace( URL, 'l50', '', [rfReplaceAll] );
501 Modified := Item.ThreadItem.LastModified;
502 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 end;
522 {$ENDIF}
523
524 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 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 FIndy.Request.Accept := 'text/html';
620 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 Screen.Cursor := crDefault;
650 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 Screen.Cursor := crDefault;
659 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 Screen.Cursor := crDefault;
672 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 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 Screen.Cursor := crDefault;
744 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 Screen.Cursor := crDefault;
753 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 Screen.Cursor := crDefault;
766 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 // -INCR 23094/512K
830 // -ERR 鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申
831 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 function MakeThreadCallBack(
898 inInstance : DWORD; // TBoardItem 鐃緒申鐃?鐃緒申鐃?鐃?鐃緒申鐃?
899 inURL : PChar; // 鐃?鐃緒申鐃?鐃?鐃緒申 URL
900 inTitle : PChar; // 鐃?鐃緒申鐃?鐃?
901 inCount : DWORD // 鐃緒申鐃?鐃緒申鐃緒申
902 ) : Boolean; stdcall; // 鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申 True
903 var
904 _ThreadItem : TThreadItem; // '_' 鐃緒申鐃?鐃緒申鐃?鐃緒申鐃?鐃緒申鐃?鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申鐃緒申
905 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 _ThreadItem := TThreadItem.Create( boardItem.BoardPlugIn, string( inURL ) );
915
916 _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 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
932 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 begin
939 Board.ListData := TList.Create;
940 Body := TStringList.Create;
941 try
942 //鐃?鐃?鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申鐃?鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申鐃?
943 Board.RoundDate := Now;
944 //鐃?鐃?鐃?鐃緒申鐃?鐃?鐃?鐃緒申鐃緒申鐃?鐃?鐃緒申鐃緒申鐃緒申鐃緒申
945 Board.LastModified := LastModified;
946
947 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 NewItem := TThreadItem.Create(
990 nil, GikoSys.Get2chBoard2ThreadURL( Board, ChangeFileExt( Rec.FFileName, '' ) ) );
991 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 finally
1041 Body.Free;
1042 Board.ListData.Free;
1043 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 finish : Boolean;
1141 loopCnt : Integer;
1142 begin
1143 FileName := ThreadItem.GetThreadFileName;
1144
1145 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 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 end else begin
1178 Body.Text := Content;
1179 // if Body.Count > 0 then
1180 // Body.Delete(0);
1181 Body.SaveToFile(FileName);
1182
1183 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 //Cnt := Body.Count;
1194 end;
1195 Cnt := Body.Count;
1196 finally
1197 Body.Free;
1198 end;
1199
1200 ThreadItem.Size := ThreadItem.Size + ContentLength;
1201 ThreadItem.LastModified := LastModified;
1202 ThreadItem.Count := Cnt;
1203 //ThreadItem.AllResCount := Cnt;
1204 ThreadItem.NewResCount := NewRes;
1205 ThreadItem.NewReceive := OldCnt + 1;
1206 end;
1207 ThreadItem.AllResCount := ThreadItem.Count;
1208 ThreadItem.IsLogFile := True;
1209 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 ini.UpdateFile;
1231 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