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.16 - (show annotations) (download) (as text)
Fri Nov 21 17:24:50 2003 UTC (20 years, 5 months ago) by yoffy
Branch: MAIN
Changes since 1.15: +2 -1 lines
File MIME type: text/x-pascal
・今まで 1 つ固定であった BBS が複数持てるようになった。
 これにより、多くの2ちゃんねる特有の処理が排除され使えなくなった可能性がある。

以下注意。
 お気に入りファイルのフォーマットが変更になった(確定)。
 巡回ファイルのフォーマットが変更になったかもしれない(不明)。
 他にもあるかも。

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

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