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

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