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.6.2.3 - (show annotations) (download) (as text)
Fri Oct 8 05:44:52 2004 UTC (19 years, 6 months ago) by yoffy
Branch: stable
Changes since 1.6.2.2: +48 -50 lines
File MIME type: text/x-pascal
b49 、ヒ・゙。シ・ク。」

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

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