6 Windows, SysUtils, Classes, ComCtrls, Controls, Forms, IdHTTP,
7 {HTTPApp,} YofUtils, IdGlobal, IdException, IdComponent, IniFiles, {DateUtils,}
8 GikoSystem, BoardGroup, MonaUtils, ExternalBoardManager, ExternalBoardPlugInMain,
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);
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;
25 FStatus: TGikoCgiStatus;
31 TDownloadThread = class(TThread)
38 FIcon: TGikoMessageIcon;
40 FOnWork: TGikoWorkEvent;
41 FOnWorkBegin: TGikoWorkBeginEvent;
42 FOnWorkEnd: TGikoWorkEndEvent;
43 FOnDownloadEnd: TDownloadEndEvent;
44 FOnDownloadMsg: TDownloadMsgEvent;
45 FDownloadTitle: string;
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;
58 procedure Execute; override;
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;
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;
72 TDownloadItem = class(TObject)
74 FDownType: TGikoDownloadType;
76 FThreadItem: TThreadItem;
78 FContentLength: Integer;
79 FLastModified: TDateTime;
81 FResponseCode: Smallint;
82 FState: TGikoDownloadState;
84 FForceDownload: Boolean;
87 procedure SaveListFile;
88 procedure SaveItemFile;
90 property DownType: TGikoDownloadType read FDownType write FDownType;
91 property Board: TBoard read FBoard write FBoard;
92 property ThreadItem: TThreadItem read FThreadItem write FThreadItem;
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;
107 Y_TextConverter, MojuUtils, HTMLCreate;
109 constructor TDownloadThread.Create(CreateSuspended: Boolean);
111 inherited Create(CreateSuspended);
112 FIndy := TIdHttp.Create(nil);
114 FIndy.OnWorkBegin := WorkBegin;
115 FIndy.OnWorkEnd := WorkEnd;
116 FIndy.OnWork := Work;
119 destructor TDownloadThread.Destroy;
121 FIndy.Request.CustomHeaders.Clear;
122 FIndy.Request.RawHeaders.Clear;
124 FIndy.Response.CustomHeaders.Clear;
125 FIndy.Response.RawHeaders.Clear;
126 FIndy.Response.Clear;
127 FIndy.ProxyParams.Clear;
132 function RFC1123_Date(aDate : TDateTime) : String;
134 StrWeekDay : String = 'MonTueWedThuFriSatSun';
135 StrMonth : String = 'JanFebMarAprMayJunJulAugSepOctNovDec';
137 Year, Month, Day : Word;
138 Hour, Min, Sec, MSec : Word;
141 DecodeDate(aDate, Year, Month, Day);
142 DecodeTime(aDate, Hour, Min, Sec, MSec);
143 DayOfWeek := ((Trunc(aDate) - 2) mod 7);
144 Result := Copy(StrWeekDay, 1 + DayOfWeek * 3, 3) + ', ' +
145 Format('%2.2d %s %4.4d %2.2d:%2.2d:%2.2d',
146 [Day, Copy(StrMonth, 1 + 3 * (Month - 1), 3),
147 Year, Hour, Min, Sec]);
150 procedure TDownloadThread.Execute;
152 ResStream: TMemoryStream;
155 CgiStatus: TCgiStatus;
161 DownloadResult: Boolean;
162 boardPlugIn : TBoardPlugIn;
163 lastContent : string;
164 logFile : TFileStream;
165 adjustMargin : Integer;
169 while not Terminated do begin
170 //=====
\83v
\83\89\83O
\83C
\83\93
173 ExternalBoardManager.OnWork := Work;
174 ExternalBoardManager.OnWorkBegin := WorkBegin;
175 ExternalBoardManager.OnWorkEnd := WorkEnd;
177 FDownloadTitle := '';
178 case FItem.FDownType of
181 FDownloadTitle := FItem.FBoard.Title;
182 if FItem.FBoard <> nil then begin
183 if FItem.FBoard.IsBoardPlugInAvailable then begin
184 boardPlugIn := FItem.FBoard.BoardPlugIn;
185 Item.State := TGikoDownloadState( boardPlugIn.DownloadBoard( DWORD( FItem.FBoard ) ) );
191 FDownloadTitle := FItem.FThreadItem.Title;
192 if FItem.FThreadItem <> nil then begin
193 if FItem.FThreadItem.ParentBoard.IsBoardPlugInAvailable then begin
194 boardPlugIn := FItem.FThreadItem.ParentBoard.BoardPlugIn;
195 Item.State := TGikoDownloadState( boardPlugIn.DownloadThread( DWORD( FItem.FThreadItem ) ) );
197 //if FItem.FThreadItem.IsBoardPlugInAvailable then begin
198 // boardPlugIn := FItem.FThreadItem.BoardPlugIn;
199 // Item.State := TGikoDownloadState( boardPlugIn.DownloadThread( DWORD( FItem.FThreadItem ) ) );
204 if Length(FDownloadTitle) = 0 then
205 FDownloadTitle := '
\81i
\96¼
\8fÌ
\95s
\96¾
\81j';
207 if boardPlugIn <> nil then begin
209 Item.State := gdsAbort;
211 if Assigned( OnDownloadEnd ) then
212 Synchronize( FireDownloadEnd );
220 //=====
\83v
\83\89\83O
\83C
\83\93\82ð
\8eg
\97p
\82µ
\82È
\82¢
\8fê
\8d\87
222 FIndy.Request.CustomHeaders.Clear;
223 FIndy.Response.Clear;
225 FIndy.ProxyParams.Clear;
227 FIndy.Request.UserAgent := GikoSys.GetUserAgent;
228 FIndy.RecvBufferSize := Gikosys.Setting.RecvBufferSize;
229 FIndy.ProxyParams.BasicAuthentication := False;
230 FIndy.ReadTimeout := GikoSys.Setting.ReadTimeOut;
232 Writeln('------------------------------------------------------------');
234 //FIndy.AllowCookies := False;
235 if GikoSys.Setting.ReadProxy then begin
236 if GikoSys.Setting.ProxyProtocol then
237 FIndy.ProtocolVersion := pv1_1
239 FIndy.ProtocolVersion := pv1_0;
240 FIndy.ProxyParams.ProxyServer := GikoSys.Setting.ReadProxyAddress;
241 FIndy.ProxyParams.ProxyPort := GikoSys.Setting.ReadProxyPort;
242 FIndy.ProxyParams.ProxyUsername := GikoSys.Setting.ReadProxyUserID;
243 FIndy.ProxyParams.ProxyPassword := GikoSys.Setting.ReadProxyPassword;
244 if GikoSys.Setting.ReadProxyUserID <> '' then
245 FIndy.ProxyParams.BasicAuthentication := True;
247 Writeln('
\83v
\83\8d\83L
\83V
\90Ý
\92è
\82 \82è');
248 Writeln('
\83z
\83X
\83g: ' + GikoSys.Setting.ReadProxyAddress);
249 Writeln('
\83|
\81[
\83g: ' + IntToStr(GikoSys.Setting.ReadProxyPort));
252 if GikoSys.Setting.Protocol then
253 FIndy.ProtocolVersion := pv1_1
255 FIndy.ProtocolVersion := pv1_0;
256 FIndy.ProxyParams.ProxyServer := '';
257 FIndy.ProxyParams.ProxyPort := 80;
258 FIndy.ProxyParams.ProxyUsername := '';
259 FIndy.ProxyParams.ProxyPassword := '';
261 Writeln('
\83v
\83\8d\83L
\83V
\90Ý
\92è
\82È
\82µ');
266 if Item.DownType = gdtThread then begin
267 if FileExists( Item.ThreadItem.GetThreadFileName ) then begin
268 // dat
\83t
\83@
\83C
\83\8b\82Ì
\8dÅ
\8cã
\82ð
\93Ç
\82Ý
\8fo
\82·
269 SetLength( lastContent, ADJUST_MARGIN + 1 );
270 logFile := TFileStream.Create( Item.ThreadItem.GetThreadFileName, fmOpenRead or fmShareDenyWrite );
272 logFile.Seek( -(ADJUST_MARGIN + 1), soFromEnd );
273 logFile.Read( lastContent[ 1 ], ADJUST_MARGIN + 1 );
274 lastContent := StringReplace( lastContent, #13, '', [] ); // CR
\82Ì
\8dí
\8f\9c
281 adjustMargin := Length( lastContent );
284 FIndy.Request.ContentRangeStart := 0;
285 FIndy.Request.LastModified := ZERO_DATE;
286 ResStream := TMemoryStream.Create;
289 //********************
290 //DAT or Subject
\8eæ
\93¾
291 //********************
292 Item.ResponseCode := 0;
296 if Item.DownType = gdtBoard then begin
298 Writeln('Subject
\8eæ
\93¾');
299 Writeln('URL: ' + Item.Board.GetReadCgiURL);
300 Writeln('Modified: ' + FloatToStr(Item.Board.LastModified));
302 URL := Item.Board.GetReadCgiURL;
303 if Item.ForceDownload then begin
305 ATitle := Item.Board.Title;
307 ATitle := '
\81i
\96¼
\8fÌ
\95s
\96¾
\81j';
308 FMsg := '
\81\9a\8b
\90§
\8eæ
\93¾
\82ð
\8ds
\82¢
\82Ü
\82· - [' + ATitle + ']';
310 if Assigned(OnDownloadMsg) then
311 Synchronize(FireDownloadMsg);
312 Modified := ZERO_DATE
314 Modified := Item.Board.LastModified;
316 end else if Item.DownType = gdtThread then begin
318 Writeln('DAT
\8eæ
\93¾');
319 Writeln('URL: ' + Item.ThreadItem.GetDatURL);
320 Writeln('Modified: ' + FloatToStr(Item.ThreadItem.LastModified));
322 URL := Item.ThreadItem.GetDatURL;
323 if Item.ForceDownload then begin
325 ATitle := Item.ThreadItem.Title;
327 ATitle := '
\81i
\96¼
\8fÌ
\95s
\96¾
\81j';
328 FMsg := '
\81\9a\8b
\90§
\8eæ
\93¾
\82ð
\8ds
\82¢
\82Ü
\82· - [' + ATitle + ']';
330 if FileExists(ChangeFileExt(Item.FThreadItem.GetThreadFileName,'.NG')) = true then
331 DeleteFile(ChangeFileExt(Item.FThreadItem.GetThreadFileName,'.NG'));
332 if Assigned(OnDownloadMsg) then
333 Synchronize(FireDownloadMsg);
334 Modified := ZERO_DATE;
338 Modified := Item.ThreadItem.LastModified;
339 if Item.ThreadItem.Size > 0 then begin
341 Writeln('RangeStart: ' + IntToStr(Item.ThreadItem.Size));
343 //
\82 \82Ú
\81[
\82ñ
\83`
\83F
\83b
\83N
\82Ì
\82½
\82ß adjustMargin
\83o
\83C
\83g
\91O
\82©
\82ç
\8eæ
\93¾
344 RangeStart := Item.ThreadItem.Size;
345 AdjustLen := -adjustMargin;
349 Item.IsAbone := False;
350 DownloadResult := DatDownload(Item.DownType, URL, Modified, RangeStart, AdjustLen);
352 Writeln('ResponseCode: ' + IntToStr(FIndy.ResponseCode));
354 if Item.DownType = gdtThread then begin
355 if Item.ResponseCode = 416 then begin
356 Item.IsAbone := True;
357 DownloadResult := True;
358 end else if DownloadResult and (AdjustLen < 0) then begin
359 if Copy( Item.Content, 1, adjustMargin ) <> lastContent then
360 Item.IsAbone := True;
364 if Trim(FIndy.Response.RawHeaders.Values['Date']) <> '' then begin
365 if Item.DownType = gdtBoard then
366 Item.Board.LastGetTime := MonaUtils.DateStrToDateTime(FIndy.Response.RawHeaders.Values['Date'])
368 Item.ThreadItem.ParentBoard.LastGetTime := MonaUtils.DateStrToDateTime(FIndy.Response.RawHeaders.Values['Date']);
371 if DownloadResult then begin
373 Writeln('Date:' + FIndy.Response.RawHeaders.Values['Date']);
375 if Item.IsAbone then begin
377 Writeln('
\82 \82Ú
\81[
\82ñ
\8c\9f\8fo');
379 ATitle := Item.ThreadItem.Title;
381 ATitle := '
\81i
\96¼
\8fÌ
\95s
\96¾
\81j';
382 //
\8d·
\95ª
\8eæ
\93¾
\82©
\82Â
\82P
\83o
\83C
\83g
\96Ú
\82ªLF
\82Å
\82È
\82¢
\8fê
\8d\87\82Í
\81u
\82 \82Ú
\81[
\82ñ
\81v
\82³
\82ê
\82Ä
\82¢
\82é
\82©
\82à
\82µ
\82ê
\82ñ
\82Ì
\82Å
\8dÄ
\8eæ
\93¾
385 FMsg := '
\81\9a\81u
\82 \82Ú
\81[
\82ñ
\81v
\82ð
\8c\9f\8fo
\82µ
\82½
\82Ì
\82Å
\8dÄ
\8eæ
\93¾
\82ð
\8ds
\82¢
\82Ü
\82· - [' + ATitle + ']';
387 if FileExists(ChangeFileExt(Item.FThreadItem.GetThreadFileName,'.NG')) = true then
388 DeleteFile(ChangeFileExt(Item.FThreadItem.GetThreadFileName,'.NG'));
389 if Assigned(OnDownloadMsg) then
390 Synchronize(FireDownloadMsg);
391 if not DatDownload(Item.DownType, URL, ZERO_DATE, RangeStart, AdjustLen) then
392 Item.State := gdsError;
394 Writeln('
\82 \82Ú
\81[
\82ñ
\8dÄ
\8eæ
\93¾
\8cã');
395 Writeln('ResponseCode: ' + IntToStr(Item.ResponseCode));
397 end else if (Item.DownType = gdtThread) and (AdjustLen < 0) then begin
398 //
\8d·
\95ª
\8eæ
\93¾
\82ª
\8fo
\97\88\82½
\8fê
\8d\87\82Í
\82 \82Ú
\81[
\82ñ
\83`
\83F
\83b
\83N
\97p
\82É
\8eæ
\93¾
\82µ
\82½
\97]
\95ª
\82È
\83T
\83C
\83Y
\82ð
\8dí
\8f\9c
399 Item.Content := Copy(Item.Content, adjustMargin + 1, MaxInt);
402 Item.State := gdsError;
403 if (Item.DownType = gdtBoard) and (Item.ResponseCode = 302) then begin
404 FMsg := '
\81\9a\81\9a\94Â
\82ª
\88Ú
\93]
\82µ
\82½
\82©
\82à
\82µ
\82ê
\82È
\82¢
\82Ì
\82Å
\94Â
\8dX
\90V
\82ð
\8ds
\82Á
\82Ä
\82
\82¾
\82³
\82¢
\81\9a\81\9a';
406 if Assigned(OnDownloadMsg) then
407 Synchronize(FireDownloadMsg);
411 //********************
413 //********************
414 if (Item.DownType = gdtThread) and (Item.ResponseCode = 302) then begin
416 Writeln('dat.gz
\8eæ
\93¾');
418 ATitle := Item.ThreadItem.Title;
420 ATitle := '
\81i
\96¼
\8fÌ
\95s
\96¾
\81j';
421 FMsg := '
\81\9adat
\82ª
\91¶
\8dÝ
\82µ
\82È
\82¢
\82½
\82ß
\89ß
\8b\8e\83\8d\83O(dat.gz)
\82ð
\92T
\82µ
\82Ü
\82· - [' + ATitle + ']';
423 if Assigned(OnDownloadMsg) then
424 Synchronize(FireDownloadMsg);
425 URL := Item.ThreadItem.GetDatgzURL;
426 Modified := Item.ThreadItem.LastModified;
429 if not DatDownload(Item.DownType, URL, Modified, RangeStart, AdjustLen) then
430 Item.State := gdsError;
432 Writeln('ResponseCode: ' + IntToStr(Item.ResponseCode));
436 //********************
437 //dat.gz
\81@
\81¨
\81@dat
\82Ì
\8eæ
\93¾
\81@2005
\94N6
\8c\8e\92Ç
\89Á
\81@by
\82à
\82¶
\82ã
438 //********************
439 if (Item.DownType = gdtThread) and (Item.ResponseCode = 302) then begin
441 Writeln('dat
\8eæ
\93¾');
443 FMsg := '
\89ß
\8b\8e\83\8d\83O(dat.gz)
\82ª
\91¶
\8dÝ
\82µ
\82È
\82¢
\82½
\82ß
\89ß
\8b\8e\83\8d\83O(dat)
\82ð
\92T
\82µ
\82Ü
\82· - [' + ATitle + ']';
445 if Assigned(OnDownloadMsg) then
446 Synchronize(FireDownloadMsg);
447 URL := ChangeFileExt(URL, '');
448 Modified := Item.ThreadItem.LastModified;
451 if not DatDownload(Item.DownType, URL, Modified, RangeStart, AdjustLen) then
452 Item.State := gdsError;
454 Writeln('ResponseCode: ' + IntToStr(Item.ResponseCode));
458 //********************
460 //********************
462 if (Item.DownType = gdtThread) and (Item.ResponseCode = 302) then begin
463 ATitle := Item.ThreadItem.Title;
465 ATitle := '
\81i
\96¼
\8fÌ
\95s
\96¾
\81j';
466 FMsg := '
\81\9a\89ß
\8b\8e\83\8d\83O(1)
\82ª
\91¶
\8dÝ
\82µ
\82È
\82¢
\82½
\82ß
\89ß
\8b\8e\83\8d\83O(2)
\82©
\82ç
\92T
\82µ
\82Ü
\82· - [' + ATitle + ']';
468 if Assigned(OnDownloadMsg) then
469 Synchronize(FireDownloadMsg);
470 URL := Item.ThreadItem.GetOldDatgzURL;
471 Modified := Item.ThreadItem.LastModified;
474 if not DatDownload(Item.DownType, URL, Modified, RangeStart, AdjustLen) then
475 Item.State := gdsError;
479 //********************
480 //offlaw.cgi
\82Å
\8eæ
\93¾
481 //********************
483 Synchronize(GetSessionID);
484 if (Item.DownType = gdtThread) and (Item.ResponseCode = 302) and (FSessionID <> '') then begin
486 Writeln('offlaw.cgi
\82Å
\8eæ
\93¾');
488 ATitle := Item.ThreadItem.Title;
490 ATitle := '
\81i
\96¼
\8fÌ
\95s
\96¾
\81j';
491 FMsg := '
\81\9adat.gz
\82ª
\91¶
\8dÝ
\82µ
\82È
\82¢
\82½
\82ßofflaw.cgi
\82ð
\97\98\97p
\82µ
\82Ü
\82· - [' + ATitle + ']';
493 if Assigned(OnDownloadMsg) then
494 Synchronize(FireDownloadMsg);
495 URL := Item.ThreadItem.GetOfflawCgiURL(FSessionID);
496 Modified := Item.ThreadItem.LastModified;
499 if not DatDownload(Item.DownType, URL, Modified, RangeStart, AdjustLen) then begin
501 Writeln('ResponseCode: ' + IntToStr(Item.ResponseCode));
503 Item.State := gdsError;
505 if (Item.DownType = gdtThread) and (Item.ResponseCode = 302) then begin
506 FMsg := '
\94Â
\82ª
\88Ú
\93]
\82µ
\82½
\82©
\82à
\82µ
\82ê
\82È
\82¢
\82Ì
\82Å
\94Â
\8dX
\90V
\82ð
\8ds
\82Á
\82Ä
\82
\82¾
\82³
\82¢
\81B';
508 if Assigned(OnDownloadMsg) then
509 Synchronize(FireDownloadMsg);
513 CgiStatus := ParseCgiStatus(Item.Content);
515 Writeln('ResponseCode: ' + IntToStr(Item.ResponseCode));
517 case CgiStatus.FStatus of
520 Writeln('CGIStatus: OK');
522 Item.ResponseCode := 200;
523 Item.Content := DeleteStatusLine(Item.Content);
524 Item.ContentLength := CgiStatus.FSize;
527 //
\8d¡
\82Í
\82 \82è
\82¦
\82È
\82¢
529 Writeln('CGIStatus: 206');
531 Item.ResponseCode := 206;
532 Item.Content := DeleteStatusLine(Item.Content);
533 Item.ContentLength := CgiStatus.FSize;
537 Writeln('CGIStatus: 404(ERROR)');
539 Item.ResponseCode := 404;
540 Item.State := gdsError;
541 Item.ErrText := CgiStatus.FErrText;
544 if (Item.ResponseCode = 404) and (AnsiPos('
\89ß
\8b\8e\83\8d\83O
\91q
\8cÉ
\82Å
\94
\8c©', Item.ErrText) <> 0) then begin
546 Writeln('
\89ß
\8b\8e\83\8d\83O
\8eæ
\93¾');
548 ATitle := Item.ThreadItem.Title;
550 ATitle := '
\81i
\96¼
\8fÌ
\95s
\96¾
\81j';
551 FMsg := '
\81\9a\89ß
\8b\8e\83\8d\83O
\91q
\8cÉ
\82Å
\94
\8c© - [' + ATitle + ']';
553 if Assigned(OnDownloadMsg) then
554 Synchronize(FireDownloadMsg);
555 Idx := Pos(' ', Item.ErrText);
556 if Idx <> 0 then begin
557 URL := Copy(Item.ErrText, Idx + 1, Length(Item.ErrText));
558 if Pos( '://', URL ) = 0 then begin
559 if Pos('../', URL) = 1 then
560 URL := Copy(URL, 4, MaxInt );
561 if Pos( '/', URL ) = 1 then
562 URL := Copy( URL, 2, MaxInt );
563 URL := GikoSys.UrlToServer(Item.ThreadItem.ParentBoard.URL) + URL;
565 Modified := Item.ThreadItem.LastModified;
568 if not DatDownload(Item.DownType, URL, Modified, RangeStart, AdjustLen) then
569 Item.State := gdsError;
571 Writeln('ResponseCode: ' + IntToStr(Item.ResponseCode));
577 if (Item.DownType = gdtThread) and (Item.ResponseCode = 302) and (FSessionID = '') then begin
579 Writeln('
\83\8d\83O
\83C
\83\93\82³
\82ê
\82Ä
\82È
\82¢
\82Ì
\82Å
\89ß
\8b\8e\83\8d\83O
\8eæ
\93¾
\95s
\89Â');
581 ATitle := Item.ThreadItem.Title;
583 ATitle := '
\81i
\96¼
\8fÌ
\95s
\96¾
\81j';
584 FMsg := '
\81\9a\83\8d\83O
\83C
\83\93\82³
\82ê
\82Ä
\82¢
\82È
\82¢
\82½
\82ß
\92T
\82·
\82±
\82Æ
\82ª
\8fo
\97\88\82Ü
\82¹
\82ñ - [' + ATitle + ']';
586 if Assigned(OnDownloadMsg) then
587 Synchronize(FireDownloadMsg);
591 case Item.ResponseCode of
592 200: Item.State := gdsComplete;
593 206: Item.State := gdsDiffComplete;
594 304: Item.State := gdsNotModify;
596 Item.State := gdsError;
599 //
\96³
\82¢
\82Æ
\8ev
\82¤
\82¯
\82Ç
\81B
\81B
\81B
600 if (Item.ResponseCode in [200, 206]) and (Item.Content = '') then
601 Item.State := gdsError;
602 Item.LastModified := FIndy.Response.LastModified;
603 //
\8d·
\95ª
\8eæ
\93¾
\82Å
\82P
\83o
\83C
\83g
\91O
\82©
\82ç
\82Æ
\82Á
\82Ä
\82«
\82½
\82Æ
\82«
\82Í
\83}
\83C
\83i
\83X
\82·
\82é
604 Item.ContentLength := FIndy.Response.ContentLength + AdjustLen;
607 FIndy.Get(URL, ResStream);
608 Item.Content := GikoSys.GzipDecompress(ResStream, FIndy.Response.ContentEncoding);
609 if (Item.DownType = gdtThread) and (AdjustLen = -1) and (Item.Content[1] <> #10) then begin
610 //
\8d·
\95ª
\8eæ
\93¾
\82©
\82Â
\82P
\83o
\83C
\83g
\96Ú
\82ªLF
\82Å
\82È
\82¢
\8fê
\8d\87\82Í
\81u
\82 \82Ú
\81[
\82ñ
\81v
\82³
\82ê
\82Ä
\82¢
\82é
\82©
\82à
\82µ
\82ê
\82ñ
\82Ì
\82Å
\8dÄ
\8eæ
\93¾
611 //
\82±
\82±
\82Å
\83\81\83b
\83Z
\81[
\83W
\95\
\8e¦
\83C
\83x
\83\93\83g
613 FMsg := '
\81u
\82 \82Ú
\81[
\82ñ
\81v
\82ð
\8c\9f\8fo
\82µ
\82½
\82Ì
\82Å
\8dÄ
\8eæ
\93¾
\82ð
\8ds
\82¢
\82Ü
\82·';
614 if Assigned(OnDownloadMsg) then
615 Synchronize(FireDownloadMsg);
616 FIndy.Request.ContentRangeStart := 0;
617 FIndy.Request.ContentRangeEnd := 0;
620 FIndy.Get(URL, ResStream);
621 Item.Content := GikoSys.GzipDecompress(ResStream, FIndy.Response.ContentEncoding);
622 end else if (Item.DownType = gdtThread) and (AdjustLen = -1) and (Item.Content[1] = #10) then begin
623 //
\8d·
\95ª
\8eæ
\93¾
\82©
\82Â
\82P
\83o
\83C
\83g
\96Ú
\82ªLF
\82Ì
\8fê
\8d\87\81i
\90³
\8fí
\8eæ
\93¾
\81j
\82Í
\93ª
\82ÌLF
\82ð
\8dí
\8f\9c
624 Item.Content := Copy(Item.Content, 2, Length(Item.Content));
627 Item.State := gdsError;
629 Item.ResponseCode := FIndy.ResponseCode;
634 FIndy.Get(URL, ResStream);
635 Item.Content := GikoSys.GzipDecompress(ResStream, FIndy.Response.ContentEncoding);
637 Item.State := gdsError;
640 CgiStatus := ParseCgiStatus(Item.Content);
641 if CgiStatus.FStatus = gcsOK then begin
642 if CgiStatus.FSize = 0 then
643 Item.State := gdsNotModify
644 else if Item.DownType = gdtBoard then
645 Item.State := gdsComplete
647 Item.State := gdsDiffComplete;
648 end else if CgiStatus.FStatus = gcsINCR then begin
649 Item.State := gdsComplete;
650 end else if CgiStatus.FStatus = gcsERR then begin
651 Item.State := gdsError;
652 Item.ErrText := CgiStatus.FErrText;
654 Item.ContentLength := CgiStatus.FSize;
657 Item.State := gdsError;
659 //Item.ResponseCode := FIndy.ResponseCode;
661 Item.State := gdsAbort;
663 if Assigned(OnDownloadEnd) then
664 Synchronize(FireDownloadEnd);
668 FIndy.Request.CustomHeaders.Clear;
669 FIndy.Request.RawHeaders.Clear;
671 FIndy.Response.CustomHeaders.Clear;
672 FIndy.Response.RawHeaders.Clear;
673 FIndy.Response.Clear;
674 FIndy.ProxyParams.Clear;
676 if Terminated then Break;
681 function TDownloadThread.CgiDownload(ItemType: TGikoDownloadType; URL: string; Modified: TDateTime): Boolean;
683 ResponseCode: Integer;
684 ResStream: TMemoryStream;
687 FIndy.Request.ContentRangeStart := 0;
688 FIndy.Request.ContentRangeEnd := 0;
690 FIndy.Request.CustomHeaders.Clear;
691 if (Modified <> 0) and (Modified <> ZERO_DATE) then begin
692 FIndy.Request.LastModified := modified - OffsetFromUTC;
694 FIndy.Request.AcceptEncoding := '';
695 FIndy.Request.Accept := 'text/html';
696 ResStream := TMemoryStream.Create;
701 Writeln('URL: ' + URL);
703 FIndy.Get(URL, ResStream);
704 Item.Content := GikoSys.GzipDecompress(ResStream, FIndy.Response.ContentEncoding);
705 Item.LastModified := FIndy.Response.LastModified;
706 //
\8d·
\95ª
\8eæ
\93¾
\82Å
\82P
\83o
\83C
\83g
\91O
\82©
\82ç
\82Æ
\82Á
\82Ä
\82«
\82½
\82Æ
\82«
\82Í
\83}
\83C
\83i
\83X
\82·
\82é
707 Item.ContentLength := Length(Item.Content);
708 //
\96³
\82¢
\82Æ
\8ev
\82¤
\82¯
\82Ç
\81B
\81B
\81B
709 if Item.Content = '' then
714 Writeln('
\8eæ
\93¾
\82Å
\97á
\8aO
\82È
\82µ');
716 ResponseCode := FIndy.ResponseCode;
718 on E: EIdSocketError do begin
720 Item.LastModified := ZERO_DATE;
721 Item.ContentLength := 0;
722 Item.ErrText := E.Message;
725 Screen.Cursor := crDefault;
727 on E: EIdConnectException do begin
729 Item.LastModified := ZERO_DATE;
730 Item.ContentLength := 0;
731 Item.ErrText := E.Message;
734 Screen.Cursor := crDefault;
736 on E: Exception do begin
738 Writeln('
\8eæ
\93¾
\82Å
\97á
\8aO
\82 \82è');
739 Writeln('E.Message: ' + E.Message);
742 Item.LastModified := ZERO_DATE;
743 Item.ContentLength := 0;
744 Item.ErrText := E.Message;
745 ResponseCode := FIndy.ResponseCode;
747 Screen.Cursor := crDefault;
751 if (Item.ContentLength = 0) and (ResponseCode = 206) then
752 Item.ResponseCode := 304
754 Item.ResponseCode := ResponseCode;
759 function TDownloadThread.DatDownload(ItemType: TGikoDownloadType; URL: string; Modified: TDateTime; RangeStart: Integer; AdjustLen: Integer): Boolean;
761 ResponseCode: Integer;
762 ResStream: TMemoryStream;
765 if (ItemType = gdtThread) and (RangeStart > 0) then begin
766 // if (ItemType = gdtThread) and (Item.ThreadItem.Size > 0) then begin
767 // FIndy.Request.ContentRangeStart := Item.ThreadItem.Size + AdjustLen;
768 FIndy.Request.ContentRangeStart := RangeStart + AdjustLen;
769 FIndy.Request.ContentRangeEnd := 0;
771 FIndy.Request.ContentRangeStart := 0;
772 FIndy.Request.ContentRangeEnd := 0;
775 FIndy.Request.CustomHeaders.Clear;
776 FIndy.Request.CacheControl := 'no-cache';
777 FIndy.Request.CustomHeaders.Add('Pragma: no-cache');
778 if (Modified <> 0) and (Modified <> ZERO_DATE) then begin
779 FIndy.Request.LastModified := modified - OffsetFromUTC;
780 //FIndy.Request.CustomHeaders.Add('If-Modified-Since: ' + RFC1123_Date(modified - OffsetFromUTC) + ' GMT');
782 // FIndy.Request.AcceptEncoding := 'gzip';
783 if RangeStart = 0 then
784 FIndy.Request.AcceptEncoding := 'gzip'
786 FIndy.Request.AcceptEncoding := '';
787 ResStream := TMemoryStream.Create;
792 Writeln('URL: ' + URL);
794 FIndy.Get(URL, ResStream);
795 Item.Content := GikoSys.GzipDecompress(ResStream, FIndy.Response.ContentEncoding);
796 Item.LastModified := FIndy.Response.LastModified;
797 //
\8d·
\95ª
\8eæ
\93¾
\82Å
\82P
\83o
\83C
\83g
\91O
\82©
\82ç
\82Æ
\82Á
\82Ä
\82«
\82½
\82Æ
\82«
\82Í
\83}
\83C
\83i
\83X
\82·
\82é
798 // Item.ContentLength := FIndy.Response.ContentLength + AdjustLen;
799 Item.ContentLength := Length(Item.Content) + AdjustLen;
800 //
\96³
\82¢
\82Æ
\8ev
\82¤
\82¯
\82Ç
\81B
\81B
\81B
801 // if (FIndy.ResponseCode in [200, 206]) and (Item.Content = '') then
803 if Item.Content = '' then
808 Writeln('
\8eæ
\93¾
\82Å
\97á
\8aO
\82È
\82µ');
810 ResponseCode := FIndy.ResponseCode;
812 on E: EIdSocketError do begin
814 Item.LastModified := ZERO_DATE;
815 Item.ContentLength := 0;
816 Item.ErrText := E.Message;
819 Screen.Cursor := crDefault;
821 on E: EIdConnectException do begin
823 Item.LastModified := ZERO_DATE;
824 Item.ContentLength := 0;
825 Item.ErrText := E.Message;
828 Screen.Cursor := crDefault;
830 on E: Exception do begin
832 Writeln('
\8eæ
\93¾
\82Å
\97á
\8aO
\82 \82è');
833 Writeln('E.Message: ' + E.Message);
836 Item.LastModified := ZERO_DATE;
837 Item.ContentLength := 0;
838 Item.ErrText := E.Message;
839 ResponseCode := FIndy.ResponseCode;
841 Screen.Cursor := crDefault;
845 if (Item.ContentLength = 0) and (ResponseCode = 206) then
846 Item.ResponseCode := 304
848 Item.ResponseCode := ResponseCode;
853 procedure TDownloadThread.FireDownloadEnd;
855 OnDownloadEnd(self, Item);
858 procedure TDownloadThread.FireDownloadMsg;
860 OnDownloadMsg(Self, Item, FMsg, FIcon);
863 procedure TDownloadThread.GetSessionID;
865 FSessionID := GikoSys.Dolib.SessionID;
868 procedure TDownloadThread.Abort;
871 FIndy.DisconnectSocket;
872 if socket <> nil then begin
873 socket.DisconnectSocket;
877 procedure TDownloadThread.WorkBegin(Sender: TObject; AWorkMode: TWorkMode; const AWorkCountMax: Integer);
879 if Assigned(OnWorkBegin) then
880 OnWorkBegin(Sender, AWorkMode, AWorkCountMax, FNumber, FDownloadTitle);
883 procedure TDownloadThread.WorkEnd(Sender: TObject; AWorkMode: TWorkMode);
885 if Assigned(OnWorkEnd) then
886 OnWorkEnd(Sender, AWorkMode, FNumber);
889 procedure TDownloadThread.Work(Sender: TObject; AWorkMode: TWorkMode; const AWorkCount: Integer);
891 if Assigned(OnWork) then
892 OnWork(Sender, AWorkMode, AWorkCount, FNumber);
895 function TDownloadThread.ParseCgiStatus(Content: string): TCgiStatus;
904 // [+OK]
\82Ì
\8fê
\8d\87\82Í
\8d·
\95ª
905 // [-INCR] (Incorrect)
\82Ì
\8fê
\8d\87\82Í
\82·
\82×
\82Ä
\82Ì
\83f
\81[
\83^
906 // [-ERR (
\83e
\83L
\83X
\83g)]
\82Ì
\8fê
\8d\87\82Í
\82È
\82ñ
\82©
\83G
\83\89\81[
907 //
\97á
\81F+OK 23094/512K
909 // -ERR
\82»
\82ñ
\82È
\94Â
\82È
\82¢
\82Å
\82·
910 Idx := AnsiPos(#10, Content);
911 StatusLine := Copy(Content, 0, Idx);
913 Idx := AnsiPos(' ', Content);
914 Status := Copy(StatusLine, 0, Idx - 1);
915 Line := Copy(StatusLine, Idx + 1, Length(StatusLine));
917 // Idx := AnsiPos('/', Line);
918 if Trim(Status) = '-ERR' then
921 Size := Copy(Line, 0, Idx - 1);
923 if Trim(Status) = '+OK' then
924 Result.FStatus := gcsOK
925 else if Trim(Status) = '-INCR' then
926 Result.FStatus := gcsINCR
927 else if Trim(Status) = '-ERR' then begin
928 Result.FStatus := gcsERR;
929 Result.FErrText := Msg;
936 Result.FStatus := gcsERR;
937 Result.FErrText := '
\83G
\83\89\81[
\82È
\82ñ
\82¾
\82¯
\82Ç
\81A
\82æ
\82
\95ª
\82©
\82ç
\82È
\82¢
\83G
\83\89\81[';
942 if GikoSys.IsNumeric(Size) then
943 Result.FSize := StrToInt(Size)
946 Result.FStatus := gcsERR;
947 Result.FErrText := '
\83X
\83e
\81[
\83^
\83X
\89ð
\90Í
\8e¸
\94s[' + StatusLine + ']';
951 //
\8eè
\94²
\82«
\82È
\8f\88\97\9d\82Å1
\8ds
\96Ú
\82ð
\8fÁ
\82·
952 function TDownloadThread.DeleteStatusLine(Content: string): string;
956 SList := TStringList.Create;
958 SList.Text := Content;
959 if SList.Count > 1 then
961 Result := SList.Text;
967 procedure TDownloadItem.SaveListFile;
971 NewItem: TThreadItem;
978 function MakeThreadCallBack(
979 inInstance : DWORD; // TBoardItem
\82Ì
\83C
\83\93\83X
\83^
\83\93\83X
980 inURL : PChar; //
\83X
\83\8c\83b
\83h
\82Ì URL
981 inTitle : PChar; //
\83X
\83\8c\83^
\83C
982 inCount : DWORD //
\83\8c\83X
\82Ì
\90\94
983 ) : Boolean; stdcall; //
\97ñ
\8b\93\82ð
\91±
\82¯
\82é
\82È
\82ç True
985 _ThreadItem : TThreadItem; // '_'
\82Í
\83N
\83\89\83X
\82Ì
\83v
\83\8d\83p
\83e
\83B
\82Æ
\82©
\82Ô
\82Á
\82Ä
\82é
\82Ì
\82Å
989 boardItem := TBoard( inInstance );
991 boardItem.IntData := boardItem.IntData + 1;
992 if boardItem.IntData < (boardItem.Count shr 2) then
993 index := boardItem.GetIndexFromURL( string( inURL ) )
995 index := boardItem.GetIndexFromURL( string( inURL ), True );
996 if index = -1 then begin
997 //
\90V
\82µ
\82¢
\83X
\83\8c\83b
\83h
998 _ThreadItem := TThreadItem.Create( boardItem.BoardPlugIn, boardItem, string( inURL ) );
1000 _ThreadItem.Title := string( inTitle );
1001 _ThreadItem.AllResCount := inCount;
1002 _ThreadItem.ParentBoard := Board;
1003 _ThreadItem.No := boardItem.IntData;
1004 _ThreadItem.RoundDate := ZERO_DATE;
1005 _ThreadItem.LastModified := ZERO_DATE;
1006 _ThreadItem.AgeSage := gasNew;
1007 boardItem.Add(_ThreadItem);
1009 //
\8f\87\88Ê
\82ª
\8fã
\82ª
\82Á
\82Ä
\82¢
\82ê
\82ÎAge
\82É
\82·
\82é
1010 if boardItem.Items[index].No > boardItem.IntData then
1011 boardItem.Items[index].AgeSage := gasAge
1012 //
\8f\87\88Ê
\82ª
\8fã
\82ª
\82Á
\82Ä
\82È
\82¢
\82¯
\82Ç
\81A
\83\8c\83X
\82ª
\82Â
\82¢
\82Ä
\82½
\82ç
\81ASage
\82É
1013 else if boardItem.Items[index].AllResCount <> inCount then
1014 boardItem.Items[index].AgeSage := gasSage
1015 //
\8f\87\88Ê
\8fã
\82ª
\82Á
\82Ä
\82È
\82¢
\82µ
\81A
\83\8c\83X
\82Ì
\91\9d\8c¸
\82à
\96³
\82¯
\82ê
\82Î
\81ANone
1017 boardItem.Items[index].AgeSage := gasNone;
1019 boardItem.Items[index].No := boardItem.IntData;
1020 boardItem.Items[index].AllResCount := inCount;
1027 Writeln('SAVELIST');
1029 //Board.ListData := TList.Create;
1030 Body := TStringList.Create;
1032 //
\83_
\83E
\83\93\83\8d\81[
\83h
\93ú
\8e\9e\90Ý
\92è
\81i
\83\8d\81[
\83J
\83\8b\93ú
\8e\9e\81j
1033 Board.RoundDate := Now;
1034 //
\83T
\81[
\83o
\8fã
\83t
\83@
\83C
\83\8b\82Ì
\8dX
\90V
\8e\9e\8d\8f\90Ý
\92è
1035 Board.LastModified := LastModified;
1038 //dat
\97\8e\82¿
\83X
\83\8c\82Ì
\83\
\81[
\83g
\8f\87\82ð
\8c\88\92è
\82·
\82é
\82½
\82ß
\82É
\83\
\81[
\83g
\82·
\82é
1039 if GikoSys.Setting.DatOchiSortIndex >= 0 then begin
1040 Sort.SortNoFlag := true;
1041 Sort.SortOrder := GikoSys.Setting.DatOchiSortOrder;
1042 Sort.SortIndex := GikoSys.Setting.DatOchiSortIndex;
1043 //Sort.SortNonAcquiredCountFlag := GikoSys.Setting.NonAcquiredCount;
1044 Board.CustomSort(ThreadItemSortProc);
1048 rt := GetTickCount - st;
1049 Writeln('END Sortd' + IntToStr(rt) + ' ms');
1052 for i := Board.Count - 1 downto 0 do
1053 Board.Items[i].AgeSage := gasNull;
1055 if Board.IsBoardPlugInAvailable then begin
1056 //
\90V
\82µ
\82¢
\83\8a\83X
\83g
\82ð
\8dì
\90¬
\82·
\82é
1057 //
\90V
\82µ
\82¢
\83\8a\83X
\83g
\82É
\8cÃ
\82¢
\83\8a\83X
\83g
\82Ì
\83\8d\83O
\82ª
\82 \82é
\82È
\82ç
\82»
\82ê
\82ð
\90V
\82µ
\82¢
\83\8a\83X
\83g
\82É
\92Ç
\89Á
1058 //
\8cÃ
\82¢
\83\8d\83O
\82ª
\82È
\82¯
\82ê
\82Î
\81A
\90V
\82½
\82É
\83X
\83\8c\83I
\83u
\83W
\83F
\83N
\83g
\82ð
\8dì
\90¬
1061 rt := GetTickCount - st;
1062 Writeln('Start Enum' + IntToStr(rt) + ' ms');
1065 //
\82±
\82ê
\82ª
\92x
\82¢
\81@
\97v
\89ü
\91P
1067 Board.BoardPlugIn.EnumThread( DWORD( Board ), @MakeThreadCallBack );
1071 rt := GetTickCount - st;
1072 Writeln('End Enum' + IntToStr(rt) + ' ms');
1075 //
\8cÃ
\82¢
\83\8a\83X
\83g
\82É
\82µ
\82©
\82È
\82¢
\82â
\82Â
\82ç
\82ð
\8dí
\8f\9c
1076 for i := Board.Count - 1 downto 0 do begin
1077 if( Board.Items[i].AgeSage = gasNull )and not (Board.Items[i].IsLogFile) then
1081 //
\90V
\82µ
\82¢
\83\8a\83X
\83g
\82É
\96³
\82©
\82Á
\82½
\83A
\83C
\83e
\83\80\82ð
\90V
\82µ
\82¢
\83\8a\83X
\83g
\82É
\92Ç
\89Á
1082 for i := 0 to Board.Count - 1 do begin
1083 if(Board.Items[i].AgeSage = gasNull) and (Board.Items[i].IsLogFile) then begin
1084 Board.IntData := Board.IntData + 1;
1085 Board.Items[i].No := Board.IntData;
1086 Board.Items[i].AllResCount := Board.Items[i].Count;
1087 Board.Items[i].NewResCount := 0;
1088 Board.Items[i].AgeSage := gasNone;
1093 //
\90V
\82µ
\82¢
\83\8a\83X
\83g
\82ð
\8dì
\90¬
\82·
\82é
1094 //
\90V
\82µ
\82¢
\83\8a\83X
\83g
\82É
\8cÃ
\82¢
\83\8a\83X
\83g
\82Ì
\83\8d\83O
\82ª
\82 \82é
\82È
\82ç
\82»
\82ê
\82ð
\90V
\82µ
\82¢
\83\8a\83X
\83g
\82É
\92Ç
\89Á
1095 //
\8cÃ
\82¢
\83\8d\83O
\82ª
\82È
\82¯
\82ê
\82Î
\81A
\90V
\82½
\82É
\83X
\83\8c\83I
\83u
\83W
\83F
\83N
\83g
\82ð
\8dì
\90¬
1096 Body.Text := Content;
1098 for i := 0 to Body.Count - 1 do begin
1099 Rec := GikoSys.DivideSubject(Body[i]);
1100 Rec.FFileName := Trim(Rec.FFileName);
1101 if (Rec.FTitle = '') and (Rec.FCount = 0) then Continue;
1103 index := Board.GetIndexFromFileName(Rec.FFileName);
1104 if index = -1 then begin
1105 //
\90V
\82µ
\82¢
\83X
\83\8c\83b
\83h
1106 NewItem := TThreadItem.Create(
1109 GikoSys.Get2chBoard2ThreadURL( Board, ChangeFileExt( Rec.FFileName, '' ) ) );
1110 NewItem.Title := Rec.FTitle;
1111 NewItem.AllResCount := Rec.FCount;
1112 NewItem.ParentBoard := Board;
1113 NewItem.No := NumCount;
1114 NewItem.RoundDate := ZERO_DATE;
1115 NewItem.LastModified := ZERO_DATE;
1116 NewItem.AgeSage := gasNew;
1119 if Board.Items[index].No > NumCount then
1120 Board.Items[index].AgeSage := gasAge
1121 else if Board.Items[index].AllResCount < Rec.FCount then
1122 Board.Items[index].AgeSage := gasSage
1124 Board.Items[index].AgeSage := gasNone;
1126 Board.Items[index].No := NumCount;
1127 Board.Items[index].AllResCount := Rec.FCount;
1130 //
\8cÃ
\82¢
\83\8a\83X
\83g
\82Ì
\8dí
\8f\9c
1131 for i := Board.Count - 1 downto 0 do begin
1132 if( Board.Items[i].AgeSage = gasNull )and not (Board.Items[i].IsLogFile) then
1136 //
\90V
\82µ
\82¢
\83\8a\83X
\83g
\82É
\96³
\82©
\82Á
\82½
\83A
\83C
\83e
\83\80\82Ì
\8dX
\90V
1137 for i := 0 to Board.Count - 1 do begin
1138 if( Board.Items[i].AgeSage = gasNull )and (Board.Items[i].IsLogFile) then begin
1140 Board.Items[i].No := NumCount;
1141 Board.Items[i].AllResCount := Board.Items[i].Count;
1142 Board.Items[i].NewResCount := 0;
1143 Board.Items[i].AgeSage := gasNone;
1146 //
\83\8a\83X
\83g(subject.txt)
\82ð
\95Û
\91¶
1147 GikoSys.ForceDirectoriesEx(ExtractFilePath(Board.GetSubjectFileName));
1148 Body.SaveToFile(Board.GetSubjectFileName);
1157 {procedure TDownloadItem.SaveListFile;
1161 NewItem: TThreadItem;
1163 // SaveCount: Integer;
1168 NewList := TList.Create;
1169 Body := TStringList.Create;
1171 //
\8f\84\89ñ
\93ú
\8e\9e\90Ý
\92è
1172 Board.RoundDate := Now;
1173 //
\83T
\81[
\83o
\8fã
\83t
\83@
\83C
\83\8b\82Ì
\8dX
\90V
\8e\9e\8d\8f\90Ý
\92è
1174 Board.LastModified := LastModified;
1176 //
\83\8a\83X
\83g
\95Û
\91¶
\8c\8f\90\94\8eæ
\93¾
1177 //SaveCount := MaxInt;
1179 //
\8cÃ
\82¢
\83\8a\83X
\83g
\82©
\82ç
\83\8d\83O
\96³
\82µ
\83A
\83C
\83e
\83\80\82ð
\8dí
\8f\9c
1180 for i := Board.Count - 1 downto 0 do
1181 if not Board.Items[i].IsLogFile then
1184 //
\90V
\82µ
\82¢
\83\8a\83X
\83g
\82ð
\8dì
\90¬
\82·
\82é
1185 //
\90V
\82µ
\82¢
\83\8a\83X
\83g
\82É
\8cÃ
\82¢
\83\8a\83X
\83g
\82Ì
\83\8d\83O
\82ª
\82 \82é
\82È
\82ç
\82»
\82ê
\82ð
\90V
\82µ
\82¢
\83\8a\83X
\83g
\82É
\92Ç
\89Á
1186 //
\8cÃ
\82¢
\83\8d\83O
\82ª
\82È
\82¯
\82ê
\82Î
\81A
\90V
\82½
\82É
\83X
\83\8c\83I
\83u
\83W
\83F
\83N
\83g
\82ð
\8dì
\90¬
1187 Body.Text := Content;
1188 // Loop := Min(Body.Count, SaveCount);
1190 // for i := 0 to Loop - 1 do begin
1191 for i := 0 to Body.Count - 1 do begin
1192 if i = 0 then Continue; //
\82P
\8ds
\96Ú
\82Í
\83X
\83e
\81[
\83^
\83X
\8ds
\82Ì
\82½
\82ß
\8f\88\97\9d\82È
\82µ
1194 Rec := GikoSys.DivideSubject(Body[i]);
1195 if (Rec.FTitle = '') and (Rec.FCount = 0) then Continue;
1197 index := Board.GetIndex(Rec.FFileName);
1198 if index = -1 then begin
1199 NewItem := TThreadItem.Create;
1200 NewItem.FileName := Rec.FFileName;
1201 NewItem.Title := Rec.FTitle;
1202 NewItem.Count := Rec.FCount;
1203 NewItem.ParentBoard := Board;
1204 NewItem.No := NumCount;
1205 NewItem.RoundDate := ZERO_DATE;
1206 NewItem.LastModified := ZERO_DATE;
1207 NewList.Add(NewItem);
1209 //Board.Items[index].Count := Count;
1210 Board.Items[index].No := NumCount;
1211 NewList.Add(Board.Items[index]);
1212 Board.DeleteList(index);
1216 //
\90V
\82µ
\82¢
\83\8a\83X
\83g
\82É
\96³
\82©
\82Á
\82½
\8cÃ
\82¢
\83\8d\83O
\97L
\82è
\83A
\83C
\83e
\83\80\82ð
\90V
\82µ
\82¢
\83\8a\83X
\83g
\82É
\92Ç
\89Á
1217 for i := 0 to Board.Count - 1 do begin
1219 Board.Items[i].No := NumCount;
1220 NewList.Add(Board.Items[i]);
1223 //
\8cÃ
\82¢
\83\8a\83X
\83g
\82ð
\8fÁ
\82·
\81i
\83\8a\83X
\83g
\82Ì
\82Ý
\81B
\83X
\83\8c\83I
\83u
\83W
\83F
\83N
\83g
\8e©
\91Ì
\82Í
\8fÁ
\82³
\82È
\82¢
\81j
1224 for i := Board.Count - 1 downto 0 do
1225 Board.DeleteList(i);
1227 //
\90V
\82µ
\82¢
\83\8a\83X
\83g
\82ð
\83{
\81[
\83h
\83I
\83u
\83W
\83F
\83N
\83g
\82É
\92Ç
\89Á
1228 for i := 0 to NewList.Count - 1 do
1229 Board.Add(TThreadItem(NewList[i]));
1231 //
\83\8a\83X
\83g(subject.txt)
\82ð
\95Û
\91¶
1232 // GikoSys.ForceDirectoriesEx(GikoSys.GetLogDir + Board.BBSID);
1233 // Body.SaveToFile(GikoSys.GetSubjectFileName(Board.BBSID));
1234 GikoSys.ForceDirectoriesEx(ExtractFilePath(Board.GetSubjectFileName));
1235 Body.SaveToFile(Board.GetSubjectFileName);
1242 procedure TDownloadItem.SaveItemFile;
1244 Body, oldBody: TStringList;
1253 // KokoTxt : string;
1254 // KokoIdx : Integer;
1256 // NewIdx : Integer;
1257 // LastTxt : string;
1260 FileName := ThreadItem.GetThreadFileName;
1262 //if not ThreadItem.IsBoardPlugInAvailable then begin
1263 if not ThreadItem.ParentBoard.IsBoardPlugInAvailable then begin
1264 if Trim(Content) = '' then
1267 GikoSys.ForceDirectoriesEx(ExtractFilePath(FileName));
1270 Body := TStringList.Create;
1274 // if FileExists(FileName) and (ResponseCode = 206) then begin
1275 if FileExists(FileName) and (State = gdsDiffComplete) then begin
1280 Body.LoadFromFile(FileName);
1281 OldCnt := Body.Count;
1282 Body.Text := Body.Text + Content;
1283 Body.SaveToFile(FileName);
1284 NewRes := Body.Count - OldCnt;
1286 on E:EFOpenError do begin
1294 //Cnt := Body.Count;
1296 if IsAbone then begin
1297 //
\82 \82Ú
\81[
\82ñ
\82ð
\8c\9f\8fo
\82µ
\82½
\82Ì
\82Å
\82±
\82±
\82Ü
\82Å
\93Ç
\82ñ
\82¾
\82Æ
\90V
\92\85\83\8c\83X
\94Ô
\82Ì
\82Â
\82¯
\82È
\82¨
\82µ
1298 oldBody := TStringList.Create;
1304 oldBody.LoadFromFile(FileName);
1306 on E:EFOpenError do begin
1317 Body.Text := Content;
1318 if (ThreadItem.Kokomade > 0) and (ThreadItem.Kokomade <= oldBody.Count) then begin
1319 ThreadItem.Kokomade := Body.IndexOf(oldBody.Strings[ ThreadItem.Kokomade - 1 ]);
1320 if ThreadItem.Kokomade <> -1 then ThreadItem.Kokomade := ThreadItem.Kokomade + 1;
1323 LastIdx := oldBody.Count;
1326 OldCnt := Body.IndexOf(oldBody.Strings[ LastIdx ]) + 1;
1327 until ( OldCnt <> 0 ) or (LastIdx = 0);
1329 if OldCnt >= Body.Count then OldCnt := Body.Count - 1;
1330 NewRes := Body.Count - OldCnt;
1332 //
\82±
\82±
\82Ü
\82Å
\93Ç
\82ñ
\82¾
\82ª
\90V
\92\85\83\8c\83X
\94Ô
\82ð
\92´
\82³
\82È
\82¢
\82æ
\82¤
\82É(
\88Ù
\8fí
\8fI
\97¹
\8e\9e\82Ì
\83\8a\83J
\83o
\83\8a)
1333 if ThreadItem.Kokomade > OldCnt then begin
1335 ThreadItem.Kokomade := OldCnt
1337 ThreadItem.Kokomade := 1;
1345 Body.Text := Content;
1346 //ThreadItem.Count := 0;
1348 NewRes := Body.Count;
1349 //Cnt := Body.Count;
1351 // if Body.Count > 0 then
1353 Body.SaveToFile(FileName);
1355 if ThreadItem.Title = '' then begin
1356 THTMLCreate.DivideStrLine(Body[0], @Res);
1357 ThreadItem.Title := Res.FTitle;
1359 ThreadItem.Size := 0;
1366 ThreadItem.Size := ThreadItem.Size + ContentLength;
1367 ThreadItem.LastModified := LastModified;
1368 ThreadItem.Count := Cnt;
1369 //ThreadItem.AllResCount := Cnt;
1370 ThreadItem.NewResCount := NewRes;
1371 ThreadItem.NewReceive := OldCnt + 1;
1373 ThreadItem.AllResCount := ThreadItem.Count;
1374 ThreadItem.IsLogFile := True;
1375 ThreadItem.RoundDate := Now;
1376 if not ThreadItem.UnRead then begin
1377 ThreadItem.UnRead := True;
1378 ThreadItem.ParentBoard.UnRead := ThreadItem.ParentBoard.UnRead + 1;
1380 // if ThreadItem.RoundNo = 6 then
1381 // ThreadItem.RoundNo := 0;
1383 //
\88Ù
\8fí
\8fI
\97¹
\8e\9e\82Í
\83C
\83\93\83f
\83b
\83N
\83X
\82ª
\8dX
\90V
\82³
\82ê
\82È
\82¢
\82½
\82ß
\81A
\83e
\83\93\83|
\83\89\83\8a\82ð
\8dì
\90¬
\82·
\82é
\81B
1384 //
\90³
\8fí
\8fI
\97¹
\8e\9e\82É
\82Í
\8dí
\8f\9c
1385 //
\88Ù
\8fí
\8fI
\97¹
\8e\9e\82Í
\81A
\8e\9f\89ñ
\8bN
\93®
\8e\9e\82É
\83e
\83\93\83|
\83\89\83\8a\82ð
\8c©
\82Ä
\8dX
\90V
1386 ini := TMemIniFile.Create(ChangeFileExt(FileName, '.tmp'));
1388 ini.WriteDateTime('Setting', 'RoundDate', ThreadItem.RoundDate);
1389 ini.WriteDateTime('Setting', 'LastModified', ThreadItem.LastModified);
1390 ini.WriteInteger('Setting', 'Size', ThreadItem.Size);
1391 ini.WriteInteger('Setting', 'Count', ThreadItem.Count);
1392 ini.WriteInteger('Setting', 'AllResCount', ThreadItem.AllResCount);
1393 ini.WriteInteger('Setting', 'NewResCount', ThreadItem.NewResCount);
1394 ini.WriteInteger('Setting', 'NewReceive', ThreadItem.NewReceive);
1395 // ini.WriteInteger('Setting', 'RoundNo', ThreadItem.RoundNo);
1396 // ini.WriteBool('Setting', 'Round', ThreadItem.Round);
1397 ini.WriteBool('Setting', 'UnRead', ThreadItem.UnRead);