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.25 - (show annotations) (download) (as text)
Mon May 3 15:18:29 2004 UTC (19 years, 11 months ago) by q9_
Branch: MAIN
Changes since 1.24: +39 -9 lines
File MIME type: text/x-pascal
Shiftキーを押しながら板/スレを更新すると強制取得するようにした

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

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