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 //FWorkCS: TCriticalSection;
32 //IdHttp
\82ÌOnWork
\81AOnWorkBegin,OnWorkEnd
\82Í
\95Ê
\82Ì
\83X
\83\8c\83b
\83h
\82©
\82ç
33 //
\8cÄ
\82Î
\82ê
\82é
\88×
\81ASynchronize
\82Å
\93¯
\8aú
\82·
\82é
\95K
\97v
\82ª
\82 \82é
\81B
34 //
\83N
\83\8a\83e
\83B
\83J
\83\8b\83Z
\83N
\83V
\83\87\83\93\82Í
\96³
\82
\82Ä
\82à
\82½
\82Ô
\82ñ
\95½
\8bC
\82¾
\82¯
\82Ç
\97p
\90S
\82Ì
\88×
\81B by eggcake
35 FWorkCS: TCriticalSection;
37 FAWorkMode: TWorkMode;
39 FAWorkCountMax: Integer
41 TDownloadThread = class(TThread)
48 FIcon: TGikoMessageIcon;
50 FOnWork: TGikoWorkEvent;
51 FOnWorkBegin: TGikoWorkBeginEvent;
52 FOnWorkEnd: TGikoWorkEndEvent;
53 FOnDownloadEnd: TDownloadEndEvent;
54 FOnDownloadMsg: TDownloadMsgEvent;
55 FDownloadTitle: string;
58 procedure FireDownloadEnd;
59 procedure FireDownloadMsg;
60 procedure GetSessionID;
61 procedure WorkBegin(Sender: TObject; AWorkMode: TWorkMode; const AWorkCountMax: Integer);
62 procedure WorkEnd(Sender: TObject; AWorkMode: TWorkMode);
63 procedure Work(Sender: TObject; AWorkMode: TWorkMode; const AWorkCount: Integer);
64 function ParseCgiStatus(Content: string): TCgiStatus;
65 function CgiDownload(ItemType: TGikoDownloadType; URL: string; Modified: TDateTime): Boolean;
66 function DatDownload(ItemType: TGikoDownloadType; URL: string; Modified: TDateTime; RangeStart: Integer; AdjustLen: Integer): Boolean;
67 procedure DeleteStatusLine(Item: TDownloadItem);
68 procedure InitHttpClient(client: TIdHttp);
69 procedure ClearHttpClient(client: TIdHttp);
71 procedure FireWorkBegin;
72 procedure FireWorkEnd;
74 procedure Execute; override;
76 property Item: TDownloadItem read FItem write FItem;
77 property Number: Integer read FNumber write FNumber;
78 constructor Create(CreateSuspended: Boolean);
79 destructor Destroy; override;
81 property OnWork: TGikoWorkEvent read FOnWork write FOnWork;
82 property OnWorkBegin: TGikoWorkBeginEvent read FOnWorkBegin write FOnWorkBegin;
83 property OnWorkEnd: TGikoWorkEndEvent read FOnWorkEnd write FOnWorkEnd;
84 property OnDownloadEnd: TDownloadEndEvent read FOnDownloadEnd write FOnDownloadEnd;
85 property OnDownloadMsg: TDownloadMsgEvent read FOnDownloadMsg write FOnDownloadMsg;
88 TDownloadItem = class(TObject)
90 FDownType: TGikoDownloadType;
92 FThreadItem: TThreadItem;
94 FContentLength: Integer;
95 FLastModified: TDateTime;
97 FResponseCode: Smallint;
98 FState: TGikoDownloadState;
100 FForceDownload: Boolean;
103 procedure SaveListFile;
104 procedure SaveItemFile;
106 property DownType: TGikoDownloadType read FDownType write FDownType;
107 property Board: TBoard read FBoard write FBoard;
108 property ThreadItem: TThreadItem read FThreadItem write FThreadItem;
110 property ContentLength: Integer read FContentLength write FContentLength;
111 property LastModified: TDateTime read FLastModified write FLastModified;
112 property Content: string read FContent write FContent;
113 property ResponseCode: Smallint read FResponseCode write FResponseCode;
114 property State: TGikoDownloadState read FState write FState;
115 property ErrText: string read FErrText write FErrText;
116 property ForceDownload: Boolean read FForceDownload write FForceDownload;
117 property IsAbone : Boolean read FIsAbone write FIsAbone;
123 Y_TextConverter, MojuUtils, HTMLCreate, ReplaceDataModule;
125 constructor TDownloadThread.Create(CreateSuspended: Boolean);
127 inherited Create(CreateSuspended);
128 FWorkData.FWorkCS := TCriticalSection.Create;
130 FIndy := TIdHttp.Create(nil);
132 FIndy.OnWorkBegin := WorkBegin;
133 FIndy.OnWorkEnd := WorkEnd;
134 FIndy.OnWork := Work;
137 destructor TDownloadThread.Destroy;
139 ClearHttpClient(FIndy);
141 FWorkData.FWorkCS.Free;
145 function RFC1123_Date(aDate : TDateTime) : String;
147 StrWeekDay : String = 'MonTueWedThuFriSatSun';
148 StrMonth : String = 'JanFebMarAprMayJunJulAugSepOctNovDec';
150 Year, Month, Day : Word;
151 Hour, Min, Sec, MSec : Word;
154 DecodeDate(aDate, Year, Month, Day);
155 DecodeTime(aDate, Hour, Min, Sec, MSec);
156 DayOfWeek := ((Trunc(aDate) - 2) mod 7);
157 Result := Copy(StrWeekDay, 1 + DayOfWeek * 3, 3) + ', ' +
158 Format('%2.2d %s %4.4d %2.2d:%2.2d:%2.2d',
159 [Day, Copy(StrMonth, 1 + 3 * (Month - 1), 3),
160 Year, Hour, Min, Sec]);
162 // ******************************************************************
163 // HTTPClient
\82Ì
\8f\89\8aú
\89»
164 // ******************************************************************
165 procedure TDownloadThread.InitHttpClient(client: TIdHttp);
167 ClearHttpClient(client);
169 client.Request.UserAgent := GikoSys.GetUserAgent;
170 client.RecvBufferSize := Gikosys.Setting.RecvBufferSize;
171 client.ProxyParams.BasicAuthentication := False;
172 client.ReadTimeout := GikoSys.Setting.ReadTimeOut;
174 Writeln('------------------------------------------------------------');
176 //FIndy.AllowCookies := False;
177 if GikoSys.Setting.ReadProxy then begin
178 if GikoSys.Setting.ProxyProtocol then
179 client.ProtocolVersion := pv1_1
181 client.ProtocolVersion := pv1_0;
182 client.ProxyParams.ProxyServer := GikoSys.Setting.ReadProxyAddress;
183 client.ProxyParams.ProxyPort := GikoSys.Setting.ReadProxyPort;
184 client.ProxyParams.ProxyUsername := GikoSys.Setting.ReadProxyUserID;
185 client.ProxyParams.ProxyPassword := GikoSys.Setting.ReadProxyPassword;
186 if GikoSys.Setting.ReadProxyUserID <> '' then
187 client.ProxyParams.BasicAuthentication := True;
189 Writeln('
\83v
\83\8d\83L
\83V
\90Ý
\92è
\82 \82è');
190 Writeln('
\83z
\83X
\83g: ' + GikoSys.Setting.ReadProxyAddress);
191 Writeln('
\83|
\81[
\83g: ' + IntToStr(GikoSys.Setting.ReadProxyPort));
194 if GikoSys.Setting.Protocol then
195 client.ProtocolVersion := pv1_1
197 client.ProtocolVersion := pv1_0;
198 client.ProxyParams.ProxyServer := '';
199 client.ProxyParams.ProxyPort := 80;
200 client.ProxyParams.ProxyUsername := '';
201 client.ProxyParams.ProxyPassword := '';
203 Writeln('
\83v
\83\8d\83L
\83V
\90Ý
\92è
\82È
\82µ');
207 // ******************************************************************
208 // HTTPClient
\82Ì
\83\8a\83N
\83G
\83X
\83g
\82Æ
\83\8c\83X
\83|
\83\93\83X
\82Ì
\83f
\81[
\83^
\82Ì
\8fÁ
\8b\8e
209 // ******************************************************************
210 procedure TDownloadThread.ClearHttpClient(client: TIdHttp);
212 client.Request.CustomHeaders.Clear;
213 client.Request.RawHeaders.Clear;
214 client.Request.Clear;
215 client.Response.CustomHeaders.Clear;
216 client.Response.RawHeaders.Clear;
217 client.Response.Clear;
219 client.ProxyParams.Clear;
221 procedure TDownloadThread.Execute;
223 ResStream: TMemoryStream;
226 CgiStatus: TCgiStatus;
232 DownloadResult: Boolean;
233 boardPlugIn : TBoardPlugIn;
234 lastContent : string;
235 logFile : TFileStream;
236 adjustMargin : Integer;
240 while not Terminated do begin
241 //=====
\83v
\83\89\83O
\83C
\83\93
244 ExternalBoardManager.OnWork := Work;
245 ExternalBoardManager.OnWorkBegin := WorkBegin;
246 ExternalBoardManager.OnWorkEnd := WorkEnd;
248 FDownloadTitle := '';
249 case FItem.FDownType of
252 FDownloadTitle := FItem.FBoard.Title;
253 if FItem.FBoard <> nil then begin
254 if FItem.FBoard.IsBoardPlugInAvailable then begin
255 boardPlugIn := FItem.FBoard.BoardPlugIn;
256 Item.State := TGikoDownloadState( boardPlugIn.DownloadBoard( DWORD( FItem.FBoard ) ) );
262 FDownloadTitle := FItem.FThreadItem.Title;
263 if FItem.FThreadItem <> nil then begin
264 if FItem.FThreadItem.ParentBoard.IsBoardPlugInAvailable then begin
265 boardPlugIn := FItem.FThreadItem.ParentBoard.BoardPlugIn;
266 Item.State := TGikoDownloadState( boardPlugIn.DownloadThread( DWORD( FItem.FThreadItem ) ) );
268 //if FItem.FThreadItem.IsBoardPlugInAvailable then begin
269 // boardPlugIn := FItem.FThreadItem.BoardPlugIn;
270 // Item.State := TGikoDownloadState( boardPlugIn.DownloadThread( DWORD( FItem.FThreadItem ) ) );
275 if Length(FDownloadTitle) = 0 then
276 FDownloadTitle := '
\81i
\96¼
\8fÌ
\95s
\96¾
\81j';
278 if boardPlugIn <> nil then begin
280 Item.State := gdsAbort;
282 if Assigned( OnDownloadEnd ) then
283 Synchronize( FireDownloadEnd );
292 //=====
\83v
\83\89\83O
\83C
\83\93\82ð
\8eg
\97p
\82µ
\82È
\82¢
\8fê
\8d\87
293 InitHttpClient(FIndy);
295 if Item.DownType = gdtThread then begin
296 if FileExists( Item.ThreadItem.GetThreadFileName ) then begin
297 // dat
\83t
\83@
\83C
\83\8b\82Ì
\8dÅ
\8cã
\82ð
\93Ç
\82Ý
\8fo
\82·
298 SetLength( lastContent, ADJUST_MARGIN + 1 );
299 logFile := TFileStream.Create( Item.ThreadItem.GetThreadFileName, fmOpenRead or fmShareDenyWrite );
301 logFile.Seek( -(ADJUST_MARGIN + 1), soFromEnd );
302 logFile.Read( lastContent[ 1 ], ADJUST_MARGIN + 1 );
303 lastContent := StringReplace( lastContent, #13, '', [] ); // CR
\82Ì
\8dí
\8f\9c
310 adjustMargin := Length( lastContent );
313 FIndy.Request.ContentRangeStart := 0;
314 FIndy.Request.LastModified := ZERO_DATE;
315 ResStream := TMemoryStream.Create;
318 //********************
319 //DAT or Subject
\8eæ
\93¾
320 //********************
321 Item.ResponseCode := 0;
325 if Item.DownType = gdtBoard then begin
327 Writeln('Subject
\8eæ
\93¾');
328 Writeln('URL: ' + Item.Board.GetReadCgiURL);
329 Writeln('Modified: ' + FloatToStr(Item.Board.LastModified));
331 URL := Item.Board.GetReadCgiURL;
332 if Item.ForceDownload then begin
334 ATitle := Item.Board.Title;
336 ATitle := '
\81i
\96¼
\8fÌ
\95s
\96¾
\81j';
337 FMsg := '
\81\9a\8b
\90§
\8eæ
\93¾
\82ð
\8ds
\82¢
\82Ü
\82· - [' + ATitle + ']';
339 if Assigned(OnDownloadMsg) then
340 Synchronize(FireDownloadMsg);
341 Modified := ZERO_DATE
343 Modified := Item.Board.LastModified;
345 end else if Item.DownType = gdtThread then begin
347 Writeln('DAT
\8eæ
\93¾');
348 Writeln('URL: ' + Item.ThreadItem.GetDatURL);
349 Writeln('Modified: ' + FloatToStr(Item.ThreadItem.LastModified));
351 URL := Item.ThreadItem.GetDatURL;
352 if Item.ForceDownload then begin
354 ATitle := Item.ThreadItem.Title;
356 ATitle := '
\81i
\96¼
\8fÌ
\95s
\96¾
\81j';
357 FMsg := '
\81\9a\8b
\90§
\8eæ
\93¾
\82ð
\8ds
\82¢
\82Ü
\82· - [' + ATitle + ']';
359 if FileExists(ChangeFileExt(Item.FThreadItem.GetThreadFileName,'.NG')) = true then
360 DeleteFile(ChangeFileExt(Item.FThreadItem.GetThreadFileName,'.NG'));
361 if Assigned(OnDownloadMsg) then
362 Synchronize(FireDownloadMsg);
363 Modified := ZERO_DATE;
367 Modified := Item.ThreadItem.LastModified;
368 if Item.ThreadItem.Size > 0 then begin
370 Writeln('RangeStart: ' + IntToStr(Item.ThreadItem.Size));
372 //
\82 \82Ú
\81[
\82ñ
\83`
\83F
\83b
\83N
\82Ì
\82½
\82ß adjustMargin
\83o
\83C
\83g
\91O
\82©
\82ç
\8eæ
\93¾
373 RangeStart := Item.ThreadItem.Size;
374 AdjustLen := -adjustMargin;
378 Item.IsAbone := False;
379 DownloadResult := DatDownload(Item.DownType, URL, Modified, RangeStart, AdjustLen);
381 Writeln('ResponseCode: ' + IntToStr(FIndy.ResponseCode));
383 if Item.DownType = gdtThread then begin
384 if Item.ResponseCode = 416 then begin
385 Item.IsAbone := True;
386 DownloadResult := True;
387 end else if DownloadResult and (AdjustLen < 0) then begin
388 if Copy( Item.Content, 1, adjustMargin ) <> lastContent then
389 Item.IsAbone := True;
393 if Trim(FIndy.Response.RawHeaders.Values['Date']) <> '' then begin
394 if Item.DownType = gdtBoard then
395 Item.Board.LastGetTime := GikoSys.DateStrToDateTime(FIndy.Response.RawHeaders.Values['Date'])
397 Item.ThreadItem.ParentBoard.LastGetTime := GikoSys.DateStrToDateTime(FIndy.Response.RawHeaders.Values['Date']);
400 if DownloadResult then begin
402 Writeln('Date:' + FIndy.Response.RawHeaders.Values['Date']);
404 if Item.IsAbone then begin
406 Writeln('
\82 \82Ú
\81[
\82ñ
\8c\9f\8fo');
408 ATitle := Item.ThreadItem.Title;
410 ATitle := '
\81i
\96¼
\8fÌ
\95s
\96¾
\81j';
411 //
\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¾
414 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 + ']';
416 if FileExists(ChangeFileExt(Item.FThreadItem.GetThreadFileName,'.NG')) = true then
417 DeleteFile(ChangeFileExt(Item.FThreadItem.GetThreadFileName,'.NG'));
418 if Assigned(OnDownloadMsg) then
419 Synchronize(FireDownloadMsg);
420 if not DatDownload(Item.DownType, URL, ZERO_DATE, RangeStart, AdjustLen) then
421 Item.State := gdsError;
423 Writeln('
\82 \82Ú
\81[
\82ñ
\8dÄ
\8eæ
\93¾
\8cã');
424 Writeln('ResponseCode: ' + IntToStr(Item.ResponseCode));
426 end else if (Item.DownType = gdtThread) and (AdjustLen < 0) then begin
427 //
\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
428 Item.Content := Copy(Item.Content, adjustMargin + 1, MaxInt);
431 Item.State := gdsError;
432 if (Item.DownType = gdtBoard) and (Item.ResponseCode = 302) then begin
433 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';
435 if Assigned(OnDownloadMsg) then
436 Synchronize(FireDownloadMsg);
440 //********************
442 //********************
443 if (Item.DownType = gdtThread) and (Item.ResponseCode = 302) then begin
445 Writeln('dat.gz
\8eæ
\93¾');
447 ATitle := Item.ThreadItem.Title;
449 ATitle := '
\81i
\96¼
\8fÌ
\95s
\96¾
\81j';
450 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 + ']';
452 if Assigned(OnDownloadMsg) then
453 Synchronize(FireDownloadMsg);
454 URL := Item.ThreadItem.GetDatgzURL;
455 Modified := Item.ThreadItem.LastModified;
458 if not DatDownload(Item.DownType, URL, Modified, RangeStart, AdjustLen) then
459 Item.State := gdsError;
461 Writeln('ResponseCode: ' + IntToStr(Item.ResponseCode));
465 //********************
466 //dat.gz
\81@
\81¨
\81@dat
\82Ì
\8eæ
\93¾
\81@2005
\94N6
\8c\8e\92Ç
\89Á
\81@by
\82à
\82¶
\82ã
467 //********************
468 if (Item.DownType = gdtThread) and (Item.ResponseCode = 302) then begin
470 Writeln('dat
\8eæ
\93¾');
472 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 + ']';
474 if Assigned(OnDownloadMsg) then
475 Synchronize(FireDownloadMsg);
476 URL := ChangeFileExt(URL, '');
477 Modified := Item.ThreadItem.LastModified;
480 if not DatDownload(Item.DownType, URL, Modified, RangeStart, AdjustLen) then
481 Item.State := gdsError;
483 Writeln('ResponseCode: ' + IntToStr(Item.ResponseCode));
487 //********************
489 //********************
491 if (Item.DownType = gdtThread) and (Item.ResponseCode = 302) then begin
492 ATitle := Item.ThreadItem.Title;
494 ATitle := '
\81i
\96¼
\8fÌ
\95s
\96¾
\81j';
495 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 + ']';
497 if Assigned(OnDownloadMsg) then
498 Synchronize(FireDownloadMsg);
499 URL := Item.ThreadItem.GetOldDatgzURL;
500 Modified := Item.ThreadItem.LastModified;
503 if not DatDownload(Item.DownType, URL, Modified, RangeStart, AdjustLen) then
504 Item.State := gdsError;
508 //********************
509 //offlaw.cgi
\82Å
\8eæ
\93¾
510 //********************
512 Synchronize(GetSessionID);
513 if (Item.DownType = gdtThread) and (Item.ResponseCode = 302) and (FSessionID <> '') then begin
515 Writeln('offlaw.cgi
\82Å
\8eæ
\93¾');
517 ATitle := Item.ThreadItem.Title;
519 ATitle := '
\81i
\96¼
\8fÌ
\95s
\96¾
\81j';
520 FMsg := '
\81\9adat.gz
\82ª
\91¶
\8dÝ
\82µ
\82È
\82¢
\82½
\82ßofflaw.cgi
\82ð
\97\98\97p
\82µ
\82Ü
\82· - [' + ATitle + ']';
522 if Assigned(OnDownloadMsg) then
523 Synchronize(FireDownloadMsg);
524 URL := Item.ThreadItem.GetOfflawCgiURL(FSessionID);
525 Modified := Item.ThreadItem.LastModified;
528 if not DatDownload(Item.DownType, URL, Modified, RangeStart, AdjustLen) then begin
530 Writeln('ResponseCode: ' + IntToStr(Item.ResponseCode));
532 Item.State := gdsError;
534 if (Item.DownType = gdtThread) and (Item.ResponseCode = 302) then begin
535 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';
537 if Assigned(OnDownloadMsg) then
538 Synchronize(FireDownloadMsg);
542 CgiStatus := ParseCgiStatus(Item.Content);
544 Writeln('ResponseCode: ' + IntToStr(Item.ResponseCode));
546 case CgiStatus.FStatus of
549 Writeln('CGIStatus: OK');
551 Item.ResponseCode := 200;
552 DeleteStatusLine(Item);
555 //
\8d¡
\82Í
\82 \82è
\82¦
\82È
\82¢
557 Writeln('CGIStatus: 206');
559 Item.ResponseCode := 206;
560 DeleteStatusLine(Item);
564 Writeln('CGIStatus: 404(ERROR)');
566 Item.ResponseCode := 404;
567 Item.State := gdsError;
568 Item.ErrText := CgiStatus.FErrText;
571 if (Item.ResponseCode = 404) and (AnsiPos('
\89ß
\8b\8e\83\8d\83O
\91q
\8cÉ
\82Å
\94
\8c©', Item.ErrText) <> 0) then begin
573 Writeln('
\89ß
\8b\8e\83\8d\83O
\8eæ
\93¾');
575 ATitle := Item.ThreadItem.Title;
577 ATitle := '
\81i
\96¼
\8fÌ
\95s
\96¾
\81j';
578 FMsg := '
\81\9a\89ß
\8b\8e\83\8d\83O
\91q
\8cÉ
\82Å
\94
\8c© - [' + ATitle + ']';
580 if Assigned(OnDownloadMsg) then
581 Synchronize(FireDownloadMsg);
582 Idx := Pos(' ', Item.ErrText);
583 if Idx <> 0 then begin
584 URL := Copy(Item.ErrText, Idx + 1, Length(Item.ErrText));
585 if Pos( '://', URL ) = 0 then begin
586 if Pos('../', URL) = 1 then
587 URL := Copy(URL, 4, MaxInt );
588 if Pos( '/', URL ) = 1 then
589 URL := Copy( URL, 2, MaxInt );
590 URL := GikoSys.UrlToServer(Item.ThreadItem.ParentBoard.URL) + URL;
592 Modified := Item.ThreadItem.LastModified;
595 if not DatDownload(Item.DownType, URL, Modified, RangeStart, AdjustLen) then
596 Item.State := gdsError;
598 Writeln('ResponseCode: ' + IntToStr(Item.ResponseCode));
604 if (Item.DownType = gdtThread) and (Item.ResponseCode = 302) and (FSessionID = '') then begin
606 Writeln('
\83\8d\83O
\83C
\83\93\82³
\82ê
\82Ä
\82È
\82¢
\82Ì
\82Å
\89ß
\8b\8e\83\8d\83O
\8eæ
\93¾
\95s
\89Â');
608 ATitle := Item.ThreadItem.Title;
610 ATitle := '
\81i
\96¼
\8fÌ
\95s
\96¾
\81j';
611 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 + ']';
613 if Assigned(OnDownloadMsg) then
614 Synchronize(FireDownloadMsg);
618 case Item.ResponseCode of
619 200: Item.State := gdsComplete;
620 206: Item.State := gdsDiffComplete;
621 304: Item.State := gdsNotModify;
623 Item.State := gdsError;
626 Item.State := gdsError;
629 Item.State := gdsAbort;
631 if Assigned(OnDownloadEnd) then
632 Synchronize(FireDownloadEnd);
636 ClearHttpClient(FIndy);
638 if Terminated then Break;
643 function TDownloadThread.CgiDownload(ItemType: TGikoDownloadType; URL: string; Modified: TDateTime): Boolean;
645 ResponseCode: Integer;
646 ResStream: TMemoryStream;
649 FIndy.Request.ContentRangeStart := 0;
650 FIndy.Request.ContentRangeEnd := 0;
652 FIndy.Request.CustomHeaders.Clear;
653 if (Modified <> 0) and (Modified <> ZERO_DATE) then begin
654 FIndy.Request.LastModified := modified - OffsetFromUTC;
656 FIndy.Request.AcceptEncoding := '';
657 FIndy.Request.Accept := 'text/html';
658 ResStream := TMemoryStream.Create;
663 Writeln('URL: ' + URL);
665 FIndy.Get(URL, ResStream);
666 Item.Content := GikoSys.GzipDecompress(ResStream, FIndy.Response.ContentEncoding);
667 Item.LastModified := FIndy.Response.LastModified;
668 //
\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é
669 Item.ContentLength := Length(Item.Content);
670 //
\96³
\82¢
\82Æ
\8ev
\82¤
\82¯
\82Ç
\81B
\81B
\81B
671 if Item.Content = '' then
676 Writeln('
\8eæ
\93¾
\82Å
\97á
\8aO
\82È
\82µ');
678 ResponseCode := FIndy.ResponseCode;
680 on E: EIdSocketError do begin
682 Item.LastModified := ZERO_DATE;
683 Item.ContentLength := 0;
684 Item.ErrText := E.Message;
687 Screen.Cursor := crDefault;
689 on E: EIdConnectException do begin
691 Item.LastModified := ZERO_DATE;
692 Item.ContentLength := 0;
693 Item.ErrText := E.Message;
696 Screen.Cursor := crDefault;
698 on E: Exception do begin
700 Writeln('
\8eæ
\93¾
\82Å
\97á
\8aO
\82 \82è');
701 Writeln('E.Message: ' + E.Message);
704 Item.LastModified := ZERO_DATE;
705 Item.ContentLength := 0;
706 Item.ErrText := E.Message;
707 ResponseCode := FIndy.ResponseCode;
709 Screen.Cursor := crDefault;
713 if (Item.ContentLength = 0) and (ResponseCode = 206) then
714 Item.ResponseCode := 304
716 Item.ResponseCode := ResponseCode;
721 function TDownloadThread.DatDownload(ItemType: TGikoDownloadType; URL: string; Modified: TDateTime; RangeStart: Integer; AdjustLen: Integer): Boolean;
723 ResponseCode: Integer;
724 ResStream: TMemoryStream;
727 if (ItemType = gdtThread) and (RangeStart > 0) then begin
728 FIndy.Request.ContentRangeStart := RangeStart + AdjustLen;
729 FIndy.Request.ContentRangeEnd := 0;
731 FIndy.Request.ContentRangeStart := 0;
732 FIndy.Request.ContentRangeEnd := 0;
735 FIndy.Request.CustomHeaders.Clear;
736 FIndy.Request.CacheControl := 'no-cache';
737 FIndy.Request.CustomHeaders.Add('Pragma: no-cache');
738 if (Modified <> 0) and (Modified <> ZERO_DATE) then begin
739 FIndy.Request.LastModified := modified - OffsetFromUTC;
741 if RangeStart = 0 then
742 FIndy.Request.AcceptEncoding := 'gzip'
744 FIndy.Request.AcceptEncoding := '';
745 ResStream := TMemoryStream.Create;
750 Writeln('URL: ' + URL);
752 FIndy.Get(URL, ResStream);
753 Item.Content := GikoSys.GzipDecompress(ResStream, FIndy.Response.ContentEncoding);
754 Item.ContentLength := Length(Item.Content) + AdjustLen;
756 if GikoSys.Setting.ReplaceDat then begin
757 Item.Content := ReplaceDM.Replace(Item.Content);
759 Item.LastModified := FIndy.Response.LastModified;
760 if Item.Content = '' then
765 Writeln('
\8eæ
\93¾
\82Å
\97á
\8aO
\82È
\82µ');
767 ResponseCode := FIndy.ResponseCode;
769 on E: EIdSocketError do begin
771 Item.LastModified := ZERO_DATE;
772 Item.ContentLength := 0;
773 Item.ErrText := E.Message;
776 Screen.Cursor := crDefault;
778 on E: EIdConnectException do begin
780 Item.LastModified := ZERO_DATE;
781 Item.ContentLength := 0;
782 Item.ErrText := E.Message;
785 Screen.Cursor := crDefault;
787 on E: Exception do begin
789 Writeln('
\8eæ
\93¾
\82Å
\97á
\8aO
\82 \82è');
790 Writeln('E.Message: ' + E.Message);
793 Item.LastModified := ZERO_DATE;
794 Item.ContentLength := 0;
795 Item.ErrText := E.Message;
796 ResponseCode := FIndy.ResponseCode;
798 Screen.Cursor := crDefault;
802 if (Item.ContentLength = 0) and (ResponseCode = 206) then
803 Item.ResponseCode := 304
805 Item.ResponseCode := ResponseCode;
810 procedure TDownloadThread.FireDownloadEnd;
812 OnDownloadEnd(self, Item);
815 procedure TDownloadThread.FireDownloadMsg;
817 OnDownloadMsg(Self, Item, FMsg, FIcon);
820 procedure TDownloadThread.GetSessionID;
822 FSessionID := GikoSys.Dolib.SessionID;
825 procedure TDownloadThread.Abort;
828 FIndy.DisconnectSocket;
829 if socket <> nil then begin
830 socket.DisconnectSocket;
834 procedure TDownloadThread.WorkBegin(Sender: TObject;
835 AWorkMode: TWorkMode; const AWorkCountMax: Integer);
837 if Assigned(OnWorkBegin) then begin
838 FWorkData.FWorkCS.Acquire;
840 FWorkData.FSender := Sender;
841 FWorkData.FAWorkMode := AWorkMode;
842 FWorkData.FAWorkCountMax := AWorkCountMax;
843 Synchronize(FireWorkBegin);
845 FWorkData.FWorkCS.Release;
850 procedure TDownloadThread.WorkEnd(Sender: TObject;
851 AWorkMode: TWorkMode);
853 if Assigned(OnWorkEnd) then begin;
854 FWorkData.FWorkCS.Acquire;
856 FWorkData.FSender := Sender;
857 FWorkData.FAWorkMode := AWorkMode;
858 Synchronize(FireWorkEnd);
860 FWorkData.FWorkCS.Release;
865 procedure TDownloadThread.Work(Sender: TObject; AWorkMode:
866 TWorkMode; const AWorkCount: Integer);
868 if Assigned(OnWork) then begin
869 FWorkData.FWorkCS.Acquire;
871 FWorkData.FSender := Sender;
872 FWorkData.FAWorkMode := AWorkMode;
873 FWorkData.FAWorkCount := AWorkCount;
874 Synchronize(FireWork);
876 FWorkData.FWorkCS.Release;
881 //
\82±
\82±
\82©
\82ç
\90V
\8bK
\83\81\83\
\83b
\83h
882 procedure TDownloadThread.FireWorkBegin;
884 OnWorkBegin(FWorkData.FSender, FWorkData.FAWorkMode,
885 FWorkData.FAWorkCountMax,
886 FNumber, FDownloadTitle);
889 procedure TDownloadThread.FireWorkEnd;
891 OnWorkEnd(FWorkData.FSender, FWorkData.FAWorkMode,
895 procedure TDownloadThread.FireWork;
897 OnWork(FWorkData.FSender, FWorkData.FAWorkMode,
898 FWorkData.FAWorkCount,
902 function TDownloadThread.ParseCgiStatus(Content: string): TCgiStatus;
911 // [+OK]
\82Ì
\8fê
\8d\87\82Í
\8d·
\95ª
912 // [-INCR] (Incorrect)
\82Ì
\8fê
\8d\87\82Í
\82·
\82×
\82Ä
\82Ì
\83f
\81[
\83^
913 // [-ERR (
\83e
\83L
\83X
\83g)]
\82Ì
\8fê
\8d\87\82Í
\82È
\82ñ
\82©
\83G
\83\89\81[
914 //
\97á
\81F+OK 23094/512K
916 // -ERR
\82»
\82ñ
\82È
\94Â
\82È
\82¢
\82Å
\82·
917 Idx := AnsiPos(#10, Content);
918 StatusLine := Copy(Content, 0, Idx);
920 Idx := AnsiPos(' ', Content);
921 Status := Copy(StatusLine, 0, Idx - 1);
922 Line := Copy(StatusLine, Idx + 1, Length(StatusLine));
924 // Idx := AnsiPos('/', Line);
925 if Trim(Status) = '-ERR' then
928 Size := Copy(Line, 0, Idx - 1);
930 if Trim(Status) = '+OK' then
931 Result.FStatus := gcsOK
932 else if Trim(Status) = '-INCR' then
933 Result.FStatus := gcsINCR
934 else if Trim(Status) = '-ERR' then begin
935 Result.FStatus := gcsERR;
936 Result.FErrText := Msg;
943 Result.FStatus := gcsERR;
944 Result.FErrText := '
\83G
\83\89\81[
\82È
\82ñ
\82¾
\82¯
\82Ç
\81A
\82æ
\82
\95ª
\82©
\82ç
\82È
\82¢
\83G
\83\89\81[';
949 if GikoSys.IsNumeric(Size) then
950 Result.FSize := StrToInt(Size)
953 Result.FStatus := gcsERR;
954 Result.FErrText := '
\83X
\83e
\81[
\83^
\83X
\89ð
\90Í
\8e¸
\94s[' + StatusLine + ']';
958 //
\82P
\8ds
\96Ú
\82ð
\8fÁ
\82µ
\82Ä
\81A
\83R
\83\93\83e
\83\93\83c
\83T
\83C
\83Y
\82ð
\90Ý
\92è
\82·
\82é
959 procedure TDownloadThread.DeleteStatusLine(Item: TDownloadItem);
963 SList := TStringList.Create;
965 SList.Text := Item.Content;
966 //1
\8ds
\96Ú
\82ð
\8dí
\8f\9c
967 if SList.Count > 1 then
969 Item.Content := SList.Text;
970 //
\89ü
\8ds
\83R
\81[
\83h
\82ðCRLF -> LF
\82Æ
\8dl
\82¦
\82Ä
\81A
\8ds
\90\94\95ª
\82¾
\82¯
\83}
\83C
\83i
\83X
971 Item.ContentLength := Length(SList.Text) - SList.Count;
977 procedure TDownloadItem.SaveListFile;
981 NewItem: TThreadItem;
988 function MakeThreadCallBack(
989 inInstance : DWORD; // TBoardItem
\82Ì
\83C
\83\93\83X
\83^
\83\93\83X
990 inURL : PChar; //
\83X
\83\8c\83b
\83h
\82Ì URL
991 inTitle : PChar; //
\83X
\83\8c\83^
\83C
992 inCount : DWORD //
\83\8c\83X
\82Ì
\90\94
993 ) : Boolean; stdcall; //
\97ñ
\8b\93\82ð
\91±
\82¯
\82é
\82È
\82ç True
995 _ThreadItem : TThreadItem; // '_'
\82Í
\83N
\83\89\83X
\82Ì
\83v
\83\8d\83p
\83e
\83B
\82Æ
\82©
\82Ô
\82Á
\82Ä
\82é
\82Ì
\82Å
999 boardItem := TBoard( inInstance );
1001 boardItem.IntData := boardItem.IntData + 1;
1002 if boardItem.IntData < (boardItem.Count shr 2) then
1003 index := boardItem.GetIndexFromURL( string( inURL ) )
1005 index := boardItem.GetIndexFromURL( string( inURL ), True );
1006 if index = -1 then begin
1007 //
\90V
\82µ
\82¢
\83X
\83\8c\83b
\83h
1008 _ThreadItem := TThreadItem.Create( boardItem.BoardPlugIn, boardItem, string( inURL ) );
1010 _ThreadItem.Title := string( inTitle );
1011 _ThreadItem.AllResCount := inCount;
1012 _ThreadItem.ParentBoard := Board;
1013 _ThreadItem.No := boardItem.IntData;
1014 _ThreadItem.RoundDate := ZERO_DATE;
1015 _ThreadItem.LastModified := ZERO_DATE;
1016 _ThreadItem.AgeSage := gasNew;
1017 boardItem.Add(_ThreadItem);
1019 //
\8f\87\88Ê
\82ª
\8fã
\82ª
\82Á
\82Ä
\82¢
\82ê
\82ÎAge
\82É
\82·
\82é
1020 if boardItem.Items[index].No > boardItem.IntData then
1021 boardItem.Items[index].AgeSage := gasAge
1022 //
\8f\87\88Ê
\82ª
\8fã
\82ª
\82Á
\82Ä
\82È
\82¢
\82¯
\82Ç
\81A
\83\8c\83X
\82ª
\82Â
\82¢
\82Ä
\82½
\82ç
\81ASage
\82É
1023 else if boardItem.Items[index].AllResCount <> inCount then
1024 boardItem.Items[index].AgeSage := gasSage
1025 //
\8f\87\88Ê
\8fã
\82ª
\82Á
\82Ä
\82È
\82¢
\82µ
\81A
\83\8c\83X
\82Ì
\91\9d\8c¸
\82à
\96³
\82¯
\82ê
\82Î
\81ANone
1027 boardItem.Items[index].AgeSage := gasNone;
1029 boardItem.Items[index].No := boardItem.IntData;
1030 boardItem.Items[index].AllResCount := inCount;
1037 Writeln('SAVELIST');
1039 //Board.ListData := TList.Create;
1040 Body := TStringList.Create;
1042 //
\83_
\83E
\83\93\83\8d\81[
\83h
\93ú
\8e\9e\90Ý
\92è
\81i
\83\8d\81[
\83J
\83\8b\93ú
\8e\9e\81j
1043 Board.RoundDate := Now;
1044 //
\83T
\81[
\83o
\8fã
\83t
\83@
\83C
\83\8b\82Ì
\8dX
\90V
\8e\9e\8d\8f\90Ý
\92è
1045 Board.LastModified := LastModified;
1048 //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é
1049 if GikoSys.Setting.DatOchiSortIndex >= 0 then begin
1050 Sort.SetSortNoFlag(true);
1051 Sort.SetSortOrder(GikoSys.Setting.DatOchiSortOrder);
1052 Sort.SetSortIndex(GikoSys.Setting.DatOchiSortIndex);
1053 //Sort.SortNonAcquiredCountFlag := GikoSys.Setting.NonAcquiredCount;
1054 Board.CustomSort(ThreadItemSortProc);
1058 rt := GetTickCount - st;
1059 Writeln('END Sortd' + IntToStr(rt) + ' ms');
1062 for i := Board.Count - 1 downto 0 do
1063 Board.Items[i].AgeSage := gasNull;
1065 if Board.IsBoardPlugInAvailable then begin
1066 //
\90V
\82µ
\82¢
\83\8a\83X
\83g
\82ð
\8dì
\90¬
\82·
\82é
1067 //
\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Á
1068 //
\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¬
1071 rt := GetTickCount - st;
1072 Writeln('Start Enum' + IntToStr(rt) + ' ms');
1075 //
\82±
\82ê
\82ª
\92x
\82¢
\81@
\97v
\89ü
\91P
1077 Board.BoardPlugIn.EnumThread( DWORD( Board ), @MakeThreadCallBack );
1081 rt := GetTickCount - st;
1082 Writeln('End Enum' + IntToStr(rt) + ' ms');
1085 //
\8cÃ
\82¢
\83\8a\83X
\83g
\82É
\82µ
\82©
\82È
\82¢
\82â
\82Â
\82ç
\82ð
\8dí
\8f\9c
1086 for i := Board.Count - 1 downto 0 do begin
1087 if( Board.Items[i].AgeSage = gasNull )and not (Board.Items[i].IsLogFile) then
1091 //
\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Á
1092 for i := 0 to Board.Count - 1 do begin
1093 if(Board.Items[i].AgeSage = gasNull) and (Board.Items[i].IsLogFile) then begin
1094 Board.IntData := Board.IntData + 1;
1095 Board.Items[i].No := Board.IntData;
1096 Board.Items[i].AllResCount := Board.Items[i].Count;
1097 Board.Items[i].NewResCount := 0;
1098 Board.Items[i].AgeSage := gasArch;
1103 //
\90V
\82µ
\82¢
\83\8a\83X
\83g
\82ð
\8dì
\90¬
\82·
\82é
1104 //
\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Á
1105 //
\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¬
1106 Body.Text := Content;
1108 for i := 0 to Body.Count - 1 do begin
1109 Rec := GikoSys.DivideSubject(Body[i]);
1110 Rec.FFileName := Trim(Rec.FFileName);
1111 if (Rec.FTitle = '') and (Rec.FCount = 0) then Continue;
1113 index := Board.GetIndexFromFileName(Rec.FFileName);
1114 if index = -1 then begin
1115 //
\90V
\82µ
\82¢
\83X
\83\8c\83b
\83h
1116 NewItem := TThreadItem.Create(
1119 GikoSys.Get2chBoard2ThreadURL( Board, ChangeFileExt( Rec.FFileName, '' ) ) );
1120 NewItem.Title := Rec.FTitle;
1121 NewItem.AllResCount := Rec.FCount;
1122 NewItem.ParentBoard := Board;
1123 NewItem.No := NumCount;
1124 NewItem.RoundDate := ZERO_DATE;
1125 NewItem.LastModified := ZERO_DATE;
1126 NewItem.AgeSage := gasNew;
1129 if Board.Items[index].No > NumCount then
1130 Board.Items[index].AgeSage := gasAge
1131 else if Board.Items[index].AllResCount < Rec.FCount then
1132 Board.Items[index].AgeSage := gasSage
1134 Board.Items[index].AgeSage := gasNone;
1136 Board.Items[index].No := NumCount;
1137 Board.Items[index].AllResCount := Rec.FCount;
1140 //
\8cÃ
\82¢
\83\8a\83X
\83g
\82Ì
\8dí
\8f\9c
1141 for i := Board.Count - 1 downto 0 do begin
1142 if( Board.Items[i].AgeSage = gasNull )and not (Board.Items[i].IsLogFile) then
1146 //
\90V
\82µ
\82¢
\83\8a\83X
\83g
\82É
\96³
\82©
\82Á
\82½
\83A
\83C
\83e
\83\80\82Ì
\8dX
\90V
1147 for i := 0 to Board.Count - 1 do begin
1148 if( Board.Items[i].AgeSage = gasNull )and (Board.Items[i].IsLogFile) then begin
1150 Board.Items[i].No := NumCount;
1151 Board.Items[i].AllResCount := Board.Items[i].Count;
1152 Board.Items[i].NewResCount := 0;
1153 Board.Items[i].AgeSage := gasArch;
1156 //
\83\8a\83X
\83g(subject.txt)
\82ð
\95Û
\91¶
1157 GikoSys.ForceDirectoriesEx(ExtractFilePath(Board.GetSubjectFileName));
1158 Body.Text := MojuUtils.Sanitize(Body.Text);
1159 Body.SaveToFile(Board.GetSubjectFileName);
1168 {procedure TDownloadItem.SaveListFile;
1172 NewItem: TThreadItem;
1174 // SaveCount: Integer;
1179 NewList := TList.Create;
1180 Body := TStringList.Create;
1182 //
\8f\84\89ñ
\93ú
\8e\9e\90Ý
\92è
1183 Board.RoundDate := Now;
1184 //
\83T
\81[
\83o
\8fã
\83t
\83@
\83C
\83\8b\82Ì
\8dX
\90V
\8e\9e\8d\8f\90Ý
\92è
1185 Board.LastModified := LastModified;
1187 //
\83\8a\83X
\83g
\95Û
\91¶
\8c\8f\90\94\8eæ
\93¾
1188 //SaveCount := MaxInt;
1190 //
\8cÃ
\82¢
\83\8a\83X
\83g
\82©
\82ç
\83\8d\83O
\96³
\82µ
\83A
\83C
\83e
\83\80\82ð
\8dí
\8f\9c
1191 for i := Board.Count - 1 downto 0 do
1192 if not Board.Items[i].IsLogFile then
1195 //
\90V
\82µ
\82¢
\83\8a\83X
\83g
\82ð
\8dì
\90¬
\82·
\82é
1196 //
\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Á
1197 //
\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¬
1198 Body.Text := Content;
1199 // Loop := Min(Body.Count, SaveCount);
1201 // for i := 0 to Loop - 1 do begin
1202 for i := 0 to Body.Count - 1 do begin
1203 if i = 0 then Continue; //
\82P
\8ds
\96Ú
\82Í
\83X
\83e
\81[
\83^
\83X
\8ds
\82Ì
\82½
\82ß
\8f\88\97\9d\82È
\82µ
1205 Rec := GikoSys.DivideSubject(Body[i]);
1206 if (Rec.FTitle = '') and (Rec.FCount = 0) then Continue;
1208 index := Board.GetIndex(Rec.FFileName);
1209 if index = -1 then begin
1210 NewItem := TThreadItem.Create;
1211 NewItem.FileName := Rec.FFileName;
1212 NewItem.Title := Rec.FTitle;
1213 NewItem.Count := Rec.FCount;
1214 NewItem.ParentBoard := Board;
1215 NewItem.No := NumCount;
1216 NewItem.RoundDate := ZERO_DATE;
1217 NewItem.LastModified := ZERO_DATE;
1218 NewList.Add(NewItem);
1220 //Board.Items[index].Count := Count;
1221 Board.Items[index].No := NumCount;
1222 NewList.Add(Board.Items[index]);
1223 Board.DeleteList(index);
1227 //
\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Á
1228 for i := 0 to Board.Count - 1 do begin
1230 Board.Items[i].No := NumCount;
1231 NewList.Add(Board.Items[i]);
1234 //
\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
1235 for i := Board.Count - 1 downto 0 do
1236 Board.DeleteList(i);
1238 //
\90V
\82µ
\82¢
\83\8a\83X
\83g
\82ð
\83{
\81[
\83h
\83I
\83u
\83W
\83F
\83N
\83g
\82É
\92Ç
\89Á
1239 for i := 0 to NewList.Count - 1 do
1240 Board.Add(TThreadItem(NewList[i]));
1242 //
\83\8a\83X
\83g(subject.txt)
\82ð
\95Û
\91¶
1243 // GikoSys.ForceDirectoriesEx(GikoSys.GetLogDir + Board.BBSID);
1244 // Body.SaveToFile(GikoSys.GetSubjectFileName(Board.BBSID));
1245 GikoSys.ForceDirectoriesEx(ExtractFilePath(Board.GetSubjectFileName));
1246 Body.SaveToFile(Board.GetSubjectFileName);
1253 procedure TDownloadItem.SaveItemFile;
1255 Body, oldBody: TStringList;
1266 FileName := ThreadItem.GetThreadFileName;
1268 //if not ThreadItem.IsBoardPlugInAvailable then begin
1269 if not ThreadItem.ParentBoard.IsBoardPlugInAvailable then begin
1270 if Trim(Content) = '' then
1273 GikoSys.ForceDirectoriesEx(ExtractFilePath(FileName));
1276 Body := TStringList.Create;
1280 // if FileExists(FileName) and (ResponseCode = 206) then begin
1281 if FileExists(FileName) and (State = gdsDiffComplete) then begin
1286 Body.LoadFromFile(FileName);
1287 OldCnt := Body.Count;
1288 Body.Text := Body.Text + Content;
1289 Body.SaveToFile(FileName);
1290 NewRes := Body.Count - OldCnt;
1292 on E:EFOpenError do begin
1300 //Cnt := Body.Count;
1302 if IsAbone then begin
1303 //
\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µ
1304 oldBody := TStringList.Create;
1310 oldBody.LoadFromFile(FileName);
1312 on E:EFOpenError do begin
1323 Body.Text := Content;
1324 if (ThreadItem.Kokomade > 0) and (ThreadItem.Kokomade <= oldBody.Count) then begin
1325 ThreadItem.Kokomade := Body.IndexOf(oldBody.Strings[ ThreadItem.Kokomade - 1 ]);
1326 if ThreadItem.Kokomade <> -1 then ThreadItem.Kokomade := ThreadItem.Kokomade + 1;
1329 LastIdx := oldBody.Count;
1332 OldCnt := Body.IndexOf(oldBody.Strings[ LastIdx ]) + 1;
1333 until ( OldCnt <> 0 ) or (LastIdx = 0);
1335 if OldCnt >= Body.Count then OldCnt := Body.Count - 1;
1336 NewRes := Body.Count - OldCnt;
1338 //
\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)
1339 if ThreadItem.Kokomade > OldCnt then begin
1341 ThreadItem.Kokomade := OldCnt
1343 ThreadItem.Kokomade := 1;
1351 Body.Text := Content;
1352 //ThreadItem.Count := 0;
1354 NewRes := Body.Count;
1355 //Cnt := Body.Count;
1357 // if Body.Count > 0 then
1359 Body.SaveToFile(FileName);
1361 if ThreadItem.Title = '' then begin
1362 THTMLCreate.DivideStrLine(Body[0], @Res);
1363 ThreadItem.Title := Res.FTitle;
1365 ThreadItem.Size := 0;
1372 ThreadItem.Size := ThreadItem.Size + ContentLength;
1373 ThreadItem.LastModified := LastModified;
1374 ThreadItem.Count := Cnt;
1375 //ThreadItem.AllResCount := Cnt;
1376 ThreadItem.NewResCount := NewRes;
1377 ThreadItem.NewReceive := OldCnt + 1;
1379 ThreadItem.AllResCount := ThreadItem.Count;
1380 ThreadItem.IsLogFile := True;
1381 ThreadItem.RoundDate := Now;
1382 if not ThreadItem.UnRead then begin
1383 ThreadItem.UnRead := True;
1385 // if ThreadItem.RoundNo = 6 then
1386 // ThreadItem.RoundNo := 0;
1388 //
\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
1389 //
\90³
\8fí
\8fI
\97¹
\8e\9e\82É
\82Í
\8dí
\8f\9c
1390 //
\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
1391 ini := TMemIniFile.Create(ChangeFileExt(FileName, '.tmp'));
1393 ini.WriteDateTime('Setting', 'RoundDate', ThreadItem.RoundDate);
1394 ini.WriteDateTime('Setting', 'LastModified', ThreadItem.LastModified);
1395 ini.WriteInteger('Setting', 'Size', ThreadItem.Size);
1396 ini.WriteInteger('Setting', 'Count', ThreadItem.Count);
1397 ini.WriteInteger('Setting', 'AllResCount', ThreadItem.AllResCount);
1398 ini.WriteInteger('Setting', 'NewResCount', ThreadItem.NewResCount);
1399 ini.WriteInteger('Setting', 'NewReceive', ThreadItem.NewReceive);
1400 // ini.WriteInteger('Setting', 'RoundNo', ThreadItem.RoundNo);
1401 // ini.WriteBool('Setting', 'Round', ThreadItem.Round);
1402 ini.WriteBool('Setting', 'UnRead', ThreadItem.UnRead);