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.43.2.2 - (show annotations) (download) (as text)
Sun Jul 17 06:55:27 2005 UTC (18 years, 9 months ago) by h677
Branch: Bb50
CVS Tags: v1_50_2_606, v1_50_0_603, v1_50_0_604, v1_50_0_606, b50, v1_50_0_600, v1_50_2_604, v1_50_0_602, v1_50_0_601, v1_50_0_605, v1_50_0_599
Changes since 1.43.2.1: +1 -1 lines
File MIME type: text/x-pascal
tmpファイルがあるときに巡回予約のある無しを設定しなくした。

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

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