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

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