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;
106 constructor TDownloadThread.Create(CreateSuspended: Boolean);
108 inherited Create(CreateSuspended);
109 FIndy := TIdHttp.Create(nil);
111 FIndy.OnWorkBegin := WorkBegin;
112 FIndy.OnWorkEnd := WorkEnd;
113 FIndy.OnWork := Work;
116 destructor TDownloadThread.Destroy;
118 FIndy.Request.CustomHeaders.Clear;
119 FIndy.Request.RawHeaders.Clear;
121 FIndy.Response.CustomHeaders.Clear;
122 FIndy.Response.RawHeaders.Clear;
123 FIndy.Response.Clear;
124 FIndy.ProxyParams.Clear;
129 function RFC1123_Date(aDate : TDateTime) : String;
131 StrWeekDay : String = 'MonTueWedThuFriSatSun';
132 StrMonth : String = 'JanFebMarAprMayJunJulAugSepOctNovDec';
134 Year, Month, Day : Word;
135 Hour, Min, Sec, MSec : Word;
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]);
147 procedure TDownloadThread.Execute;
149 ResStream: TMemoryStream;
152 CgiStatus: TCgiStatus;
158 DownloadResult: Boolean;
160 boardPlugIn : TBoardPlugIn;
161 listContent : string;
162 lastContent : string;
163 logFile : TFileStream;
164 adjustMargin : Integer;
168 while not Terminated do begin
169 //=====
\83v
\83\89\83O
\83C
\83\93
172 ExternalBoardManager.OnWork := Work;
173 ExternalBoardManager.OnWorkBegin := WorkBegin;
174 ExternalBoardManager.OnWorkEnd := WorkEnd;
176 FDownloadTitle := '';
177 case FItem.FDownType of
180 FDownloadTitle := FItem.FBoard.Title;
181 if FItem.FBoard <> nil then begin
182 if FItem.FBoard.IsBoardPlugInAvailable then begin
183 boardPlugIn := FItem.FBoard.BoardPlugIn;
184 Item.State := TGikoDownloadState( boardPlugIn.DownloadBoard( DWORD( FItem.FBoard ) ) );
190 FDownloadTitle := FItem.FThreadItem.Title;
191 if FItem.FThreadItem <> nil then begin
192 if FItem.FThreadItem.IsBoardPlugInAvailable then begin
193 boardPlugIn := FItem.FThreadItem.BoardPlugIn;
194 Item.State := TGikoDownloadState( boardPlugIn.DownloadThread( DWORD( FItem.FThreadItem ) ) );
199 if Length(FDownloadTitle) = 0 then
200 FDownloadTitle := '
\81i
\96¼
\8fÌ
\95s
\96¾
\81j';
202 if boardPlugIn <> nil then begin
204 Item.State := gdsAbort;
206 if Assigned( OnDownloadEnd ) then
207 Synchronize( FireDownloadEnd );
215 //=====
\83v
\83\89\83O
\83C
\83\93\82ð
\8eg
\97p
\82µ
\82È
\82¢
\8fê
\8d\87
217 FIndy.Request.CustomHeaders.Clear;
218 FIndy.Response.Clear;
220 FIndy.ProxyParams.Clear;
222 FIndy.Request.UserAgent := GikoSys.GetUserAgent;
223 FIndy.RecvBufferSize := Gikosys.Setting.RecvBufferSize;
224 FIndy.ProxyParams.BasicAuthentication := False;
226 Writeln('------------------------------------------------------------');
228 //FIndy.AllowCookies := False;
229 if GikoSys.Setting.ReadProxy then begin
230 if GikoSys.Setting.ProxyProtocol then
231 FIndy.ProtocolVersion := pv1_1
233 FIndy.ProtocolVersion := pv1_0;
234 FIndy.ProxyParams.ProxyServer := GikoSys.Setting.ReadProxyAddress;
235 FIndy.ProxyParams.ProxyPort := GikoSys.Setting.ReadProxyPort;
236 FIndy.ProxyParams.ProxyUsername := GikoSys.Setting.ReadProxyUserID;
237 FIndy.ProxyParams.ProxyPassword := GikoSys.Setting.ReadProxyPassword;
238 if GikoSys.Setting.ReadProxyUserID <> '' then
239 FIndy.ProxyParams.BasicAuthentication := True;
241 Writeln('
\83v
\83\8d\83L
\83V
\90Ý
\92è
\82 \82è');
242 Writeln('
\83z
\83X
\83g: ' + GikoSys.Setting.ReadProxyAddress);
243 Writeln('
\83|
\81[
\83g: ' + IntToStr(GikoSys.Setting.ReadProxyPort));
246 if GikoSys.Setting.Protocol then
247 FIndy.ProtocolVersion := pv1_1
249 FIndy.ProtocolVersion := pv1_0;
250 FIndy.ProxyParams.ProxyServer := '';
251 FIndy.ProxyParams.ProxyPort := 80;
252 FIndy.ProxyParams.ProxyUsername := '';
253 FIndy.ProxyParams.ProxyPassword := '';
255 Writeln('
\83v
\83\8d\83L
\83V
\90Ý
\92è
\82È
\82µ');
260 if Item.DownType = gdtThread then begin
261 if FileExists( Item.ThreadItem.GetThreadFileName ) then begin
262 // dat
\83t
\83@
\83C
\83\8b\82Ì
\8dÅ
\8cã
\82ð
\93Ç
\82Ý
\8fo
\82·
263 SetLength( lastContent, ADJUST_MARGIN + 1 );
264 logFile := TFileStream.Create( Item.ThreadItem.GetThreadFileName, fmOpenRead or fmShareDenyWrite );
266 logFile.Seek( -(ADJUST_MARGIN + 1), soFromEnd );
267 logFile.Read( lastContent[ 1 ], ADJUST_MARGIN + 1 );
268 lastContent := StringReplace( lastContent, #13, '', [] ); // CR
\82Ì
\8dí
\8f\9c
275 adjustMargin := Length( lastContent );
278 FIndy.Request.ContentRangeStart := 0;
279 FIndy.Request.LastModified := ZERO_DATE;
280 ResStream := TMemoryStream.Create;
283 //********************
284 //DAT or Subject
\8eæ
\93¾
285 //********************
286 Item.ResponseCode := 0;
290 if Item.DownType = gdtBoard then begin
292 Writeln('Subject
\8eæ
\93¾');
293 Writeln('URL: ' + Item.Board.GetReadCgiURL);
294 Writeln('Modified: ' + FloatToStr(Item.Board.LastModified));
296 URL := Item.Board.GetReadCgiURL;
297 if Item.ForceDownload then begin
299 ATitle := Item.Board.Title;
301 ATitle := '
\81i
\96¼
\8fÌ
\95s
\96¾
\81j';
302 FMsg := '
\81\9a\8b
\90§
\8eæ
\93¾
\82ð
\8ds
\82¢
\82Ü
\82· - [' + ATitle + ']';
304 if Assigned(OnDownloadMsg) then
305 Synchronize(FireDownloadMsg);
306 Modified := ZERO_DATE
308 Modified := Item.Board.LastModified;
310 end else if Item.DownType = gdtThread then begin
312 Writeln('DAT
\8eæ
\93¾');
313 Writeln('URL: ' + Item.ThreadItem.GetDatURL);
314 Writeln('Modified: ' + FloatToStr(Item.ThreadItem.LastModified));
316 URL := Item.ThreadItem.GetDatURL;
317 if Item.ForceDownload then begin
319 ATitle := Item.ThreadItem.Title;
321 ATitle := '
\81i
\96¼
\8fÌ
\95s
\96¾
\81j';
322 FMsg := '
\81\9a\8b
\90§
\8eæ
\93¾
\82ð
\8ds
\82¢
\82Ü
\82· - [' + ATitle + ']';
324 if FileExists(ChangeFileExt(Item.FThreadItem.GetThreadFileName,'.NG')) = true then
325 DeleteFile(ChangeFileExt(Item.FThreadItem.GetThreadFileName,'.NG'));
326 if Assigned(OnDownloadMsg) then
327 Synchronize(FireDownloadMsg);
328 Modified := ZERO_DATE;
332 Modified := Item.ThreadItem.LastModified;
333 if Item.ThreadItem.Size > 0 then begin
335 Writeln('RangeStart: ' + IntToStr(Item.ThreadItem.Size));
337 //
\82 \82Ú
\81[
\82ñ
\83`
\83F
\83b
\83N
\82Ì
\82½
\82ß adjustMargin
\83o
\83C
\83g
\91O
\82©
\82ç
\8eæ
\93¾
338 RangeStart := Item.ThreadItem.Size;
339 AdjustLen := -adjustMargin;
343 Item.IsAbone := False;
344 DownloadResult := DatDownload(Item.DownType, URL, Modified, RangeStart, AdjustLen);
346 Writeln('ResponseCode: ' + IntToStr(FIndy.ResponseCode));
348 if Item.DownType = gdtThread then begin
349 if Item.ResponseCode = 416 then begin
350 Item.IsAbone := True;
351 DownloadResult := True;
352 end else if DownloadResult and (AdjustLen < 0) then begin
353 if Copy( Item.Content, 1, adjustMargin ) <> lastContent then
354 Item.IsAbone := True;
358 if Trim(FIndy.Response.RawHeaders.Values['Date']) <> '' then begin
359 if Item.DownType = gdtBoard then
360 Item.Board.LastGetTime := MonaUtils.DateStrToDateTime(FIndy.Response.RawHeaders.Values['Date'])
362 Item.ThreadItem.ParentBoard.LastGetTime := MonaUtils.DateStrToDateTime(FIndy.Response.RawHeaders.Values['Date']);
365 if DownloadResult then begin
367 Writeln('Date:' + FIndy.Response.RawHeaders.Values['Date']);
369 if Item.IsAbone then begin
371 Writeln('
\82 \82Ú
\81[
\82ñ
\8c\9f\8fo');
373 ATitle := Item.ThreadItem.Title;
375 ATitle := '
\81i
\96¼
\8fÌ
\95s
\96¾
\81j';
376 //
\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¾
379 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 + ']';
381 if FileExists(ChangeFileExt(Item.FThreadItem.GetThreadFileName,'.NG')) = true then
382 DeleteFile(ChangeFileExt(Item.FThreadItem.GetThreadFileName,'.NG'));
383 if Assigned(OnDownloadMsg) then
384 Synchronize(FireDownloadMsg);
385 if not DatDownload(Item.DownType, URL, ZERO_DATE, RangeStart, AdjustLen) then
386 Item.State := gdsError;
388 Writeln('
\82 \82Ú
\81[
\82ñ
\8dÄ
\8eæ
\93¾
\8cã');
389 Writeln('ResponseCode: ' + IntToStr(Item.ResponseCode));
391 end else if (Item.DownType = gdtThread) and (AdjustLen < 0) then begin
392 //
\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
393 Item.Content := Copy(Item.Content, adjustMargin + 1, MaxInt);
396 Item.State := gdsError;
397 if (Item.DownType = gdtBoard) and (Item.ResponseCode = 302) then begin
398 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';
400 if Assigned(OnDownloadMsg) then
401 Synchronize(FireDownloadMsg);
405 //********************
407 //********************
408 if (Item.DownType = gdtThread) and (Item.ResponseCode = 302) then begin
410 Writeln('dat.gz
\8eæ
\93¾');
412 ATitle := Item.ThreadItem.Title;
414 ATitle := '
\81i
\96¼
\8fÌ
\95s
\96¾
\81j';
415 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 + ']';
417 if Assigned(OnDownloadMsg) then
418 Synchronize(FireDownloadMsg);
419 URL := Item.ThreadItem.GetDatgzURL;
420 Modified := Item.ThreadItem.LastModified;
423 if not DatDownload(Item.DownType, URL, Modified, RangeStart, AdjustLen) then
424 Item.State := gdsError;
426 Writeln('ResponseCode: ' + IntToStr(Item.ResponseCode));
430 //********************
432 //********************
434 if (Item.DownType = gdtThread) and (Item.ResponseCode = 302) then begin
435 ATitle := Item.ThreadItem.Title;
437 ATitle := '
\81i
\96¼
\8fÌ
\95s
\96¾
\81j';
438 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 + ']';
440 if Assigned(OnDownloadMsg) then
441 Synchronize(FireDownloadMsg);
442 URL := Item.ThreadItem.GetOldDatgzURL;
443 Modified := Item.ThreadItem.LastModified;
446 if not DatDownload(Item.DownType, URL, Modified, RangeStart, AdjustLen) then
447 Item.State := gdsError;
451 //********************
452 //offlaw.cgi
\82Å
\8eæ
\93¾
453 //********************
455 Synchronize(GetSessionID);
456 if (Item.DownType = gdtThread) and (Item.ResponseCode = 302) and (FSessionID <> '') then begin
458 Writeln('offlaw.cgi
\82Å
\8eæ
\93¾');
460 ATitle := Item.ThreadItem.Title;
462 ATitle := '
\81i
\96¼
\8fÌ
\95s
\96¾
\81j';
463 FMsg := '
\81\9adat.gz
\82ª
\91¶
\8dÝ
\82µ
\82È
\82¢
\82½
\82ßofflaw.cgi
\82ð
\97\98\97p
\82µ
\82Ü
\82· - [' + ATitle + ']';
465 if Assigned(OnDownloadMsg) then
466 Synchronize(FireDownloadMsg);
467 URL := Item.ThreadItem.GetOfflawCgiURL(FSessionID);
468 Modified := Item.ThreadItem.LastModified;
471 if not DatDownload(Item.DownType, URL, Modified, RangeStart, AdjustLen) then begin
473 Writeln('ResponseCode: ' + IntToStr(Item.ResponseCode));
475 Item.State := gdsError;
477 if (Item.DownType = gdtThread) and (Item.ResponseCode = 302) then begin
478 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';
480 if Assigned(OnDownloadMsg) then
481 Synchronize(FireDownloadMsg);
485 CgiStatus := ParseCgiStatus(Item.Content);
487 Writeln('ResponseCode: ' + IntToStr(Item.ResponseCode));
489 case CgiStatus.FStatus of
492 Writeln('CGIStatus: OK');
494 Item.ResponseCode := 200;
495 Item.Content := DeleteStatusLine(Item.Content);
496 Item.ContentLength := CgiStatus.FSize;
499 //
\8d¡
\82Í
\82 \82è
\82¦
\82È
\82¢
501 Writeln('CGIStatus: 206');
503 Item.ResponseCode := 206;
504 Item.Content := DeleteStatusLine(Item.Content);
505 Item.ContentLength := CgiStatus.FSize;
509 Writeln('CGIStatus: 404(ERROR)');
511 Item.ResponseCode := 404;
512 Item.State := gdsError;
513 Item.ErrText := CgiStatus.FErrText;
516 if (Item.ResponseCode = 404) and (AnsiPos('
\89ß
\8b\8e\83\8d\83O
\91q
\8cÉ
\82Å
\94
\8c©', Item.ErrText) <> 0) then begin
518 Writeln('
\89ß
\8b\8e\83\8d\83O
\8eæ
\93¾');
520 ATitle := Item.ThreadItem.Title;
522 ATitle := '
\81i
\96¼
\8fÌ
\95s
\96¾
\81j';
523 FMsg := '
\81\9a\89ß
\8b\8e\83\8d\83O
\91q
\8cÉ
\82Å
\94
\8c© - [' + ATitle + ']';
525 if Assigned(OnDownloadMsg) then
526 Synchronize(FireDownloadMsg);
527 Idx := Pos(' ', Item.ErrText);
528 if Idx <> 0 then begin
529 URL := Copy(Item.ErrText, Idx + 1, Length(Item.ErrText));
530 if Pos( '://', URL ) = 0 then begin
531 if Pos('../', URL) = 1 then
532 URL := Copy(URL, 4, MaxInt );
533 if Pos( '/', URL ) = 1 then
534 URL := Copy( URL, 2, MaxInt );
535 URL := GikoSys.UrlToServer(Item.ThreadItem.ParentBoard.URL) + URL;
537 Modified := Item.ThreadItem.LastModified;
540 if not DatDownload(Item.DownType, URL, Modified, RangeStart, AdjustLen) then
541 Item.State := gdsError;
543 Writeln('ResponseCode: ' + IntToStr(Item.ResponseCode));
549 if (Item.DownType = gdtThread) and (Item.ResponseCode = 302) and (FSessionID = '') then begin
551 Writeln('
\83\8d\83O
\83C
\83\93\82³
\82ê
\82Ä
\82È
\82¢
\82Ì
\82Å
\89ß
\8b\8e\83\8d\83O
\8eæ
\93¾
\95s
\89Â');
553 ATitle := Item.ThreadItem.Title;
555 ATitle := '
\81i
\96¼
\8fÌ
\95s
\96¾
\81j';
556 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 + ']';
558 if Assigned(OnDownloadMsg) then
559 Synchronize(FireDownloadMsg);
563 case Item.ResponseCode of
564 200: Item.State := gdsComplete;
565 206: Item.State := gdsDiffComplete;
566 304: Item.State := gdsNotModify;
568 Item.State := gdsError;
571 //
\96³
\82¢
\82Æ
\8ev
\82¤
\82¯
\82Ç
\81B
\81B
\81B
572 if (Item.ResponseCode in [200, 206]) and (Item.Content = '') then
573 Item.State := gdsError;
574 Item.LastModified := FIndy.Response.LastModified;
575 //
\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é
576 Item.ContentLength := FIndy.Response.ContentLength + AdjustLen;
579 FIndy.Get(URL, ResStream);
580 Item.Content := GikoSys.GzipDecompress(ResStream, FIndy.Response.ContentEncoding);
581 if (Item.DownType = gdtThread) and (AdjustLen = -1) and (Item.Content[1] <> #10) then begin
582 //
\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¾
583 //
\82±
\82±
\82Å
\83\81\83b
\83Z
\81[
\83W
\95\
\8e¦
\83C
\83x
\83\93\83g
585 FMsg := '
\81u
\82 \82Ú
\81[
\82ñ
\81v
\82ð
\8c\9f\8fo
\82µ
\82½
\82Ì
\82Å
\8dÄ
\8eæ
\93¾
\82ð
\8ds
\82¢
\82Ü
\82·';
586 if Assigned(OnDownloadMsg) then
587 Synchronize(FireDownloadMsg);
588 FIndy.Request.ContentRangeStart := 0;
589 FIndy.Request.ContentRangeEnd := 0;
592 FIndy.Get(URL, ResStream);
593 Item.Content := GikoSys.GzipDecompress(ResStream, FIndy.Response.ContentEncoding);
594 end else if (Item.DownType = gdtThread) and (AdjustLen = -1) and (Item.Content[1] = #10) then begin
595 //
\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
596 Item.Content := Copy(Item.Content, 2, Length(Item.Content));
599 Item.State := gdsError;
601 Item.ResponseCode := FIndy.ResponseCode;
606 FIndy.Get(URL, ResStream);
607 Item.Content := GikoSys.GzipDecompress(ResStream, FIndy.Response.ContentEncoding);
609 Item.State := gdsError;
612 CgiStatus := ParseCgiStatus(Item.Content);
613 if CgiStatus.FStatus = gcsOK then begin
614 if CgiStatus.FSize = 0 then
615 Item.State := gdsNotModify
616 else if Item.DownType = gdtBoard then
617 Item.State := gdsComplete
619 Item.State := gdsDiffComplete;
620 end else if CgiStatus.FStatus = gcsINCR then begin
621 Item.State := gdsComplete;
622 end else if CgiStatus.FStatus = gcsERR then begin
623 Item.State := gdsError;
624 Item.ErrText := CgiStatus.FErrText;
626 Item.ContentLength := CgiStatus.FSize;
629 Item.State := gdsError;
631 //Item.ResponseCode := FIndy.ResponseCode;
633 Item.State := gdsAbort;
635 if Assigned(OnDownloadEnd) then
636 Synchronize(FireDownloadEnd);
640 FIndy.Request.CustomHeaders.Clear;
641 FIndy.Request.RawHeaders.Clear;
643 FIndy.Response.CustomHeaders.Clear;
644 FIndy.Response.RawHeaders.Clear;
645 FIndy.Response.Clear;
646 FIndy.ProxyParams.Clear;
648 if Terminated then Break;
653 function TDownloadThread.CgiDownload(ItemType: TGikoDownloadType; URL: string; Modified: TDateTime): Boolean;
655 ResponseCode: Integer;
656 ResStream: TMemoryStream;
659 FIndy.Request.ContentRangeStart := 0;
660 FIndy.Request.ContentRangeEnd := 0;
662 FIndy.Request.CustomHeaders.Clear;
663 if (Modified <> 0) and (Modified <> ZERO_DATE) then begin
664 FIndy.Request.LastModified := modified - OffsetFromUTC;
666 FIndy.Request.AcceptEncoding := '';
667 FIndy.Request.Accept := 'text/html';
668 ResStream := TMemoryStream.Create;
673 Writeln('URL: ' + URL);
675 FIndy.Get(URL, ResStream);
676 Item.Content := GikoSys.GzipDecompress(ResStream, FIndy.Response.ContentEncoding);
677 Item.LastModified := FIndy.Response.LastModified;
678 //
\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é
679 Item.ContentLength := Length(Item.Content);
680 //
\96³
\82¢
\82Æ
\8ev
\82¤
\82¯
\82Ç
\81B
\81B
\81B
681 if Item.Content = '' then
686 Writeln('
\8eæ
\93¾
\82Å
\97á
\8aO
\82È
\82µ');
688 ResponseCode := FIndy.ResponseCode;
690 on E: EIdSocketError do begin
692 Item.LastModified := ZERO_DATE;
693 Item.ContentLength := 0;
694 Item.ErrText := E.Message;
697 Screen.Cursor := crDefault;
699 on E: EIdConnectException do begin
701 Item.LastModified := ZERO_DATE;
702 Item.ContentLength := 0;
703 Item.ErrText := E.Message;
706 Screen.Cursor := crDefault;
708 on E: Exception do begin
710 Writeln('
\8eæ
\93¾
\82Å
\97á
\8aO
\82 \82è');
711 Writeln('E.Message: ' + E.Message);
714 Item.LastModified := ZERO_DATE;
715 Item.ContentLength := 0;
716 Item.ErrText := E.Message;
717 ResponseCode := FIndy.ResponseCode;
719 Screen.Cursor := crDefault;
723 if (Item.ContentLength = 0) and (ResponseCode = 206) then
724 Item.ResponseCode := 304
726 Item.ResponseCode := ResponseCode;
731 function TDownloadThread.DatDownload(ItemType: TGikoDownloadType; URL: string; Modified: TDateTime; RangeStart: Integer; AdjustLen: Integer): Boolean;
733 ResponseCode: Integer;
734 ResStream: TMemoryStream;
737 if (ItemType = gdtThread) and (RangeStart > 0) then begin
738 // if (ItemType = gdtThread) and (Item.ThreadItem.Size > 0) then begin
739 // FIndy.Request.ContentRangeStart := Item.ThreadItem.Size + AdjustLen;
740 FIndy.Request.ContentRangeStart := RangeStart + AdjustLen;
741 FIndy.Request.ContentRangeEnd := 0;
743 FIndy.Request.ContentRangeStart := 0;
744 FIndy.Request.ContentRangeEnd := 0;
747 FIndy.Request.CustomHeaders.Clear;
748 FIndy.Request.CacheControl := 'no-cache';
749 FIndy.Request.CustomHeaders.Add('Pragma: no-cache');
750 if (Modified <> 0) and (Modified <> ZERO_DATE) then begin
751 FIndy.Request.LastModified := modified - OffsetFromUTC;
752 //FIndy.Request.CustomHeaders.Add('If-Modified-Since: ' + RFC1123_Date(modified - OffsetFromUTC) + ' GMT');
754 // FIndy.Request.AcceptEncoding := 'gzip';
755 if RangeStart = 0 then
756 FIndy.Request.AcceptEncoding := 'gzip'
758 FIndy.Request.AcceptEncoding := '';
759 ResStream := TMemoryStream.Create;
764 Writeln('URL: ' + URL);
766 FIndy.Get(URL, ResStream);
767 Item.Content := GikoSys.GzipDecompress(ResStream, FIndy.Response.ContentEncoding);
768 Item.LastModified := FIndy.Response.LastModified;
769 //
\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é
770 // Item.ContentLength := FIndy.Response.ContentLength + AdjustLen;
771 Item.ContentLength := Length(Item.Content) + AdjustLen;
772 //
\96³
\82¢
\82Æ
\8ev
\82¤
\82¯
\82Ç
\81B
\81B
\81B
773 // if (FIndy.ResponseCode in [200, 206]) and (Item.Content = '') then
775 if Item.Content = '' then
780 Writeln('
\8eæ
\93¾
\82Å
\97á
\8aO
\82È
\82µ');
782 ResponseCode := FIndy.ResponseCode;
784 on E: EIdSocketError do begin
786 Item.LastModified := ZERO_DATE;
787 Item.ContentLength := 0;
788 Item.ErrText := E.Message;
791 Screen.Cursor := crDefault;
793 on E: EIdConnectException do begin
795 Item.LastModified := ZERO_DATE;
796 Item.ContentLength := 0;
797 Item.ErrText := E.Message;
800 Screen.Cursor := crDefault;
802 on E: Exception do begin
804 Writeln('
\8eæ
\93¾
\82Å
\97á
\8aO
\82 \82è');
805 Writeln('E.Message: ' + E.Message);
808 Item.LastModified := ZERO_DATE;
809 Item.ContentLength := 0;
810 Item.ErrText := E.Message;
811 ResponseCode := FIndy.ResponseCode;
813 Screen.Cursor := crDefault;
817 if (Item.ContentLength = 0) and (ResponseCode = 206) then
818 Item.ResponseCode := 304
820 Item.ResponseCode := ResponseCode;
825 procedure TDownloadThread.FireDownloadEnd;
827 OnDownloadEnd(self, Item);
830 procedure TDownloadThread.FireDownloadMsg;
832 OnDownloadMsg(Self, Item, FMsg, FIcon);
835 procedure TDownloadThread.GetSessionID;
837 FSessionID := GikoSys.Dolib.SessionID;
840 procedure TDownloadThread.Abort;
843 FIndy.DisconnectSocket;
844 if socket <> nil then begin
845 socket.DisconnectSocket;
849 procedure TDownloadThread.WorkBegin(Sender: TObject; AWorkMode: TWorkMode; const AWorkCountMax: Integer);
851 if Assigned(OnWorkBegin) then
852 OnWorkBegin(Sender, AWorkMode, AWorkCountMax, FNumber, FDownloadTitle);
855 procedure TDownloadThread.WorkEnd(Sender: TObject; AWorkMode: TWorkMode);
857 if Assigned(OnWorkEnd) then
858 OnWorkEnd(Sender, AWorkMode, FNumber);
861 procedure TDownloadThread.Work(Sender: TObject; AWorkMode: TWorkMode; const AWorkCount: Integer);
863 if Assigned(OnWork) then
864 OnWork(Sender, AWorkMode, AWorkCount, FNumber);
867 function TDownloadThread.ParseCgiStatus(Content: string): TCgiStatus;
876 // [+OK]
\82Ì
\8fê
\8d\87\82Í
\8d·
\95ª
877 // [-INCR] (Incorrect)
\82Ì
\8fê
\8d\87\82Í
\82·
\82×
\82Ä
\82Ì
\83f
\81[
\83^
878 // [-ERR (
\83e
\83L
\83X
\83g)]
\82Ì
\8fê
\8d\87\82Í
\82È
\82ñ
\82©
\83G
\83\89\81[
879 //
\97á
\81F+OK 23094/512K
881 // -ERR
\82»
\82ñ
\82È
\94Â
\82È
\82¢
\82Å
\82·
882 Idx := AnsiPos(#10, Content);
883 StatusLine := Copy(Content, 0, Idx);
885 Idx := AnsiPos(' ', Content);
886 Status := Copy(StatusLine, 0, Idx - 1);
887 Line := Copy(StatusLine, Idx + 1, Length(StatusLine));
889 // Idx := AnsiPos('/', Line);
890 if Trim(Status) = '-ERR' then
893 Size := Copy(Line, 0, Idx - 1);
895 if Trim(Status) = '+OK' then
896 Result.FStatus := gcsOK
897 else if Trim(Status) = '-INCR' then
898 Result.FStatus := gcsINCR
899 else if Trim(Status) = '-ERR' then begin
900 Result.FStatus := gcsERR;
901 Result.FErrText := Msg;
908 Result.FStatus := gcsERR;
909 Result.FErrText := '
\83G
\83\89\81[
\82È
\82ñ
\82¾
\82¯
\82Ç
\81A
\82æ
\82
\95ª
\82©
\82ç
\82È
\82¢
\83G
\83\89\81[';
914 if GikoSys.IsNumeric(Size) then
915 Result.FSize := StrToInt(Size)
918 Result.FStatus := gcsERR;
919 Result.FErrText := '
\83X
\83e
\81[
\83^
\83X
\89ð
\90Í
\8e¸
\94s[' + StatusLine + ']';
923 //
\8eè
\94²
\82«
\82È
\8f\88\97\9d\82Å1
\8ds
\96Ú
\82ð
\8fÁ
\82·
924 function TDownloadThread.DeleteStatusLine(Content: string): string;
928 SList := TStringList.Create;
930 SList.Text := Content;
931 if SList.Count > 1 then
933 Result := SList.Text;
939 procedure TDownloadItem.SaveListFile;
943 NewItem: TThreadItem;
947 function MakeThreadCallBack(
948 inInstance : DWORD; // TBoardItem
\82Ì
\83C
\83\93\83X
\83^
\83\93\83X
949 inURL : PChar; //
\83X
\83\8c\83b
\83h
\82Ì URL
950 inTitle : PChar; //
\83X
\83\8c\83^
\83C
951 inCount : DWORD //
\83\8c\83X
\82Ì
\90\94
952 ) : Boolean; stdcall; //
\97ñ
\8b\93\82ð
\91±
\82¯
\82é
\82È
\82ç True
954 _ThreadItem : TThreadItem; // '_'
\82Í
\83N
\83\89\83X
\82Ì
\83v
\83\8d\83p
\83e
\83B
\82Æ
\82©
\82Ô
\82Á
\82Ä
\82é
\82Ì
\82Å
958 boardItem := TBoard( inInstance );
960 boardItem.IntData := boardItem.IntData + 1;
961 index := boardItem.GetIndexFromURL( string( inURL ) );
962 if index = -1 then begin
963 //
\90V
\82µ
\82¢
\83X
\83\8c\83b
\83h
964 _ThreadItem := TThreadItem.Create( boardItem.BoardPlugIn, string( inURL ) );
966 _ThreadItem.Title := string( inTitle );
967 _ThreadItem.AllResCount := inCount;
968 _ThreadItem.ParentBoard := Board;
969 _ThreadItem.No := boardItem.IntData;
970 _ThreadItem.RoundDate := ZERO_DATE;
971 _ThreadItem.LastModified := ZERO_DATE;
972 _ThreadItem.AgeSage := gasNew;
973 boardItem.Add(_ThreadItem);
975 if boardItem.Items[index].No > boardItem.IntData then
976 boardItem.Items[index].AgeSage := gasAge
977 else if boardItem.Items[index].AllResCount < inCount then
978 boardItem.Items[index].AgeSage := gasSage
980 boardItem.Items[index].AgeSage := gasNone;
982 boardItem.Items[index].No := boardItem.IntData;
983 boardItem.Items[index].AllResCount := inCount;
987 //Board.ListData := TList.Create;
988 Body := TStringList.Create;
990 //
\83_
\83E
\83\93\83\8d\81[
\83h
\93ú
\8e\9e\90Ý
\92è
\81i
\83\8d\81[
\83J
\83\8b\93ú
\8e\9e\81j
991 Board.RoundDate := Now;
992 //
\83T
\81[
\83o
\8fã
\83t
\83@
\83C
\83\8b\82Ì
\8dX
\90V
\8e\9e\8d\8f\90Ý
\92è
993 Board.LastModified := LastModified;
995 //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é
996 Sort.SortOrder := False; //
\8d~
\8f\87
997 Sort.SortIndex := 7; //
\83X
\83\8c\8dì
\90¬
\93ú
\8e\9e
998 Sort.SortNonAcquiredCountFlag := GikoSys.Setting.NonAcquiredCount;
999 Board.CustomSort(ThreadItemSortProc);
1001 for i := Board.Count - 1 downto 0 do
1002 Board.Items[i].AgeSage := gasNull;
1004 if Board.IsBoardPlugInAvailable then begin
1005 //
\90V
\82µ
\82¢
\83\8a\83X
\83g
\82ð
\8dì
\90¬
\82·
\82é
1006 //
\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Á
1007 //
\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¬
1009 Board.BoardPlugIn.EnumThread( DWORD( Board ), @MakeThreadCallBack );
1011 //
\8cÃ
\82¢
\83\8a\83X
\83g
\82É
\82µ
\82©
\82È
\82¢
\82â
\82Â
\82ç
\82ð
\8dí
\8f\9c
1012 for i := Board.Count - 1 downto 0 do begin
1013 if( Board.Items[i].AgeSage = gasNull )and not (Board.Items[i].IsLogFile) then
1017 //
\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Á
1018 for i := 0 to Board.Count - 1 do begin
1019 if(Board.Items[i].AgeSage = gasNull) and (Board.Items[i].IsLogFile) then begin
1020 Board.IntData := Board.IntData + 1;
1021 Board.Items[i].No := Board.IntData;
1022 Board.Items[i].AllResCount := Board.Items[i].Count;
1023 Board.Items[i].NewResCount := 0;
1024 Board.Items[i].AgeSage := gasNone;
1028 //
\90V
\82µ
\82¢
\83\8a\83X
\83g
\82ð
\8dì
\90¬
\82·
\82é
1029 //
\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Á
1030 //
\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¬
1031 Body.Text := Content;
1033 for i := 0 to Body.Count - 1 do begin
1034 Rec := GikoSys.DivideSubject(Body[i]);
1035 Rec.FFileName := Trim(Rec.FFileName);
1036 if (Rec.FTitle = '') and (Rec.FCount = 0) then Continue;
1038 index := Board.GetIndexFromFileName(Rec.FFileName);
1039 if index = -1 then begin
1040 //
\90V
\82µ
\82¢
\83X
\83\8c\83b
\83h
1041 NewItem := TThreadItem.Create(
1042 nil, GikoSys.Get2chBoard2ThreadURL( Board, ChangeFileExt( Rec.FFileName, '' ) ) );
1043 NewItem.Title := Rec.FTitle;
1044 NewItem.AllResCount := Rec.FCount;
1045 NewItem.ParentBoard := Board;
1046 NewItem.No := NumCount;
1047 NewItem.RoundDate := ZERO_DATE;
1048 NewItem.LastModified := ZERO_DATE;
1049 NewItem.AgeSage := gasNew;
1052 if Board.Items[index].No > NumCount then
1053 Board.Items[index].AgeSage := gasAge
1054 else if Board.Items[index].AllResCount < Rec.FCount then
1055 Board.Items[index].AgeSage := gasSage
1057 Board.Items[index].AgeSage := gasNone;
1059 Board.Items[index].No := NumCount;
1060 Board.Items[index].AllResCount := Rec.FCount;
1063 //
\8cÃ
\82¢
\83\8a\83X
\83g
\82Ì
\8dí
\8f\9c
1064 for i := Board.Count - 1 downto 0 do begin
1065 if( Board.Items[i].AgeSage = gasNull )and not (Board.Items[i].IsLogFile) then
1069 //
\90V
\82µ
\82¢
\83\8a\83X
\83g
\82É
\96³
\82©
\82Á
\82½
\83A
\83C
\83e
\83\80\82Ì
\8dX
\90V
1070 for i := 0 to Board.Count - 1 do begin
1071 if( Board.Items[i].AgeSage = gasNull )and (Board.Items[i].IsLogFile) then begin
1073 Board.Items[i].No := NumCount;
1074 Board.Items[i].AllResCount := Board.Items[i].Count;
1075 Board.Items[i].NewResCount := 0;
1076 Board.Items[i].AgeSage := gasNone;
1079 //
\83\8a\83X
\83g(subject.txt)
\82ð
\95Û
\91¶
1080 GikoSys.ForceDirectoriesEx(ExtractFilePath(Board.GetSubjectFileName));
1081 Body.SaveToFile(Board.GetSubjectFileName);
1090 {procedure TDownloadItem.SaveListFile;
1094 NewItem: TThreadItem;
1096 // SaveCount: Integer;
1101 NewList := TList.Create;
1102 Body := TStringList.Create;
1104 //
\8f\84\89ñ
\93ú
\8e\9e\90Ý
\92è
1105 Board.RoundDate := Now;
1106 //
\83T
\81[
\83o
\8fã
\83t
\83@
\83C
\83\8b\82Ì
\8dX
\90V
\8e\9e\8d\8f\90Ý
\92è
1107 Board.LastModified := LastModified;
1109 //
\83\8a\83X
\83g
\95Û
\91¶
\8c\8f\90\94\8eæ
\93¾
1110 //SaveCount := MaxInt;
1112 //
\8cÃ
\82¢
\83\8a\83X
\83g
\82©
\82ç
\83\8d\83O
\96³
\82µ
\83A
\83C
\83e
\83\80\82ð
\8dí
\8f\9c
1113 for i := Board.Count - 1 downto 0 do
1114 if not Board.Items[i].IsLogFile then
1117 //
\90V
\82µ
\82¢
\83\8a\83X
\83g
\82ð
\8dì
\90¬
\82·
\82é
1118 //
\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Á
1119 //
\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¬
1120 Body.Text := Content;
1121 // Loop := Min(Body.Count, SaveCount);
1123 // for i := 0 to Loop - 1 do begin
1124 for i := 0 to Body.Count - 1 do begin
1125 if i = 0 then Continue; //
\82P
\8ds
\96Ú
\82Í
\83X
\83e
\81[
\83^
\83X
\8ds
\82Ì
\82½
\82ß
\8f\88\97\9d\82È
\82µ
1127 Rec := GikoSys.DivideSubject(Body[i]);
1128 if (Rec.FTitle = '') and (Rec.FCount = 0) then Continue;
1130 index := Board.GetIndex(Rec.FFileName);
1131 if index = -1 then begin
1132 NewItem := TThreadItem.Create;
1133 NewItem.FileName := Rec.FFileName;
1134 NewItem.Title := Rec.FTitle;
1135 NewItem.Count := Rec.FCount;
1136 NewItem.ParentBoard := Board;
1137 NewItem.No := NumCount;
1138 NewItem.RoundDate := ZERO_DATE;
1139 NewItem.LastModified := ZERO_DATE;
1140 NewList.Add(NewItem);
1142 //Board.Items[index].Count := Count;
1143 Board.Items[index].No := NumCount;
1144 NewList.Add(Board.Items[index]);
1145 Board.DeleteList(index);
1149 //
\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Á
1150 for i := 0 to Board.Count - 1 do begin
1152 Board.Items[i].No := NumCount;
1153 NewList.Add(Board.Items[i]);
1156 //
\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
1157 for i := Board.Count - 1 downto 0 do
1158 Board.DeleteList(i);
1160 //
\90V
\82µ
\82¢
\83\8a\83X
\83g
\82ð
\83{
\81[
\83h
\83I
\83u
\83W
\83F
\83N
\83g
\82É
\92Ç
\89Á
1161 for i := 0 to NewList.Count - 1 do
1162 Board.Add(TThreadItem(NewList[i]));
1164 //
\83\8a\83X
\83g(subject.txt)
\82ð
\95Û
\91¶
1165 // GikoSys.ForceDirectoriesEx(GikoSys.GetLogDir + Board.BBSID);
1166 // Body.SaveToFile(GikoSys.GetSubjectFileName(Board.BBSID));
1167 GikoSys.ForceDirectoriesEx(ExtractFilePath(Board.GetSubjectFileName));
1168 Body.SaveToFile(Board.GetSubjectFileName);
1175 procedure TDownloadItem.SaveItemFile;
1193 FileName := ThreadItem.GetThreadFileName;
1195 if not ThreadItem.IsBoardPlugInAvailable then begin
1196 if Trim(Content) = '' then
1199 GikoSys.ForceDirectoriesEx(ExtractFilePath(FileName));
1202 Body := TStringList.Create;
1206 // if FileExists(FileName) and (ResponseCode = 206) then begin
1207 if FileExists(FileName) and (State = gdsDiffComplete) then begin
1208 // Body.Text := Content;
1209 // if Body.Count > 0 then
1211 // Content := Body.Text;
1216 Body.LoadFromFile(FileName);
1217 OldCnt := Body.Count;
1218 Body.Text := Body.Text + Content;
1219 Body.SaveToFile(FileName);
1220 NewRes := Body.Count - OldCnt;
1222 on E:EFOpenError do begin
1228 until finish and ( loopCnt > 0 );
1229 //Cnt := Body.Count;
1231 if IsAbone then begin
1232 //
\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 Body.LoadFromFile(FileName);
1239 on E:EFOpenError do begin
1245 until finish and ( loopCnt > 0 );
1246 LastTxt := Body.Strings[ ThreadItem.Count - 1 ];
1247 if ThreadItem.Kokomade > 0 then begin
1248 KokoTxt := Body.Strings[ ThreadItem.Kokomade - 1 ];
1250 if ThreadItem.NewReceive > 0 then begin
1251 NewTxt := Body.Strings[ ThreadItem.NewReceive - 1 ];
1254 Body.Text := Content;
1255 ThreadItem.AllResCount := 0;
1256 ThreadItem.NewResCount := 0;
1257 NewRes := Body.Count;
1259 Body.Find( LastTxt, LastIdx );
1260 OldCnt := LastIdx + 1;
1261 if ThreadItem.Kokomade > 0 then begin
1262 Body.Find( KokoTxt, KokoIdx );
1263 ThreadItem.Kokomade := KokoIdx + 1;
1265 if ThreadItem.NewReceive > 0 then begin
1266 Body.Find( NewTxt, NewIdx );
1268 ThreadItem.AllResCount := NewIdx;
1269 if OldCnt >= NewIdx then
1270 NewRes := Body.Count - OldCnt
1272 NewRes := Body.Count - NewIdx;
1275 Body.Text := Content;
1276 //ThreadItem.Count := 0;
1277 ThreadItem.AllResCount := 0;
1278 ThreadItem.NewResCount := 0;
1280 NewRes := Body.Count;
1281 //Cnt := Body.Count;
1283 // if Body.Count > 0 then
1285 Body.SaveToFile(FileName);
1287 if ThreadItem.Title = '' then begin
1288 Res := GikoSys.DivideStrLine(Body[0]);
1289 ThreadItem.Title := Res.FTitle;
1291 ThreadItem.Size := 0;
1298 ThreadItem.Size := ThreadItem.Size + ContentLength;
1299 ThreadItem.LastModified := LastModified;
1300 ThreadItem.Count := Cnt;
1301 //ThreadItem.AllResCount := Cnt;
1302 ThreadItem.NewResCount := NewRes;
1303 ThreadItem.NewReceive := OldCnt + 1;
1305 ThreadItem.AllResCount := ThreadItem.Count;
1306 ThreadItem.IsLogFile := True;
1307 ThreadItem.RoundDate := Now;
1308 ThreadItem.UnRead := True;
1309 ThreadItem.ParentBoard.UnRead := ThreadItem.ParentBoard.UnRead + 1;
1310 // if ThreadItem.RoundNo = 6 then
1311 // ThreadItem.RoundNo := 0;
1313 //
\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
1314 //
\90³
\8fí
\8fI
\97¹
\8e\9e\82É
\82Í
\8dí
\8f\9c
1315 //
\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
1316 ini := TMemIniFile.Create(ChangeFileExt(FileName, '.tmp'));
1318 ini.WriteDateTime('Setting', 'RoundDate', ThreadItem.RoundDate);
1319 ini.WriteDateTime('Setting', 'LastModified', ThreadItem.LastModified);
1320 ini.WriteInteger('Setting', 'Size', ThreadItem.Size);
1321 ini.WriteInteger('Setting', 'Count', ThreadItem.Count);
1322 ini.WriteInteger('Setting', 'AllResCount', ThreadItem.AllResCount);
1323 ini.WriteInteger('Setting', 'NewResCount', ThreadItem.NewResCount);
1324 ini.WriteInteger('Setting', 'NewReceive', ThreadItem.NewReceive);
1325 // ini.WriteInteger('Setting', 'RoundNo', ThreadItem.RoundNo);
1326 ini.WriteBool('Setting', 'Round', ThreadItem.Round);
1327 ini.WriteBool('Setting', 'UnRead', ThreadItem.UnRead);