6 Windows, SysUtils, Classes, ComCtrls, Controls, Forms, IdHTTP,
7 {HTTPApp,} YofUtils, IdGlobal, IdException, IdComponent, IniFiles, {DateUtils,}
8 GikoSystem, BoardGroup, 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 procedure DeleteStatusLine(Item: TDownloadItem);
57 procedure InitHttpClient(client: TIdHttp);
58 procedure ClearHttpClient(client: TIdHttp);
60 procedure Execute; override;
62 property Item: TDownloadItem read FItem write FItem;
63 property Number: Integer read FNumber write FNumber;
64 constructor Create(CreateSuspended: Boolean);
65 destructor Destroy; override;
67 property OnWork: TGikoWorkEvent read FOnWork write FOnWork;
68 property OnWorkBegin: TGikoWorkBeginEvent read FOnWorkBegin write FOnWorkBegin;
69 property OnWorkEnd: TGikoWorkEndEvent read FOnWorkEnd write FOnWorkEnd;
70 property OnDownloadEnd: TDownloadEndEvent read FOnDownloadEnd write FOnDownloadEnd;
71 property OnDownloadMsg: TDownloadMsgEvent read FOnDownloadMsg write FOnDownloadMsg;
74 TDownloadItem = class(TObject)
76 FDownType: TGikoDownloadType;
78 FThreadItem: TThreadItem;
80 FContentLength: Integer;
81 FLastModified: TDateTime;
83 FResponseCode: Smallint;
84 FState: TGikoDownloadState;
86 FForceDownload: Boolean;
89 procedure SaveListFile;
90 procedure SaveItemFile;
92 property DownType: TGikoDownloadType read FDownType write FDownType;
93 property Board: TBoard read FBoard write FBoard;
94 property ThreadItem: TThreadItem read FThreadItem write FThreadItem;
96 property ContentLength: Integer read FContentLength write FContentLength;
97 property LastModified: TDateTime read FLastModified write FLastModified;
98 property Content: string read FContent write FContent;
99 property ResponseCode: Smallint read FResponseCode write FResponseCode;
100 property State: TGikoDownloadState read FState write FState;
101 property ErrText: string read FErrText write FErrText;
102 property ForceDownload: Boolean read FForceDownload write FForceDownload;
103 property IsAbone : Boolean read FIsAbone write FIsAbone;
109 Y_TextConverter, MojuUtils, HTMLCreate, ReplaceDataModule;
111 constructor TDownloadThread.Create(CreateSuspended: Boolean);
113 inherited Create(CreateSuspended);
114 FIndy := TIdHttp.Create(nil);
116 FIndy.OnWorkBegin := WorkBegin;
117 FIndy.OnWorkEnd := WorkEnd;
118 FIndy.OnWork := Work;
121 destructor TDownloadThread.Destroy;
123 ClearHttpClient(FIndy);
128 function RFC1123_Date(aDate : TDateTime) : String;
130 StrWeekDay : String = 'MonTueWedThuFriSatSun';
131 StrMonth : String = 'JanFebMarAprMayJunJulAugSepOctNovDec';
133 Year, Month, Day : Word;
134 Hour, Min, Sec, MSec : Word;
137 DecodeDate(aDate, Year, Month, Day);
138 DecodeTime(aDate, Hour, Min, Sec, MSec);
139 DayOfWeek := ((Trunc(aDate) - 2) mod 7);
140 Result := Copy(StrWeekDay, 1 + DayOfWeek * 3, 3) + ', ' +
141 Format('%2.2d %s %4.4d %2.2d:%2.2d:%2.2d',
142 [Day, Copy(StrMonth, 1 + 3 * (Month - 1), 3),
143 Year, Hour, Min, Sec]);
145 // ******************************************************************
146 // HTTPClient
\82Ì
\8f\89\8aú
\89»
147 // ******************************************************************
148 procedure TDownloadThread.InitHttpClient(client: TIdHttp);
150 ClearHttpClient(client);
152 client.Request.UserAgent := GikoSys.GetUserAgent;
153 client.RecvBufferSize := Gikosys.Setting.RecvBufferSize;
154 client.ProxyParams.BasicAuthentication := False;
155 client.ReadTimeout := GikoSys.Setting.ReadTimeOut;
157 Writeln('------------------------------------------------------------');
159 //FIndy.AllowCookies := False;
160 if GikoSys.Setting.ReadProxy then begin
161 if GikoSys.Setting.ProxyProtocol then
162 client.ProtocolVersion := pv1_1
164 client.ProtocolVersion := pv1_0;
165 client.ProxyParams.ProxyServer := GikoSys.Setting.ReadProxyAddress;
166 client.ProxyParams.ProxyPort := GikoSys.Setting.ReadProxyPort;
167 client.ProxyParams.ProxyUsername := GikoSys.Setting.ReadProxyUserID;
168 client.ProxyParams.ProxyPassword := GikoSys.Setting.ReadProxyPassword;
169 if GikoSys.Setting.ReadProxyUserID <> '' then
170 client.ProxyParams.BasicAuthentication := True;
172 Writeln('
\83v
\83\8d\83L
\83V
\90Ý
\92è
\82 \82è');
173 Writeln('
\83z
\83X
\83g: ' + GikoSys.Setting.ReadProxyAddress);
174 Writeln('
\83|
\81[
\83g: ' + IntToStr(GikoSys.Setting.ReadProxyPort));
177 if GikoSys.Setting.Protocol then
178 client.ProtocolVersion := pv1_1
180 client.ProtocolVersion := pv1_0;
181 client.ProxyParams.ProxyServer := '';
182 client.ProxyParams.ProxyPort := 80;
183 client.ProxyParams.ProxyUsername := '';
184 client.ProxyParams.ProxyPassword := '';
186 Writeln('
\83v
\83\8d\83L
\83V
\90Ý
\92è
\82È
\82µ');
190 // ******************************************************************
191 // HTTPClient
\82Ì
\83\8a\83N
\83G
\83X
\83g
\82Æ
\83\8c\83X
\83|
\83\93\83X
\82Ì
\83f
\81[
\83^
\82Ì
\8fÁ
\8b\8e
192 // ******************************************************************
193 procedure TDownloadThread.ClearHttpClient(client: TIdHttp);
195 client.Request.CustomHeaders.Clear;
196 client.Request.RawHeaders.Clear;
197 client.Request.Clear;
198 client.Response.CustomHeaders.Clear;
199 client.Response.RawHeaders.Clear;
200 client.Response.Clear;
202 client.ProxyParams.Clear;
204 procedure TDownloadThread.Execute;
206 ResStream: TMemoryStream;
209 CgiStatus: TCgiStatus;
215 DownloadResult: Boolean;
216 boardPlugIn : TBoardPlugIn;
217 lastContent : string;
218 logFile : TFileStream;
219 adjustMargin : Integer;
223 while not Terminated do begin
224 //=====
\83v
\83\89\83O
\83C
\83\93
227 ExternalBoardManager.OnWork := Work;
228 ExternalBoardManager.OnWorkBegin := WorkBegin;
229 ExternalBoardManager.OnWorkEnd := WorkEnd;
231 FDownloadTitle := '';
232 case FItem.FDownType of
235 FDownloadTitle := FItem.FBoard.Title;
236 if FItem.FBoard <> nil then begin
237 if FItem.FBoard.IsBoardPlugInAvailable then begin
238 boardPlugIn := FItem.FBoard.BoardPlugIn;
239 Item.State := TGikoDownloadState( boardPlugIn.DownloadBoard( DWORD( FItem.FBoard ) ) );
245 FDownloadTitle := FItem.FThreadItem.Title;
246 if FItem.FThreadItem <> nil then begin
247 if FItem.FThreadItem.ParentBoard.IsBoardPlugInAvailable then begin
248 boardPlugIn := FItem.FThreadItem.ParentBoard.BoardPlugIn;
249 Item.State := TGikoDownloadState( boardPlugIn.DownloadThread( DWORD( FItem.FThreadItem ) ) );
251 //if FItem.FThreadItem.IsBoardPlugInAvailable then begin
252 // boardPlugIn := FItem.FThreadItem.BoardPlugIn;
253 // Item.State := TGikoDownloadState( boardPlugIn.DownloadThread( DWORD( FItem.FThreadItem ) ) );
258 if Length(FDownloadTitle) = 0 then
259 FDownloadTitle := '
\81i
\96¼
\8fÌ
\95s
\96¾
\81j';
261 if boardPlugIn <> nil then begin
263 Item.State := gdsAbort;
265 if Assigned( OnDownloadEnd ) then
266 Synchronize( FireDownloadEnd );
275 //=====
\83v
\83\89\83O
\83C
\83\93\82ð
\8eg
\97p
\82µ
\82È
\82¢
\8fê
\8d\87
276 InitHttpClient(FIndy);
278 if Item.DownType = gdtThread then begin
279 if FileExists( Item.ThreadItem.GetThreadFileName ) then begin
280 // dat
\83t
\83@
\83C
\83\8b\82Ì
\8dÅ
\8cã
\82ð
\93Ç
\82Ý
\8fo
\82·
281 SetLength( lastContent, ADJUST_MARGIN + 1 );
282 logFile := TFileStream.Create( Item.ThreadItem.GetThreadFileName, fmOpenRead or fmShareDenyWrite );
284 logFile.Seek( -(ADJUST_MARGIN + 1), soFromEnd );
285 logFile.Read( lastContent[ 1 ], ADJUST_MARGIN + 1 );
286 lastContent := StringReplace( lastContent, #13, '', [] ); // CR
\82Ì
\8dí
\8f\9c
293 adjustMargin := Length( lastContent );
296 FIndy.Request.ContentRangeStart := 0;
297 FIndy.Request.LastModified := ZERO_DATE;
298 ResStream := TMemoryStream.Create;
301 //********************
302 //DAT or Subject
\8eæ
\93¾
303 //********************
304 Item.ResponseCode := 0;
308 if Item.DownType = gdtBoard then begin
310 Writeln('Subject
\8eæ
\93¾');
311 Writeln('URL: ' + Item.Board.GetReadCgiURL);
312 Writeln('Modified: ' + FloatToStr(Item.Board.LastModified));
314 URL := Item.Board.GetReadCgiURL;
315 if Item.ForceDownload then begin
317 ATitle := Item.Board.Title;
319 ATitle := '
\81i
\96¼
\8fÌ
\95s
\96¾
\81j';
320 FMsg := '
\81\9a\8b
\90§
\8eæ
\93¾
\82ð
\8ds
\82¢
\82Ü
\82· - [' + ATitle + ']';
322 if Assigned(OnDownloadMsg) then
323 Synchronize(FireDownloadMsg);
324 Modified := ZERO_DATE
326 Modified := Item.Board.LastModified;
328 end else if Item.DownType = gdtThread then begin
330 Writeln('DAT
\8eæ
\93¾');
331 Writeln('URL: ' + Item.ThreadItem.GetDatURL);
332 Writeln('Modified: ' + FloatToStr(Item.ThreadItem.LastModified));
334 URL := Item.ThreadItem.GetDatURL;
335 if Item.ForceDownload then begin
337 ATitle := Item.ThreadItem.Title;
339 ATitle := '
\81i
\96¼
\8fÌ
\95s
\96¾
\81j';
340 FMsg := '
\81\9a\8b
\90§
\8eæ
\93¾
\82ð
\8ds
\82¢
\82Ü
\82· - [' + ATitle + ']';
342 if FileExists(ChangeFileExt(Item.FThreadItem.GetThreadFileName,'.NG')) = true then
343 DeleteFile(ChangeFileExt(Item.FThreadItem.GetThreadFileName,'.NG'));
344 if Assigned(OnDownloadMsg) then
345 Synchronize(FireDownloadMsg);
346 Modified := ZERO_DATE;
350 Modified := Item.ThreadItem.LastModified;
351 if Item.ThreadItem.Size > 0 then begin
353 Writeln('RangeStart: ' + IntToStr(Item.ThreadItem.Size));
355 //
\82 \82Ú
\81[
\82ñ
\83`
\83F
\83b
\83N
\82Ì
\82½
\82ß adjustMargin
\83o
\83C
\83g
\91O
\82©
\82ç
\8eæ
\93¾
356 RangeStart := Item.ThreadItem.Size;
357 AdjustLen := -adjustMargin;
361 Item.IsAbone := False;
362 DownloadResult := DatDownload(Item.DownType, URL, Modified, RangeStart, AdjustLen);
364 Writeln('ResponseCode: ' + IntToStr(FIndy.ResponseCode));
366 if Item.DownType = gdtThread then begin
367 if Item.ResponseCode = 416 then begin
368 Item.IsAbone := True;
369 DownloadResult := True;
370 end else if DownloadResult and (AdjustLen < 0) then begin
371 if Copy( Item.Content, 1, adjustMargin ) <> lastContent then
372 Item.IsAbone := True;
376 if Trim(FIndy.Response.RawHeaders.Values['Date']) <> '' then begin
377 if Item.DownType = gdtBoard then
378 Item.Board.LastGetTime := GikoSys.DateStrToDateTime(FIndy.Response.RawHeaders.Values['Date'])
380 Item.ThreadItem.ParentBoard.LastGetTime := GikoSys.DateStrToDateTime(FIndy.Response.RawHeaders.Values['Date']);
383 if DownloadResult then begin
385 Writeln('Date:' + FIndy.Response.RawHeaders.Values['Date']);
387 if Item.IsAbone then begin
389 Writeln('
\82 \82Ú
\81[
\82ñ
\8c\9f\8fo');
391 ATitle := Item.ThreadItem.Title;
393 ATitle := '
\81i
\96¼
\8fÌ
\95s
\96¾
\81j';
394 //
\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¾
397 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 + ']';
399 if FileExists(ChangeFileExt(Item.FThreadItem.GetThreadFileName,'.NG')) = true then
400 DeleteFile(ChangeFileExt(Item.FThreadItem.GetThreadFileName,'.NG'));
401 if Assigned(OnDownloadMsg) then
402 Synchronize(FireDownloadMsg);
403 if not DatDownload(Item.DownType, URL, ZERO_DATE, RangeStart, AdjustLen) then
404 Item.State := gdsError;
406 Writeln('
\82 \82Ú
\81[
\82ñ
\8dÄ
\8eæ
\93¾
\8cã');
407 Writeln('ResponseCode: ' + IntToStr(Item.ResponseCode));
409 end else if (Item.DownType = gdtThread) and (AdjustLen < 0) then begin
410 //
\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
411 Item.Content := Copy(Item.Content, adjustMargin + 1, MaxInt);
414 Item.State := gdsError;
415 if (Item.DownType = gdtBoard) and (Item.ResponseCode = 302) then begin
416 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';
418 if Assigned(OnDownloadMsg) then
419 Synchronize(FireDownloadMsg);
423 //********************
425 //********************
426 if (Item.DownType = gdtThread) and (Item.ResponseCode = 302) then begin
428 Writeln('dat.gz
\8eæ
\93¾');
430 ATitle := Item.ThreadItem.Title;
432 ATitle := '
\81i
\96¼
\8fÌ
\95s
\96¾
\81j';
433 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 + ']';
435 if Assigned(OnDownloadMsg) then
436 Synchronize(FireDownloadMsg);
437 URL := Item.ThreadItem.GetDatgzURL;
438 Modified := Item.ThreadItem.LastModified;
441 if not DatDownload(Item.DownType, URL, Modified, RangeStart, AdjustLen) then
442 Item.State := gdsError;
444 Writeln('ResponseCode: ' + IntToStr(Item.ResponseCode));
448 //********************
449 //dat.gz
\81@
\81¨
\81@dat
\82Ì
\8eæ
\93¾
\81@2005
\94N6
\8c\8e\92Ç
\89Á
\81@by
\82à
\82¶
\82ã
450 //********************
451 if (Item.DownType = gdtThread) and (Item.ResponseCode = 302) then begin
453 Writeln('dat
\8eæ
\93¾');
455 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 + ']';
457 if Assigned(OnDownloadMsg) then
458 Synchronize(FireDownloadMsg);
459 URL := ChangeFileExt(URL, '');
460 Modified := Item.ThreadItem.LastModified;
463 if not DatDownload(Item.DownType, URL, Modified, RangeStart, AdjustLen) then
464 Item.State := gdsError;
466 Writeln('ResponseCode: ' + IntToStr(Item.ResponseCode));
470 //********************
472 //********************
474 if (Item.DownType = gdtThread) and (Item.ResponseCode = 302) then begin
475 ATitle := Item.ThreadItem.Title;
477 ATitle := '
\81i
\96¼
\8fÌ
\95s
\96¾
\81j';
478 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 + ']';
480 if Assigned(OnDownloadMsg) then
481 Synchronize(FireDownloadMsg);
482 URL := Item.ThreadItem.GetOldDatgzURL;
483 Modified := Item.ThreadItem.LastModified;
486 if not DatDownload(Item.DownType, URL, Modified, RangeStart, AdjustLen) then
487 Item.State := gdsError;
491 //********************
492 //offlaw.cgi
\82Å
\8eæ
\93¾
493 //********************
495 Synchronize(GetSessionID);
496 if (Item.DownType = gdtThread) and (Item.ResponseCode = 302) and (FSessionID <> '') then begin
498 Writeln('offlaw.cgi
\82Å
\8eæ
\93¾');
500 ATitle := Item.ThreadItem.Title;
502 ATitle := '
\81i
\96¼
\8fÌ
\95s
\96¾
\81j';
503 FMsg := '
\81\9adat.gz
\82ª
\91¶
\8dÝ
\82µ
\82È
\82¢
\82½
\82ßofflaw.cgi
\82ð
\97\98\97p
\82µ
\82Ü
\82· - [' + ATitle + ']';
505 if Assigned(OnDownloadMsg) then
506 Synchronize(FireDownloadMsg);
507 URL := Item.ThreadItem.GetOfflawCgiURL(FSessionID);
508 Modified := Item.ThreadItem.LastModified;
511 if not DatDownload(Item.DownType, URL, Modified, RangeStart, AdjustLen) then begin
513 Writeln('ResponseCode: ' + IntToStr(Item.ResponseCode));
515 Item.State := gdsError;
517 if (Item.DownType = gdtThread) and (Item.ResponseCode = 302) then begin
518 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';
520 if Assigned(OnDownloadMsg) then
521 Synchronize(FireDownloadMsg);
525 CgiStatus := ParseCgiStatus(Item.Content);
527 Writeln('ResponseCode: ' + IntToStr(Item.ResponseCode));
529 case CgiStatus.FStatus of
532 Writeln('CGIStatus: OK');
534 Item.ResponseCode := 200;
535 DeleteStatusLine(Item);
538 //
\8d¡
\82Í
\82 \82è
\82¦
\82È
\82¢
540 Writeln('CGIStatus: 206');
542 Item.ResponseCode := 206;
543 DeleteStatusLine(Item);
547 Writeln('CGIStatus: 404(ERROR)');
549 Item.ResponseCode := 404;
550 Item.State := gdsError;
551 Item.ErrText := CgiStatus.FErrText;
554 if (Item.ResponseCode = 404) and (AnsiPos('
\89ß
\8b\8e\83\8d\83O
\91q
\8cÉ
\82Å
\94
\8c©', Item.ErrText) <> 0) then begin
556 Writeln('
\89ß
\8b\8e\83\8d\83O
\8eæ
\93¾');
558 ATitle := Item.ThreadItem.Title;
560 ATitle := '
\81i
\96¼
\8fÌ
\95s
\96¾
\81j';
561 FMsg := '
\81\9a\89ß
\8b\8e\83\8d\83O
\91q
\8cÉ
\82Å
\94
\8c© - [' + ATitle + ']';
563 if Assigned(OnDownloadMsg) then
564 Synchronize(FireDownloadMsg);
565 Idx := Pos(' ', Item.ErrText);
566 if Idx <> 0 then begin
567 URL := Copy(Item.ErrText, Idx + 1, Length(Item.ErrText));
568 if Pos( '://', URL ) = 0 then begin
569 if Pos('../', URL) = 1 then
570 URL := Copy(URL, 4, MaxInt );
571 if Pos( '/', URL ) = 1 then
572 URL := Copy( URL, 2, MaxInt );
573 URL := GikoSys.UrlToServer(Item.ThreadItem.ParentBoard.URL) + URL;
575 Modified := Item.ThreadItem.LastModified;
578 if not DatDownload(Item.DownType, URL, Modified, RangeStart, AdjustLen) then
579 Item.State := gdsError;
581 Writeln('ResponseCode: ' + IntToStr(Item.ResponseCode));
587 if (Item.DownType = gdtThread) and (Item.ResponseCode = 302) and (FSessionID = '') then begin
589 Writeln('
\83\8d\83O
\83C
\83\93\82³
\82ê
\82Ä
\82È
\82¢
\82Ì
\82Å
\89ß
\8b\8e\83\8d\83O
\8eæ
\93¾
\95s
\89Â');
591 ATitle := Item.ThreadItem.Title;
593 ATitle := '
\81i
\96¼
\8fÌ
\95s
\96¾
\81j';
594 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 + ']';
596 if Assigned(OnDownloadMsg) then
597 Synchronize(FireDownloadMsg);
601 case Item.ResponseCode of
602 200: Item.State := gdsComplete;
603 206: Item.State := gdsDiffComplete;
604 304: Item.State := gdsNotModify;
606 Item.State := gdsError;
609 Item.State := gdsError;
612 Item.State := gdsAbort;
614 if Assigned(OnDownloadEnd) then
615 Synchronize(FireDownloadEnd);
619 ClearHttpClient(FIndy);
621 if Terminated then Break;
626 function TDownloadThread.CgiDownload(ItemType: TGikoDownloadType; URL: string; Modified: TDateTime): Boolean;
628 ResponseCode: Integer;
629 ResStream: TMemoryStream;
632 FIndy.Request.ContentRangeStart := 0;
633 FIndy.Request.ContentRangeEnd := 0;
635 FIndy.Request.CustomHeaders.Clear;
636 if (Modified <> 0) and (Modified <> ZERO_DATE) then begin
637 FIndy.Request.LastModified := modified - OffsetFromUTC;
639 FIndy.Request.AcceptEncoding := '';
640 FIndy.Request.Accept := 'text/html';
641 ResStream := TMemoryStream.Create;
646 Writeln('URL: ' + URL);
648 FIndy.Get(URL, ResStream);
649 Item.Content := GikoSys.GzipDecompress(ResStream, FIndy.Response.ContentEncoding);
650 Item.LastModified := FIndy.Response.LastModified;
651 //
\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é
652 Item.ContentLength := Length(Item.Content);
653 //
\96³
\82¢
\82Æ
\8ev
\82¤
\82¯
\82Ç
\81B
\81B
\81B
654 if Item.Content = '' then
659 Writeln('
\8eæ
\93¾
\82Å
\97á
\8aO
\82È
\82µ');
661 ResponseCode := FIndy.ResponseCode;
663 on E: EIdSocketError do begin
665 Item.LastModified := ZERO_DATE;
666 Item.ContentLength := 0;
667 Item.ErrText := E.Message;
670 Screen.Cursor := crDefault;
672 on E: EIdConnectException do begin
674 Item.LastModified := ZERO_DATE;
675 Item.ContentLength := 0;
676 Item.ErrText := E.Message;
679 Screen.Cursor := crDefault;
681 on E: Exception do begin
683 Writeln('
\8eæ
\93¾
\82Å
\97á
\8aO
\82 \82è');
684 Writeln('E.Message: ' + E.Message);
687 Item.LastModified := ZERO_DATE;
688 Item.ContentLength := 0;
689 Item.ErrText := E.Message;
690 ResponseCode := FIndy.ResponseCode;
692 Screen.Cursor := crDefault;
696 if (Item.ContentLength = 0) and (ResponseCode = 206) then
697 Item.ResponseCode := 304
699 Item.ResponseCode := ResponseCode;
704 function TDownloadThread.DatDownload(ItemType: TGikoDownloadType; URL: string; Modified: TDateTime; RangeStart: Integer; AdjustLen: Integer): Boolean;
706 ResponseCode: Integer;
707 ResStream: TMemoryStream;
710 if (ItemType = gdtThread) and (RangeStart > 0) then begin
711 FIndy.Request.ContentRangeStart := RangeStart + AdjustLen;
712 FIndy.Request.ContentRangeEnd := 0;
714 FIndy.Request.ContentRangeStart := 0;
715 FIndy.Request.ContentRangeEnd := 0;
718 FIndy.Request.CustomHeaders.Clear;
719 FIndy.Request.CacheControl := 'no-cache';
720 FIndy.Request.CustomHeaders.Add('Pragma: no-cache');
721 if (Modified <> 0) and (Modified <> ZERO_DATE) then begin
722 FIndy.Request.LastModified := modified - OffsetFromUTC;
724 if RangeStart = 0 then
725 FIndy.Request.AcceptEncoding := 'gzip'
727 FIndy.Request.AcceptEncoding := '';
728 ResStream := TMemoryStream.Create;
733 Writeln('URL: ' + URL);
735 FIndy.Get(URL, ResStream);
736 Item.Content := GikoSys.GzipDecompress(ResStream, FIndy.Response.ContentEncoding);
737 Item.ContentLength := Length(Item.Content) + AdjustLen;
739 if GikoSys.Setting.ReplaceDat then begin
740 Item.Content := ReplaceDM.Replace(Item.Content);
742 Item.LastModified := FIndy.Response.LastModified;
743 if Item.Content = '' then
748 Writeln('
\8eæ
\93¾
\82Å
\97á
\8aO
\82È
\82µ');
750 ResponseCode := FIndy.ResponseCode;
752 on E: EIdSocketError do begin
754 Item.LastModified := ZERO_DATE;
755 Item.ContentLength := 0;
756 Item.ErrText := E.Message;
759 Screen.Cursor := crDefault;
761 on E: EIdConnectException do begin
763 Item.LastModified := ZERO_DATE;
764 Item.ContentLength := 0;
765 Item.ErrText := E.Message;
768 Screen.Cursor := crDefault;
770 on E: Exception do begin
772 Writeln('
\8eæ
\93¾
\82Å
\97á
\8aO
\82 \82è');
773 Writeln('E.Message: ' + E.Message);
776 Item.LastModified := ZERO_DATE;
777 Item.ContentLength := 0;
778 Item.ErrText := E.Message;
779 ResponseCode := FIndy.ResponseCode;
781 Screen.Cursor := crDefault;
785 if (Item.ContentLength = 0) and (ResponseCode = 206) then
786 Item.ResponseCode := 304
788 Item.ResponseCode := ResponseCode;
793 procedure TDownloadThread.FireDownloadEnd;
795 OnDownloadEnd(self, Item);
798 procedure TDownloadThread.FireDownloadMsg;
800 OnDownloadMsg(Self, Item, FMsg, FIcon);
803 procedure TDownloadThread.GetSessionID;
805 FSessionID := GikoSys.Dolib.SessionID;
808 procedure TDownloadThread.Abort;
811 FIndy.DisconnectSocket;
812 if socket <> nil then begin
813 socket.DisconnectSocket;
817 procedure TDownloadThread.WorkBegin(Sender: TObject; AWorkMode: TWorkMode; const AWorkCountMax: Integer);
819 if Assigned(OnWorkBegin) then
820 OnWorkBegin(Sender, AWorkMode, AWorkCountMax, FNumber, FDownloadTitle);
823 procedure TDownloadThread.WorkEnd(Sender: TObject; AWorkMode: TWorkMode);
825 if Assigned(OnWorkEnd) then
826 OnWorkEnd(Sender, AWorkMode, FNumber);
829 procedure TDownloadThread.Work(Sender: TObject; AWorkMode: TWorkMode; const AWorkCount: Integer);
831 if Assigned(OnWork) then
832 OnWork(Sender, AWorkMode, AWorkCount, FNumber);
835 function TDownloadThread.ParseCgiStatus(Content: string): TCgiStatus;
844 // [+OK]
\82Ì
\8fê
\8d\87\82Í
\8d·
\95ª
845 // [-INCR] (Incorrect)
\82Ì
\8fê
\8d\87\82Í
\82·
\82×
\82Ä
\82Ì
\83f
\81[
\83^
846 // [-ERR (
\83e
\83L
\83X
\83g)]
\82Ì
\8fê
\8d\87\82Í
\82È
\82ñ
\82©
\83G
\83\89\81[
847 //
\97á
\81F+OK 23094/512K
849 // -ERR
\82»
\82ñ
\82È
\94Â
\82È
\82¢
\82Å
\82·
850 Idx := AnsiPos(#10, Content);
851 StatusLine := Copy(Content, 0, Idx);
853 Idx := AnsiPos(' ', Content);
854 Status := Copy(StatusLine, 0, Idx - 1);
855 Line := Copy(StatusLine, Idx + 1, Length(StatusLine));
857 // Idx := AnsiPos('/', Line);
858 if Trim(Status) = '-ERR' then
861 Size := Copy(Line, 0, Idx - 1);
863 if Trim(Status) = '+OK' then
864 Result.FStatus := gcsOK
865 else if Trim(Status) = '-INCR' then
866 Result.FStatus := gcsINCR
867 else if Trim(Status) = '-ERR' then begin
868 Result.FStatus := gcsERR;
869 Result.FErrText := Msg;
876 Result.FStatus := gcsERR;
877 Result.FErrText := '
\83G
\83\89\81[
\82È
\82ñ
\82¾
\82¯
\82Ç
\81A
\82æ
\82
\95ª
\82©
\82ç
\82È
\82¢
\83G
\83\89\81[';
882 if GikoSys.IsNumeric(Size) then
883 Result.FSize := StrToInt(Size)
886 Result.FStatus := gcsERR;
887 Result.FErrText := '
\83X
\83e
\81[
\83^
\83X
\89ð
\90Í
\8e¸
\94s[' + StatusLine + ']';
891 //
\82P
\8ds
\96Ú
\82ð
\8fÁ
\82µ
\82Ä
\81A
\83R
\83\93\83e
\83\93\83c
\83T
\83C
\83Y
\82ð
\90Ý
\92è
\82·
\82é
892 procedure TDownloadThread.DeleteStatusLine(Item: TDownloadItem);
896 SList := TStringList.Create;
898 SList.Text := Item.Content;
899 //1
\8ds
\96Ú
\82ð
\8dí
\8f\9c
900 if SList.Count > 1 then
902 Item.Content := SList.Text;
903 //
\89ü
\8ds
\83R
\81[
\83h
\82ðCRLF -> LF
\82Æ
\8dl
\82¦
\82Ä
\81A
\8ds
\90\94\95ª
\82¾
\82¯
\83}
\83C
\83i
\83X
904 Item.ContentLength := Length(SList.Text) - SList.Count;
910 procedure TDownloadItem.SaveListFile;
914 NewItem: TThreadItem;
921 function MakeThreadCallBack(
922 inInstance : DWORD; // TBoardItem
\82Ì
\83C
\83\93\83X
\83^
\83\93\83X
923 inURL : PChar; //
\83X
\83\8c\83b
\83h
\82Ì URL
924 inTitle : PChar; //
\83X
\83\8c\83^
\83C
925 inCount : DWORD //
\83\8c\83X
\82Ì
\90\94
926 ) : Boolean; stdcall; //
\97ñ
\8b\93\82ð
\91±
\82¯
\82é
\82È
\82ç True
928 _ThreadItem : TThreadItem; // '_'
\82Í
\83N
\83\89\83X
\82Ì
\83v
\83\8d\83p
\83e
\83B
\82Æ
\82©
\82Ô
\82Á
\82Ä
\82é
\82Ì
\82Å
932 boardItem := TBoard( inInstance );
934 boardItem.IntData := boardItem.IntData + 1;
935 if boardItem.IntData < (boardItem.Count shr 2) then
936 index := boardItem.GetIndexFromURL( string( inURL ) )
938 index := boardItem.GetIndexFromURL( string( inURL ), True );
939 if index = -1 then begin
940 //
\90V
\82µ
\82¢
\83X
\83\8c\83b
\83h
941 _ThreadItem := TThreadItem.Create( boardItem.BoardPlugIn, boardItem, string( inURL ) );
943 _ThreadItem.Title := string( inTitle );
944 _ThreadItem.AllResCount := inCount;
945 _ThreadItem.ParentBoard := Board;
946 _ThreadItem.No := boardItem.IntData;
947 _ThreadItem.RoundDate := ZERO_DATE;
948 _ThreadItem.LastModified := ZERO_DATE;
949 _ThreadItem.AgeSage := gasNew;
950 boardItem.Add(_ThreadItem);
952 //
\8f\87\88Ê
\82ª
\8fã
\82ª
\82Á
\82Ä
\82¢
\82ê
\82ÎAge
\82É
\82·
\82é
953 if boardItem.Items[index].No > boardItem.IntData then
954 boardItem.Items[index].AgeSage := gasAge
955 //
\8f\87\88Ê
\82ª
\8fã
\82ª
\82Á
\82Ä
\82È
\82¢
\82¯
\82Ç
\81A
\83\8c\83X
\82ª
\82Â
\82¢
\82Ä
\82½
\82ç
\81ASage
\82É
956 else if boardItem.Items[index].AllResCount <> inCount then
957 boardItem.Items[index].AgeSage := gasSage
958 //
\8f\87\88Ê
\8fã
\82ª
\82Á
\82Ä
\82È
\82¢
\82µ
\81A
\83\8c\83X
\82Ì
\91\9d\8c¸
\82à
\96³
\82¯
\82ê
\82Î
\81ANone
960 boardItem.Items[index].AgeSage := gasNone;
962 boardItem.Items[index].No := boardItem.IntData;
963 boardItem.Items[index].AllResCount := inCount;
972 //Board.ListData := TList.Create;
973 Body := TStringList.Create;
975 //
\83_
\83E
\83\93\83\8d\81[
\83h
\93ú
\8e\9e\90Ý
\92è
\81i
\83\8d\81[
\83J
\83\8b\93ú
\8e\9e\81j
976 Board.RoundDate := Now;
977 //
\83T
\81[
\83o
\8fã
\83t
\83@
\83C
\83\8b\82Ì
\8dX
\90V
\8e\9e\8d\8f\90Ý
\92è
978 Board.LastModified := LastModified;
981 //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é
982 if GikoSys.Setting.DatOchiSortIndex >= 0 then begin
983 Sort.SetSortNoFlag(true);
984 Sort.SetSortOrder(GikoSys.Setting.DatOchiSortOrder);
985 Sort.SetSortIndex(GikoSys.Setting.DatOchiSortIndex);
986 //Sort.SortNonAcquiredCountFlag := GikoSys.Setting.NonAcquiredCount;
987 Board.CustomSort(ThreadItemSortProc);
991 rt := GetTickCount - st;
992 Writeln('END Sortd' + IntToStr(rt) + ' ms');
995 for i := Board.Count - 1 downto 0 do
996 Board.Items[i].AgeSage := gasNull;
998 if Board.IsBoardPlugInAvailable then begin
999 //
\90V
\82µ
\82¢
\83\8a\83X
\83g
\82ð
\8dì
\90¬
\82·
\82é
1000 //
\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Á
1001 //
\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¬
1004 rt := GetTickCount - st;
1005 Writeln('Start Enum' + IntToStr(rt) + ' ms');
1008 //
\82±
\82ê
\82ª
\92x
\82¢
\81@
\97v
\89ü
\91P
1010 Board.BoardPlugIn.EnumThread( DWORD( Board ), @MakeThreadCallBack );
1014 rt := GetTickCount - st;
1015 Writeln('End Enum' + IntToStr(rt) + ' ms');
1018 //
\8cÃ
\82¢
\83\8a\83X
\83g
\82É
\82µ
\82©
\82È
\82¢
\82â
\82Â
\82ç
\82ð
\8dí
\8f\9c
1019 for i := Board.Count - 1 downto 0 do begin
1020 if( Board.Items[i].AgeSage = gasNull )and not (Board.Items[i].IsLogFile) then
1024 //
\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Á
1025 for i := 0 to Board.Count - 1 do begin
1026 if(Board.Items[i].AgeSage = gasNull) and (Board.Items[i].IsLogFile) then begin
1027 Board.IntData := Board.IntData + 1;
1028 Board.Items[i].No := Board.IntData;
1029 Board.Items[i].AllResCount := Board.Items[i].Count;
1030 Board.Items[i].NewResCount := 0;
1031 Board.Items[i].AgeSage := gasArch;
1036 //
\90V
\82µ
\82¢
\83\8a\83X
\83g
\82ð
\8dì
\90¬
\82·
\82é
1037 //
\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Á
1038 //
\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¬
1039 Body.Text := Content;
1041 for i := 0 to Body.Count - 1 do begin
1042 Rec := GikoSys.DivideSubject(Body[i]);
1043 Rec.FFileName := Trim(Rec.FFileName);
1044 if (Rec.FTitle = '') and (Rec.FCount = 0) then Continue;
1046 index := Board.GetIndexFromFileName(Rec.FFileName);
1047 if index = -1 then begin
1048 //
\90V
\82µ
\82¢
\83X
\83\8c\83b
\83h
1049 NewItem := TThreadItem.Create(
1052 GikoSys.Get2chBoard2ThreadURL( Board, ChangeFileExt( Rec.FFileName, '' ) ) );
1053 NewItem.Title := Rec.FTitle;
1054 NewItem.AllResCount := Rec.FCount;
1055 NewItem.ParentBoard := Board;
1056 NewItem.No := NumCount;
1057 NewItem.RoundDate := ZERO_DATE;
1058 NewItem.LastModified := ZERO_DATE;
1059 NewItem.AgeSage := gasNew;
1062 if Board.Items[index].No > NumCount then
1063 Board.Items[index].AgeSage := gasAge
1064 else if Board.Items[index].AllResCount < Rec.FCount then
1065 Board.Items[index].AgeSage := gasSage
1067 Board.Items[index].AgeSage := gasNone;
1069 Board.Items[index].No := NumCount;
1070 Board.Items[index].AllResCount := Rec.FCount;
1073 //
\8cÃ
\82¢
\83\8a\83X
\83g
\82Ì
\8dí
\8f\9c
1074 for i := Board.Count - 1 downto 0 do begin
1075 if( Board.Items[i].AgeSage = gasNull )and not (Board.Items[i].IsLogFile) then
1079 //
\90V
\82µ
\82¢
\83\8a\83X
\83g
\82É
\96³
\82©
\82Á
\82½
\83A
\83C
\83e
\83\80\82Ì
\8dX
\90V
1080 for i := 0 to Board.Count - 1 do begin
1081 if( Board.Items[i].AgeSage = gasNull )and (Board.Items[i].IsLogFile) then begin
1083 Board.Items[i].No := NumCount;
1084 Board.Items[i].AllResCount := Board.Items[i].Count;
1085 Board.Items[i].NewResCount := 0;
1086 Board.Items[i].AgeSage := gasArch;
1089 //
\83\8a\83X
\83g(subject.txt)
\82ð
\95Û
\91¶
1090 GikoSys.ForceDirectoriesEx(ExtractFilePath(Board.GetSubjectFileName));
1091 Body.Text := MojuUtils.Sanitize(Body.Text);
1092 Body.SaveToFile(Board.GetSubjectFileName);
1101 {procedure TDownloadItem.SaveListFile;
1105 NewItem: TThreadItem;
1107 // SaveCount: Integer;
1112 NewList := TList.Create;
1113 Body := TStringList.Create;
1115 //
\8f\84\89ñ
\93ú
\8e\9e\90Ý
\92è
1116 Board.RoundDate := Now;
1117 //
\83T
\81[
\83o
\8fã
\83t
\83@
\83C
\83\8b\82Ì
\8dX
\90V
\8e\9e\8d\8f\90Ý
\92è
1118 Board.LastModified := LastModified;
1120 //
\83\8a\83X
\83g
\95Û
\91¶
\8c\8f\90\94\8eæ
\93¾
1121 //SaveCount := MaxInt;
1123 //
\8cÃ
\82¢
\83\8a\83X
\83g
\82©
\82ç
\83\8d\83O
\96³
\82µ
\83A
\83C
\83e
\83\80\82ð
\8dí
\8f\9c
1124 for i := Board.Count - 1 downto 0 do
1125 if not Board.Items[i].IsLogFile then
1128 //
\90V
\82µ
\82¢
\83\8a\83X
\83g
\82ð
\8dì
\90¬
\82·
\82é
1129 //
\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Á
1130 //
\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¬
1131 Body.Text := Content;
1132 // Loop := Min(Body.Count, SaveCount);
1134 // for i := 0 to Loop - 1 do begin
1135 for i := 0 to Body.Count - 1 do begin
1136 if i = 0 then Continue; //
\82P
\8ds
\96Ú
\82Í
\83X
\83e
\81[
\83^
\83X
\8ds
\82Ì
\82½
\82ß
\8f\88\97\9d\82È
\82µ
1138 Rec := GikoSys.DivideSubject(Body[i]);
1139 if (Rec.FTitle = '') and (Rec.FCount = 0) then Continue;
1141 index := Board.GetIndex(Rec.FFileName);
1142 if index = -1 then begin
1143 NewItem := TThreadItem.Create;
1144 NewItem.FileName := Rec.FFileName;
1145 NewItem.Title := Rec.FTitle;
1146 NewItem.Count := Rec.FCount;
1147 NewItem.ParentBoard := Board;
1148 NewItem.No := NumCount;
1149 NewItem.RoundDate := ZERO_DATE;
1150 NewItem.LastModified := ZERO_DATE;
1151 NewList.Add(NewItem);
1153 //Board.Items[index].Count := Count;
1154 Board.Items[index].No := NumCount;
1155 NewList.Add(Board.Items[index]);
1156 Board.DeleteList(index);
1160 //
\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Á
1161 for i := 0 to Board.Count - 1 do begin
1163 Board.Items[i].No := NumCount;
1164 NewList.Add(Board.Items[i]);
1167 //
\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
1168 for i := Board.Count - 1 downto 0 do
1169 Board.DeleteList(i);
1171 //
\90V
\82µ
\82¢
\83\8a\83X
\83g
\82ð
\83{
\81[
\83h
\83I
\83u
\83W
\83F
\83N
\83g
\82É
\92Ç
\89Á
1172 for i := 0 to NewList.Count - 1 do
1173 Board.Add(TThreadItem(NewList[i]));
1175 //
\83\8a\83X
\83g(subject.txt)
\82ð
\95Û
\91¶
1176 // GikoSys.ForceDirectoriesEx(GikoSys.GetLogDir + Board.BBSID);
1177 // Body.SaveToFile(GikoSys.GetSubjectFileName(Board.BBSID));
1178 GikoSys.ForceDirectoriesEx(ExtractFilePath(Board.GetSubjectFileName));
1179 Body.SaveToFile(Board.GetSubjectFileName);
1186 procedure TDownloadItem.SaveItemFile;
1188 Body, oldBody: TStringList;
1199 FileName := ThreadItem.GetThreadFileName;
1201 //if not ThreadItem.IsBoardPlugInAvailable then begin
1202 if not ThreadItem.ParentBoard.IsBoardPlugInAvailable then begin
1203 if Trim(Content) = '' then
1206 GikoSys.ForceDirectoriesEx(ExtractFilePath(FileName));
1209 Body := TStringList.Create;
1213 // if FileExists(FileName) and (ResponseCode = 206) then begin
1214 if FileExists(FileName) and (State = gdsDiffComplete) then begin
1219 Body.LoadFromFile(FileName);
1220 OldCnt := Body.Count;
1221 Body.Text := Body.Text + Content;
1222 Body.SaveToFile(FileName);
1223 NewRes := Body.Count - OldCnt;
1225 on E:EFOpenError do begin
1233 //Cnt := Body.Count;
1235 if IsAbone then begin
1236 //
\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µ
1237 oldBody := TStringList.Create;
1243 oldBody.LoadFromFile(FileName);
1245 on E:EFOpenError do begin
1256 Body.Text := Content;
1257 if (ThreadItem.Kokomade > 0) and (ThreadItem.Kokomade <= oldBody.Count) then begin
1258 ThreadItem.Kokomade := Body.IndexOf(oldBody.Strings[ ThreadItem.Kokomade - 1 ]);
1259 if ThreadItem.Kokomade <> -1 then ThreadItem.Kokomade := ThreadItem.Kokomade + 1;
1262 LastIdx := oldBody.Count;
1265 OldCnt := Body.IndexOf(oldBody.Strings[ LastIdx ]) + 1;
1266 until ( OldCnt <> 0 ) or (LastIdx = 0);
1268 if OldCnt >= Body.Count then OldCnt := Body.Count - 1;
1269 NewRes := Body.Count - OldCnt;
1271 //
\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)
1272 if ThreadItem.Kokomade > OldCnt then begin
1274 ThreadItem.Kokomade := OldCnt
1276 ThreadItem.Kokomade := 1;
1284 Body.Text := Content;
1285 //ThreadItem.Count := 0;
1287 NewRes := Body.Count;
1288 //Cnt := Body.Count;
1290 // if Body.Count > 0 then
1292 Body.SaveToFile(FileName);
1294 if ThreadItem.Title = '' then begin
1295 THTMLCreate.DivideStrLine(Body[0], @Res);
1296 ThreadItem.Title := Res.FTitle;
1298 ThreadItem.Size := 0;
1305 ThreadItem.Size := ThreadItem.Size + ContentLength;
1306 ThreadItem.LastModified := LastModified;
1307 ThreadItem.Count := Cnt;
1308 //ThreadItem.AllResCount := Cnt;
1309 ThreadItem.NewResCount := NewRes;
1310 ThreadItem.NewReceive := OldCnt + 1;
1312 ThreadItem.AllResCount := ThreadItem.Count;
1313 ThreadItem.IsLogFile := True;
1314 ThreadItem.RoundDate := Now;
1315 if not ThreadItem.UnRead then begin
1316 ThreadItem.UnRead := True;
1318 // if ThreadItem.RoundNo = 6 then
1319 // ThreadItem.RoundNo := 0;
1321 //
\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
1322 //
\90³
\8fí
\8fI
\97¹
\8e\9e\82É
\82Í
\8dí
\8f\9c
1323 //
\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
1324 ini := TMemIniFile.Create(ChangeFileExt(FileName, '.tmp'));
1326 ini.WriteDateTime('Setting', 'RoundDate', ThreadItem.RoundDate);
1327 ini.WriteDateTime('Setting', 'LastModified', ThreadItem.LastModified);
1328 ini.WriteInteger('Setting', 'Size', ThreadItem.Size);
1329 ini.WriteInteger('Setting', 'Count', ThreadItem.Count);
1330 ini.WriteInteger('Setting', 'AllResCount', ThreadItem.AllResCount);
1331 ini.WriteInteger('Setting', 'NewResCount', ThreadItem.NewResCount);
1332 ini.WriteInteger('Setting', 'NewReceive', ThreadItem.NewReceive);
1333 // ini.WriteInteger('Setting', 'RoundNo', ThreadItem.RoundNo);
1334 // ini.WriteBool('Setting', 'Round', ThreadItem.Round);
1335 ini.WriteBool('Setting', 'UnRead', ThreadItem.UnRead);