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.51 - (show annotations) (download) (as text)
Fri Dec 16 17:10:38 2005 UTC (18 years, 4 months ago) by h677
Branch: MAIN
CVS Tags: v1_51_0_632, v1_51_0_633, v1_51_0_631
Changes since 1.50: +9 -9 lines
File MIME type: text/x-pascal
DAT落ちしたスレのサイズを正しく取得するように修正。

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

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