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.58 - (show annotations) (download) (as text)
Thu Feb 14 16:48:00 2008 UTC (16 years, 1 month ago) by h677
Branch: MAIN
CVS Tags: v1_59_0_771, v1_59_0_770, v1_59_0_773, v1_59_0_772, v1_59_0_775, v1_59_0_774, v1_59_0_777, v1_59_0_776, v1_59_0_778, v1_63_1_819, v1_62_0_812, v1_59_1_765, v1_60_0_788, v1_60_0_789, v1_58_0_748, v1_58_0_745, v1_60_0_781, v1_60_0_782, v1_58_0_746, v1_60_0_784, v1_60_0_786, v1_60_0_787, v1_59_0_767, v1_59_1_778, v1_59_0_768, v1_59_0_769, v1_57_1_744, v1_58_0_752, v1_58_0_750, v1_58_0_751, v1_58_0_756, v1_58_0_757, v1_58_0_754, v1_58_0_755, v1_58_0_759, v1_61_0_796, v1_61_0_797, v1_61_0_795, v1_61_0_798, v1_61_0_799, v1_63_0_818, v1_63_0_817, v1_63_0_816, v1_63_0_815, v1_62_0_805, v1_62_0_804, v1_62_0_807, v1_62_0_806, v1_62_0_803, v1_62_0_802, v1_62_0_809, v1_60_0_780, v1_60_0_779, v1_62_0_810, v1_62_0_811, v1_58_0_747, v1_60_0_783, v1_59_2_785, v1_60_1_793, v1_58_0_763, v1_58_0_762, v1_58_0_761, v1_58_0_760, v1_62_1_813, v1_57_2_749, v1_57_0_742, v1_57_0_743, v1_57_0_741, v1_57_0_744, v1_61_0_800, v1_60_0_793, v1_60_0_792, v1_60_0_791, v1_60_0_790, v1_60_2_794, v1_61_1_801, HEAD
Branch point for: Bb57, Bb62, Bb63, Bb60, Bb61, Bb59, Bb58
Changes since 1.57: +79 -12 lines
File MIME type: text/x-pascal
ダウンロード中の終了で、クラッシュする不具合対応(eggcakeさんありがとう)

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

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