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

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