X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=ItemDownload.pas;h=c229d17be349e443e855388338e92064903425bc;hb=refs%2Fheads%2FBb52;hp=e497de5cfab9eb6b8bb4d57fb39361d842895265;hpb=4169f635026d30bf6042ec638b7669440958b60e;p=gikonavigoeson%2Fgikonavi.git diff --git a/ItemDownload.pas b/ItemDownload.pas index e497de5..c229d17 100644 --- a/ItemDownload.pas +++ b/ItemDownload.pas @@ -5,7 +5,8 @@ interface uses Windows, SysUtils, Classes, ComCtrls, Controls, Forms, IdHTTP, {HTTPApp,} YofUtils, IdGlobal, IdException, IdComponent, IniFiles, {DateUtils,} - GikoSystem, BoardGroup, MonaUtils, ExternalBoardManager; + GikoSystem, BoardGroup, MonaUtils, ExternalBoardManager, ExternalBoardPlugInMain, + Sort; type TDownloadItem = class; @@ -15,7 +16,7 @@ type TGikoDLProgress = (gdpStd, gdpAll, gdpDatOchi, gdpOfflaw); TGikoWorkEvent = procedure(Sender: TObject; AWorkMode: TWorkMode; const AWorkCount: Integer; ID: Integer) of object; - TGikoWorkBeginEvent = procedure(Sender: TObject; AWorkMode: TWorkMode; const AWorkCountMax: Integer; ID: Integer) of object; + TGikoWorkBeginEvent = procedure(Sender: TObject; AWorkMode: TWorkMode; const AWorkCountMax: Integer; ID: Integer; const AWorkTitle: string) of object; TGikoWorkEndEvent = procedure(Sender: TObject; AWorkMode: TWorkMode; ID: Integer) of object; TDownloadEndEvent = procedure(Sender: TObject; Item: TDownloadItem) of object; TDownloadMsgEvent = procedure(Sender: TObject; Item: TDownloadItem; Msg: string; Icon: TGikoMessageIcon) of object; @@ -41,6 +42,7 @@ type FOnWorkEnd: TGikoWorkEndEvent; FOnDownloadEnd: TDownloadEndEvent; FOnDownloadMsg: TDownloadMsgEvent; + FDownloadTitle: string; procedure FireDownloadEnd; procedure FireDownloadMsg; @@ -49,16 +51,18 @@ type procedure WorkEnd(Sender: TObject; AWorkMode: TWorkMode); procedure Work(Sender: TObject; AWorkMode: TWorkMode; const AWorkCount: Integer); function ParseCgiStatus(Content: string): TCgiStatus; - function CgiDownload(ItemType: TGikoDownloadType; URL: string; Modified: TDateTime): Boolean; + function CgiDownload(ItemType: TGikoDownloadType; URL: string; Modified: TDateTime): Boolean; function DatDownload(ItemType: TGikoDownloadType; URL: string; Modified: TDateTime; RangeStart: Integer; AdjustLen: Integer): Boolean; - function DeleteStatusLine(Content: string): string; + procedure DeleteStatusLine(Item: TDownloadItem); + procedure InitHttpClient(client: TIdHttp); + procedure ClearHttpClient(client: TIdHttp); protected procedure Execute; override; public property Item: TDownloadItem read FItem write FItem; property Number: Integer read FNumber write FNumber; constructor Create(CreateSuspended: Boolean); - destructor Destroy; override; + destructor Destroy; override; procedure Abort; property OnWork: TGikoWorkEvent read FOnWork write FOnWork; property OnWorkBegin: TGikoWorkBeginEvent read FOnWorkBegin write FOnWorkBegin; @@ -79,6 +83,8 @@ type FResponseCode: Smallint; FState: TGikoDownloadState; FErrText: string; + FForceDownload: Boolean; + FIsAbone : Boolean; public procedure SaveListFile; procedure SaveItemFile; @@ -93,10 +99,15 @@ type property ResponseCode: Smallint read FResponseCode write FResponseCode; property State: TGikoDownloadState read FState write FState; property ErrText: string read FErrText write FErrText; + property ForceDownload: Boolean read FForceDownload write FForceDownload; + property IsAbone : Boolean read FIsAbone write FIsAbone; end; implementation +uses + Y_TextConverter, MojuUtils, HTMLCreate; + constructor TDownloadThread.Create(CreateSuspended: Boolean); begin inherited Create(CreateSuspended); @@ -109,6 +120,7 @@ end; destructor TDownloadThread.Destroy; begin + ClearHttpClient(FIndy); FIndy.Free; inherited; end; @@ -116,21 +128,79 @@ end; function RFC1123_Date(aDate : TDateTime) : String; const StrWeekDay : String = 'MonTueWedThuFriSatSun'; - StrMonth : String = 'JanFebMarAprMayJunJulAugSepOctNovDec'; + StrMonth : String = 'JanFebMarAprMayJunJulAugSepOctNovDec'; var - Year, Month, Day : Word; - Hour, Min, Sec, MSec : Word; - DayOfWeek : Word; + Year, Month, Day : Word; + Hour, Min, Sec, MSec : Word; + DayOfWeek : Word; begin DecodeDate(aDate, Year, Month, Day); - DecodeTime(aDate, Hour, Min, Sec, MSec); + DecodeTime(aDate, Hour, Min, Sec, MSec); DayOfWeek := ((Trunc(aDate) - 2) mod 7); Result := Copy(StrWeekDay, 1 + DayOfWeek * 3, 3) + ', ' + Format('%2.2d %s %4.4d %2.2d:%2.2d:%2.2d', [Day, Copy(StrMonth, 1 + 3 * (Month - 1), 3), Year, Hour, Min, Sec]); end; - +// ****************************************************************** +// HTTPClient‚̏‰Šú‰» +// ****************************************************************** +procedure TDownloadThread.InitHttpClient(client: TIdHttp); +begin + ClearHttpClient(client); + client.Disconnect; + client.Request.UserAgent := GikoSys.GetUserAgent; + client.RecvBufferSize := Gikosys.Setting.RecvBufferSize; + client.ProxyParams.BasicAuthentication := False; + client.ReadTimeout := GikoSys.Setting.ReadTimeOut; + {$IFDEF DEBUG} + Writeln('------------------------------------------------------------'); + {$ENDIF} + //FIndy.AllowCookies := False; + if GikoSys.Setting.ReadProxy then begin + if GikoSys.Setting.ProxyProtocol then + client.ProtocolVersion := pv1_1 + else + client.ProtocolVersion := pv1_0; + client.ProxyParams.ProxyServer := GikoSys.Setting.ReadProxyAddress; + client.ProxyParams.ProxyPort := GikoSys.Setting.ReadProxyPort; + client.ProxyParams.ProxyUsername := GikoSys.Setting.ReadProxyUserID; + client.ProxyParams.ProxyPassword := GikoSys.Setting.ReadProxyPassword; + if GikoSys.Setting.ReadProxyUserID <> '' then + client.ProxyParams.BasicAuthentication := True; + {$IFDEF DEBUG} + Writeln('ƒvƒƒLƒVÝ’è‚ ‚è'); + Writeln('ƒzƒXƒg: ' + GikoSys.Setting.ReadProxyAddress); + Writeln('ƒ|[ƒg: ' + IntToStr(GikoSys.Setting.ReadProxyPort)); + {$ENDIF} + end else begin + if GikoSys.Setting.Protocol then + client.ProtocolVersion := pv1_1 + else + client.ProtocolVersion := pv1_0; + client.ProxyParams.ProxyServer := ''; + client.ProxyParams.ProxyPort := 80; + client.ProxyParams.ProxyUsername := ''; + client.ProxyParams.ProxyPassword := ''; + {$IFDEF DEBUG} + Writeln('ƒvƒƒLƒVÝ’è‚È‚µ'); + {$ENDIF} + end; +end; +// ****************************************************************** +// HTTPClient‚̃ŠƒNƒGƒXƒg‚ƃŒƒXƒ|ƒ“ƒX‚̃f[ƒ^‚̏Á‹Ž +// ****************************************************************** +procedure TDownloadThread.ClearHttpClient(client: TIdHttp); +begin + client.Request.CustomHeaders.Clear; + client.Request.RawHeaders.Clear; + client.Request.Clear; + client.Response.CustomHeaders.Clear; + client.Response.RawHeaders.Clear; + client.Response.Clear; + + client.ProxyParams.Clear; +end; procedure TDownloadThread.Execute; var ResStream: TMemoryStream; @@ -143,91 +213,84 @@ var Idx: Integer; ATitle: string; DownloadResult: Boolean; - Abone: Boolean; - foundPos: Integer; - boardPlugIn : TBoardPlugIn; - listContent : string; + boardPlugIn : TBoardPlugIn; + lastContent : string; + logFile : TFileStream; + adjustMargin : Integer; +const + ADJUST_MARGIN = 16; begin while not Terminated do begin //===== ƒvƒ‰ƒOƒCƒ“ - boardPlugIn := nil; - ExternalBoardManager.OnWork := Work; - ExternalBoardManager.OnWorkBegin := WorkBegin; - ExternalBoardManager.OnWorkEnd := WorkEnd; - - case FItem.FDownType of - gdtBoard: - begin - if FItem.FBoard <> nil then begin - if FItem.FBoard.IsBoardPlugInAvailable then begin - boardPlugIn := FItem.FBoard.BoardPlugIn; - Item.State := TGikoDownloadState( boardPlugIn.DownloadBoard( DWORD( FItem.FBoard ) ) ); - end; - end; - end; - gdtThread: - begin - if FItem.FThreadItem <> nil then begin - if FItem.FThreadItem.IsBoardPlugInAvailable then begin - boardPlugIn := FItem.FThreadItem.BoardPlugIn; - Item.State := TGikoDownloadState( boardPlugIn.DownloadThread( DWORD( FItem.FThreadItem ) ) ); - end; - end; - end; - end; - - if boardPlugIn <> nil then begin - if FAbort then - Item.State := gdsAbort; - if Assigned( OnDownloadEnd ) then - Synchronize( FireDownloadEnd ); - if Terminated then - Break; - - Suspend; - Continue; - end; + FAbort := False; + boardPlugIn := nil; + ExternalBoardManager.OnWork := Work; + ExternalBoardManager.OnWorkBegin := WorkBegin; + ExternalBoardManager.OnWorkEnd := WorkEnd; + + FDownloadTitle := ''; + case FItem.FDownType of + gdtBoard: + begin + FDownloadTitle := FItem.FBoard.Title; + if FItem.FBoard <> nil then begin + if FItem.FBoard.IsBoardPlugInAvailable then begin + boardPlugIn := FItem.FBoard.BoardPlugIn; + Item.State := TGikoDownloadState( boardPlugIn.DownloadBoard( DWORD( FItem.FBoard ) ) ); + end; + end; + end; + gdtThread: + begin + FDownloadTitle := FItem.FThreadItem.Title; + if FItem.FThreadItem <> nil then begin + if FItem.FThreadItem.ParentBoard.IsBoardPlugInAvailable then begin + boardPlugIn := FItem.FThreadItem.ParentBoard.BoardPlugIn; + Item.State := TGikoDownloadState( boardPlugIn.DownloadThread( DWORD( FItem.FThreadItem ) ) ); + end; + //if FItem.FThreadItem.IsBoardPlugInAvailable then begin + // boardPlugIn := FItem.FThreadItem.BoardPlugIn; + // Item.State := TGikoDownloadState( boardPlugIn.DownloadThread( DWORD( FItem.FThreadItem ) ) ); + //end; + end; + end; + end; + if Length(FDownloadTitle) = 0 then + FDownloadTitle := 'i–¼Ì•s–¾j'; + + if boardPlugIn <> nil then begin + if FAbort then begin + Item.State := gdsAbort; + end; + if Assigned( OnDownloadEnd ) then + Synchronize( FireDownloadEnd ); + if Terminated then + Break; + + Suspend; + Continue; + end; - //===== ƒvƒ‰ƒOƒCƒ“‚ðŽg—p‚µ‚È‚¢ê‡ FAbort := False; - FIndy.Request.CustomHeaders.Clear; - FIndy.Response.Clear; - FIndy.Request.Clear; - FIndy.Request.UserAgent := GikoSys.GetUserAgent; - FIndy.RecvBufferSize := Gikosys.Setting.RecvBufferSize; - FIndy.ProxyParams.BasicAuthentication := False; - {$IFDEF DEBUG} - Writeln('------------------------------------------------------------'); - {$ENDIF} - //FIndy.AllowCookies := False; - if GikoSys.Setting.ReadProxy then begin - if GikoSys.Setting.ProxyProtocol then - FIndy.ProtocolVersion := pv1_1 - else - FIndy.ProtocolVersion := pv1_0; - FIndy.ProxyParams.ProxyServer := GikoSys.Setting.ReadProxyAddress; - FIndy.ProxyParams.ProxyPort := GikoSys.Setting.ReadProxyPort; - FIndy.ProxyParams.ProxyUsername := GikoSys.Setting.ReadProxyUserID; - FIndy.ProxyParams.ProxyPassword := GikoSys.Setting.ReadProxyPassword; - if GikoSys.Setting.ReadProxyUserID <> '' then - FIndy.ProxyParams.BasicAuthentication := True; - {$IFDEF DEBUG} - Writeln('ƒvƒƒLƒVÝ’è‚ ‚è'); - Writeln('ƒzƒXƒg: ' + GikoSys.Setting.ReadProxyAddress); - Writeln('ƒ|[ƒg: ' + IntToStr(GikoSys.Setting.ReadProxyPort)); - {$ENDIF} - end else begin - if GikoSys.Setting.Protocol then - FIndy.ProtocolVersion := pv1_1 - else - FIndy.ProtocolVersion := pv1_0; - FIndy.ProxyParams.ProxyServer := ''; - FIndy.ProxyParams.ProxyPort := 80; - FIndy.ProxyParams.ProxyUsername := ''; - FIndy.ProxyParams.ProxyPassword := ''; - {$IFDEF DEBUG} - Writeln('ƒvƒƒLƒVÝ’è‚È‚µ'); - {$ENDIF} + //===== ƒvƒ‰ƒOƒCƒ“‚ðŽg—p‚µ‚È‚¢ê‡ + InitHttpClient(FIndy); + adjustMargin := 0; + if Item.DownType = gdtThread then begin + if FileExists( Item.ThreadItem.GetThreadFileName ) then begin + // dat ƒtƒ@ƒCƒ‹‚̍Ōã‚ð“ǂݏo‚· + SetLength( lastContent, ADJUST_MARGIN + 1 ); + logFile := TFileStream.Create( Item.ThreadItem.GetThreadFileName, fmOpenRead or fmShareDenyWrite ); + try + logFile.Seek( -(ADJUST_MARGIN + 1), soFromEnd ); + logFile.Read( lastContent[ 1 ], ADJUST_MARGIN + 1 ); + lastContent := StringReplace( lastContent, #13, '', [] ); // CR ‚̍폜 + finally + logFile.Free; + end; + end else begin + lastContent := ''; + end; + adjustMargin := Length( lastContent ); end; FIndy.Request.ContentRangeStart := 0; @@ -249,7 +312,19 @@ begin Writeln('Modified: ' + FloatToStr(Item.Board.LastModified)); {$ENDIF} URL := Item.Board.GetReadCgiURL; - Modified := Item.Board.LastModified; + if Item.ForceDownload then begin + // ‹­§Žæ“¾ + ATitle := Item.Board.Title; + if ATitle = '' then + ATitle := 'i–¼Ì•s–¾j'; + FMsg := 'š‹­§Žæ“¾‚ðs‚¢‚Ü‚· - [' + ATitle + ']'; + FIcon := gmiWhat; + if Assigned(OnDownloadMsg) then + Synchronize(FireDownloadMsg); + Modified := ZERO_DATE + end else begin + Modified := Item.Board.LastModified; + end; end else if Item.DownType = gdtThread then begin {$IFDEF DEBUG} Writeln('DATŽæ“¾'); @@ -257,27 +332,45 @@ begin Writeln('Modified: ' + FloatToStr(Item.ThreadItem.LastModified)); {$ENDIF} URL := Item.ThreadItem.GetDatURL; - Modified := Item.ThreadItem.LastModified; - if Item.ThreadItem.Size > 0 then begin - {$IFDEF DEBUG} - Writeln('RangeStart: ' + IntToStr(Item.ThreadItem.Size)); - {$ENDIF} - //‚ ‚ځ[‚ñƒ`ƒFƒbƒN‚Ì‚½‚ß‚PƒoƒCƒg‘O‚©‚çŽæ“¾ - RangeStart := Item.ThreadItem.Size; - AdjustLen := -1; + if Item.ForceDownload then begin + // ‹­§Žæ“¾ + ATitle := Item.ThreadItem.Title; + if ATitle = '' then + ATitle := 'i–¼Ì•s–¾j'; + FMsg := 'š‹­§Žæ“¾‚ðs‚¢‚Ü‚· - [' + ATitle + ']'; + FIcon := gmiWhat; + if FileExists(ChangeFileExt(Item.FThreadItem.GetThreadFileName,'.NG')) = true then + DeleteFile(ChangeFileExt(Item.FThreadItem.GetThreadFileName,'.NG')); + if Assigned(OnDownloadMsg) then + Synchronize(FireDownloadMsg); + Modified := ZERO_DATE; + RangeStart := 0; + AdjustLen := 0; + end else begin + Modified := Item.ThreadItem.LastModified; + if Item.ThreadItem.Size > 0 then begin + {$IFDEF DEBUG} + Writeln('RangeStart: ' + IntToStr(Item.ThreadItem.Size)); + {$ENDIF} + // ‚ ‚ځ[‚ñƒ`ƒFƒbƒN‚Ì‚½‚ß adjustMargin ƒoƒCƒg‘O‚©‚çŽæ“¾ + RangeStart := Item.ThreadItem.Size; + AdjustLen := -adjustMargin; + end; end; end; - Abone := False; + Item.IsAbone := False; DownloadResult := DatDownload(Item.DownType, URL, Modified, RangeStart, AdjustLen); {$IFDEF DEBUG} Writeln('ResponseCode: ' + IntToStr(FIndy.ResponseCode)); {$ENDIF} if Item.DownType = gdtThread then begin if Item.ResponseCode = 416 then begin - Abone := True; + Item.IsAbone := True; DownloadResult := True; - end else if DownloadResult and (AdjustLen = -1) and (Item.Content[1] <> #10) then - Abone := True; + end else if DownloadResult and (AdjustLen < 0) then begin + if Copy( Item.Content, 1, adjustMargin ) <> lastContent then + Item.IsAbone := True; + end; end; if Trim(FIndy.Response.RawHeaders.Values['Date']) <> '' then begin @@ -291,7 +384,7 @@ begin {$IFDEF DEBUG} Writeln('Date:' + FIndy.Response.RawHeaders.Values['Date']); {$ENDIF} - if Abone then begin + if Item.IsAbone then begin {$IFDEF DEBUG} Writeln('‚ ‚ځ[‚ñŒŸo'); {$ENDIF} @@ -303,8 +396,8 @@ begin AdjustLen := 0; FMsg := 'šu‚ ‚ځ[‚ñv‚ðŒŸo‚µ‚½‚̂ōĎ擾‚ðs‚¢‚Ü‚· - [' + ATitle + ']'; FIcon := gmiWhat; - if FileExists(ChangeFileExt(Item.FThreadItem.GetThreadFileName,'.NG')) = true then - DeleteFile(ChangeFileExt(Item.FThreadItem.GetThreadFileName,'.NG')); + if FileExists(ChangeFileExt(Item.FThreadItem.GetThreadFileName,'.NG')) = true then + DeleteFile(ChangeFileExt(Item.FThreadItem.GetThreadFileName,'.NG')); if Assigned(OnDownloadMsg) then Synchronize(FireDownloadMsg); if not DatDownload(Item.DownType, URL, ZERO_DATE, RangeStart, AdjustLen) then @@ -313,9 +406,9 @@ begin Writeln('‚ ‚ځ[‚ñÄŽæ“¾Œã'); Writeln('ResponseCode: ' + IntToStr(Item.ResponseCode)); {$ENDIF} - end else if (Item.DownType = gdtThread) and (AdjustLen = -1) and (Item.Content[1] = #10) then begin - //·•ªŽæ“¾‚©‚‚PƒoƒCƒg–Ú‚ªLF‚̏ꍇi³íŽæ“¾j‚Í“ª‚ÌLF‚ðíœ - Item.Content := Copy(Item.Content, 2, Length(Item.Content)); + end else if (Item.DownType = gdtThread) and (AdjustLen < 0) then begin + // ·•ªŽæ“¾‚ªo—ˆ‚½ê‡‚Í‚ ‚ځ[‚ñƒ`ƒFƒbƒN—p‚Ɏ擾‚µ‚½—]•ª‚ȃTƒCƒY‚ðíœ + Item.Content := Copy(Item.Content, adjustMargin + 1, MaxInt); end; end else begin Item.State := gdsError; @@ -353,6 +446,28 @@ begin end; //******************** + //dat.gz@¨@dat‚̎擾@2005”N6ŒŽ’ljÁ@by‚à‚¶‚ã + //******************** + if (Item.DownType = gdtThread) and (Item.ResponseCode = 302) then begin + {$IFDEF DEBUG} + Writeln('datŽæ“¾'); + {$ENDIF} + FMsg := '‰ß‹ŽƒƒO(dat.gz)‚ª‘¶Ý‚µ‚È‚¢‚½‚߉ߋŽƒƒO(dat)‚ð’T‚µ‚Ü‚· - [' + ATitle + ']'; + FIcon := gmiWhat; + if Assigned(OnDownloadMsg) then + Synchronize(FireDownloadMsg); + URL := ChangeFileExt(URL, ''); + Modified := Item.ThreadItem.LastModified; + RangeStart := 0; + AdjustLen := 0; + if not DatDownload(Item.DownType, URL, Modified, RangeStart, AdjustLen) then + Item.State := gdsError; + {$IFDEF DEBUG} + Writeln('ResponseCode: ' + IntToStr(Item.ResponseCode)); + {$ENDIF} + end; + + //******************** //dat.gzŽæ“¾(2) //******************** { @@ -417,8 +532,7 @@ begin Writeln('CGIStatus: OK'); {$ENDIF} Item.ResponseCode := 200; - Item.Content := DeleteStatusLine(Item.Content); - Item.ContentLength := CgiStatus.FSize; + DeleteStatusLine(Item); end; gcsINCR: begin //¡‚Í‚ ‚肦‚È‚¢ @@ -426,8 +540,7 @@ begin Writeln('CGIStatus: 206'); {$ENDIF} Item.ResponseCode := 206; - Item.Content := DeleteStatusLine(Item.Content); - Item.ContentLength := CgiStatus.FSize; + DeleteStatusLine(Item); end; gcsERR: begin {$IFDEF DEBUG} @@ -452,9 +565,13 @@ begin Idx := Pos(' ', Item.ErrText); if Idx <> 0 then begin URL := Copy(Item.ErrText, Idx + 1, Length(Item.ErrText)); - if Pos('../', URL) = 1 then - URL := Copy(URL, 4, Length(URL)); - URL := GikoSys.UrlToServer(Item.ThreadItem.ParentBoard.URL) + URL; + if Pos( '://', URL ) = 0 then begin + if Pos('../', URL) = 1 then + URL := Copy(URL, 4, MaxInt ); + if Pos( '/', URL ) = 1 then + URL := Copy( URL, 2, MaxInt ); + URL := GikoSys.UrlToServer(Item.ThreadItem.ParentBoard.URL) + URL; + end; Modified := Item.ThreadItem.LastModified; RangeStart := 0; AdjustLen := 0; @@ -481,40 +598,6 @@ begin end; end; - {$IFDEF DEBUG} - if (Item.DownType = gdtThread) and (Item.ResponseCode = 302) then begin - ATitle := Item.ThreadItem.Title; - if ATitle = '' then - ATitle := 'i–¼Ì•s–¾j'; - FMsg := 'š‰ß‹ŽƒƒO(1)‚ª‘¶Ý‚µ‚È‚¢‚½‚ßgoogleƒLƒƒƒbƒVƒ…‚©‚ç’T‚µ‚Ü‚· - [' + ATitle + ']'; - FIcon := gmiWhat; - if Assigned(OnDownloadMsg) then - Synchronize(FireDownloadMsg); - URL := 'http://www.google.co.jp/search?q=cache:' + Item.ThreadItem.URL; - URL := StringReplace( URL, 'l50', '', [rfReplaceAll] ); - Modified := Item.ThreadItem.LastModified; - Repeat - if not CgiDownload(Item.DownType, URL, Modified) then - Item.State := gdsError; - URL := FIndy.Response.Location; - Until Item.ResponseCode <> 301; - if Item.ResponseCode = 200 then begin - foundPos := Pos( '
', Item.Content ) + Length( '
' ); - Item.Content := Copy( Item.Content, foundPos, Length( Item.Content ) ); - foundPos := Pos( '', Item.Content ); - If foundPos > 0 Then - Item.Content := Copy( Item.Content, 1, foundPos - 1 ); - Item.Content := StringReplace( Item.Content, '
', '<>' + #13#10, [rfReplaceAll] ); - Item.Content := StringReplace( Item.Content, '', '<>', [rfReplaceAll] ); - Item.Content := StringReplace( Item.Content, '', '<>', [rfReplaceAll] ); - Item.Content := StringReplace( Item.Content, '', '<>', [rfReplaceAll] ); - Item.Content := StringReplace( Item.Content, '', '<>', [rfReplaceAll] ); - Item.Content := StringReplace( Item.Content, '
', '<>', [rfReplaceAll] ); - end; - end; - {$ENDIF} - case Item.ResponseCode of 200: Item.State := gdsComplete; 206: Item.State := gdsDiffComplete; @@ -522,68 +605,9 @@ begin else Item.State := gdsError; end; -{ - //–³‚¢‚ÆŽv‚¤‚¯‚ǁBBB - if (Item.ResponseCode in [200, 206]) and (Item.Content = '') then - Item.State := gdsError; - Item.LastModified := FIndy.Response.LastModified; - //·•ªŽæ“¾‚Å‚PƒoƒCƒg‘O‚©‚ç‚Æ‚Á‚Ä‚«‚½‚Æ‚«‚̓}ƒCƒiƒX‚·‚é - Item.ContentLength := FIndy.Response.ContentLength + AdjustLen; - try - ResStream.Clear; - FIndy.Get(URL, ResStream); - Item.Content := GikoSys.GzipDecompress(ResStream, FIndy.Response.ContentEncoding); - if (Item.DownType = gdtThread) and (AdjustLen = -1) and (Item.Content[1] <> #10) then begin - //·•ªŽæ“¾‚©‚‚PƒoƒCƒg–Ú‚ªLF‚Å‚È‚¢ê‡‚́u‚ ‚ځ[‚ñv‚³‚ê‚Ä‚¢‚é‚©‚à‚µ‚ê‚ñ‚̂ōĎ擾 - //‚±‚±‚сƒbƒZ[ƒW•\Ž¦ƒCƒxƒ“ƒg - //event - FMsg := 'u‚ ‚ځ[‚ñv‚ðŒŸo‚µ‚½‚̂ōĎ擾‚ðs‚¢‚Ü‚·'; - if Assigned(OnDownloadMsg) then - Synchronize(FireDownloadMsg); - FIndy.Request.ContentRangeStart := 0; - FIndy.Request.ContentRangeEnd := 0; - AdjustLen := 0; - ResStream.Clear; - FIndy.Get(URL, ResStream); - Item.Content := GikoSys.GzipDecompress(ResStream, FIndy.Response.ContentEncoding); - end else if (Item.DownType = gdtThread) and (AdjustLen = -1) and (Item.Content[1] = #10) then begin - //·•ªŽæ“¾‚©‚‚PƒoƒCƒg–Ú‚ªLF‚̏ꍇi³íŽæ“¾j‚Í“ª‚ÌLF‚ðíœ - Item.Content := Copy(Item.Content, 2, Length(Item.Content)); - end; - except - Item.State := gdsError; - end; - Item.ResponseCode := FIndy.ResponseCode; -} -{ - try - ResStream.Clear; - FIndy.Get(URL, ResStream); - Item.Content := GikoSys.GzipDecompress(ResStream, FIndy.Response.ContentEncoding); - except - Item.State := gdsError; - end; - - CgiStatus := ParseCgiStatus(Item.Content); - if CgiStatus.FStatus = gcsOK then begin - if CgiStatus.FSize = 0 then - Item.State := gdsNotModify - else if Item.DownType = gdtBoard then - Item.State := gdsComplete - else - Item.State := gdsDiffComplete; - end else if CgiStatus.FStatus = gcsINCR then begin - Item.State := gdsComplete; - end else if CgiStatus.FStatus = gcsERR then begin - Item.State := gdsError; - Item.ErrText := CgiStatus.FErrText; - end; - Item.ContentLength := CgiStatus.FSize; - } except Item.State := gdsError; end; - //Item.ResponseCode := FIndy.ResponseCode; if FAbort then Item.State := gdsAbort; finally @@ -591,6 +615,9 @@ begin Synchronize(FireDownloadEnd); ResStream.Free; end; + + ClearHttpClient(FIndy); + if Terminated then Break; Suspend; end; @@ -610,7 +637,7 @@ begin FIndy.Request.LastModified := modified - OffsetFromUTC; end; FIndy.Request.AcceptEncoding := ''; - FIndy.Request.Accept := 'text/html'; + FIndy.Request.Accept := 'text/html'; ResStream := TMemoryStream.Create; try try @@ -640,7 +667,7 @@ begin Item.ErrText := E.Message; Result := False; ResponseCode := -1; - Screen.Cursor := crDefault; + Screen.Cursor := crDefault; end; on E: EIdConnectException do begin Item.Content := ''; @@ -649,7 +676,7 @@ begin Item.ErrText := E.Message; Result := False; ResponseCode := -1; - Screen.Cursor := crDefault; + Screen.Cursor := crDefault; end; on E: Exception do begin {$IFDEF DEBUG} @@ -662,7 +689,7 @@ begin Item.ErrText := E.Message; ResponseCode := FIndy.ResponseCode; Result := False; - Screen.Cursor := crDefault; + Screen.Cursor := crDefault; end; end; finally @@ -681,8 +708,6 @@ var begin ResponseCode := -1; if (ItemType = gdtThread) and (RangeStart > 0) then begin -// if (ItemType = gdtThread) and (Item.ThreadItem.Size > 0) then begin -// FIndy.Request.ContentRangeStart := Item.ThreadItem.Size + AdjustLen; FIndy.Request.ContentRangeStart := RangeStart + AdjustLen; FIndy.Request.ContentRangeEnd := 0; end else begin @@ -695,9 +720,7 @@ begin FIndy.Request.CustomHeaders.Add('Pragma: no-cache'); if (Modified <> 0) and (Modified <> ZERO_DATE) then begin FIndy.Request.LastModified := modified - OffsetFromUTC; - //FIndy.Request.CustomHeaders.Add('If-Modified-Since: ' + RFC1123_Date(modified - OffsetFromUTC) + ' GMT'); end; -// FIndy.Request.AcceptEncoding := 'gzip'; if RangeStart = 0 then FIndy.Request.AcceptEncoding := 'gzip' else @@ -710,7 +733,7 @@ begin Writeln('URL: ' + URL); {$ENDIF} FIndy.Get(URL, ResStream); - Item.Content := GikoSys.GzipDecompress(ResStream, FIndy.Response.ContentEncoding); + Item.Content := GikoSys.GzipDecompress(ResStream, FIndy.Response.ContentEncoding); Item.LastModified := FIndy.Response.LastModified; //·•ªŽæ“¾‚Å‚PƒoƒCƒg‘O‚©‚ç‚Æ‚Á‚Ä‚«‚½‚Æ‚«‚̓}ƒCƒiƒX‚·‚é // Item.ContentLength := FIndy.Response.ContentLength + AdjustLen; @@ -734,7 +757,7 @@ begin Item.ErrText := E.Message; Result := False; ResponseCode := -1; - Screen.Cursor := crDefault; + Screen.Cursor := crDefault; end; on E: EIdConnectException do begin Item.Content := ''; @@ -743,7 +766,7 @@ begin Item.ErrText := E.Message; Result := False; ResponseCode := -1; - Screen.Cursor := crDefault; + Screen.Cursor := crDefault; end; on E: Exception do begin {$IFDEF DEBUG} @@ -756,7 +779,7 @@ begin Item.ErrText := E.Message; ResponseCode := FIndy.ResponseCode; Result := False; - Screen.Cursor := crDefault; + Screen.Cursor := crDefault; end; end; finally @@ -787,12 +810,15 @@ procedure TDownloadThread.Abort; begin FAbort := True; FIndy.DisconnectSocket; + if socket <> nil then begin + socket.DisconnectSocket; + end; end; procedure TDownloadThread.WorkBegin(Sender: TObject; AWorkMode: TWorkMode; const AWorkCountMax: Integer); begin if Assigned(OnWorkBegin) then - OnWorkBegin(Sender, AWorkMode, AWorkCountMax, FNumber); + OnWorkBegin(Sender, AWorkMode, AWorkCountMax, FNumber, FDownloadTitle); end; procedure TDownloadThread.WorkEnd(Sender: TObject; AWorkMode: TWorkMode); @@ -820,8 +846,8 @@ begin // [-INCR] (Incorrect)‚̏ꍇ‚Í‚·‚ׂẴf[ƒ^ // [-ERR (ƒeƒLƒXƒg)]‚̏ꍇ‚Í‚È‚ñ‚©ƒGƒ‰[ // —áF+OK 23094/512K -// -INCR 23094/512K -// -ERR ‚»‚ñ‚Ȕ‚Ȃ¢‚Å‚· +// -INCR 23094/512K +// -ERR ‚»‚ñ‚Ȕ‚Ȃ¢‚Å‚· Idx := AnsiPos(#10, Content); StatusLine := Copy(Content, 0, Idx); @@ -863,17 +889,20 @@ begin end; end; -//Žè”²‚«‚ȏˆ—‚Å1s–Ú‚ðÁ‚· -function TDownloadThread.DeleteStatusLine(Content: string): string; +//‚Ps–Ú‚ðÁ‚µ‚āAƒRƒ“ƒeƒ“ƒcƒTƒCƒY‚ðÝ’è‚·‚é +procedure TDownloadThread.DeleteStatusLine(Item: TDownloadItem); var SList: TStringList; begin SList := TStringList.Create; try - SList.Text := Content; + SList.Text := Item.Content; + //1s–Ú‚ðíœ if SList.Count > 1 then SList.Delete(0); - Result := SList.Text; + Item.Content := SList.Text; + //‰üsƒR[ƒh‚ðCRLF -> LF‚ƍl‚¦‚āAs”•ª‚¾‚¯ƒ}ƒCƒiƒX + Item.ContentLength := Length(SList.Text) - SList.Count; finally SList.Free; end; @@ -884,58 +913,64 @@ var i: Integer; index: Integer; NewItem: TThreadItem; -// SaveCount: Integer; NumCount: Integer; Body: TStringList; Rec: TSubjectRec; + {$IFDEF DEBUG} + st, rt : Cardinal; + {$ENDIF} function MakeThreadCallBack( - inInstance : DWORD; // TBoardItem ‚̃Cƒ“ƒXƒ^ƒ“ƒX + inInstance : DWORD; // TBoardItem ‚̃Cƒ“ƒXƒ^ƒ“ƒX inURL : PChar; // ƒXƒŒƒbƒh‚Ì URL inTitle : PChar; // ƒXƒŒƒ^ƒC inCount : DWORD // ƒŒƒX‚̐” ) : Boolean; stdcall; // —ñ‹“‚𑱂¯‚é‚È‚ç True - var - threadItem : TThreadItem; - boardItem : TBoard; - begin - Result := True; - boardItem := TBoard( inInstance ); - - boardItem.IntData := boardItem.IntData + 1; - // ¦ì‚è“r’†B–{“–‚Í URL ‚Å‚Í‚È‚­ FileName ‚ðˆø”‚ÉŽæ‚遦 - index := boardItem.GetIndex( string( inURL ) ); - if index = -1 then begin - //V‚µ‚¢ƒXƒŒƒbƒh - threadItem := TThreadItem.Create( boardItem.BoardPlugIn, string( inURL ) ); - - threadItem.Title := string( inTitle ); -// threadItem.Count := inCount; - threadItem.ParentBoard := Board; - threadItem.No := boardItem.IntData; - threadItem.RoundDate := ZERO_DATE; - threadItem.LastModified := ZERO_DATE; - threadItem.AgeSage := gasNew; - boardItem.ListData.Add( threadItem ); - end else begin - //boardItem.Items[index].Count := Count; - //boardItem.Items[index].Count := Rec.FCount; - if boardItem.Items[index].No > boardItem.IntData then - boardItem.Items[index].AgeSage := gasAge - else if boardItem.Items[index].AllResCount < inCount then - boardItem.Items[index].AgeSage := gasSage - else - boardItem.Items[index].AgeSage := gasNone; - - boardItem.Items[index].No := boardItem.IntData; - boardItem.Items[index].AllResCount := inCount; -// if not boardItem.Items[index].IsLogFile then -// boardItem.Items[index].Count := inCountt; - boardItem.ListData.Add( boardItem.Items[index] ); - boardItem.DeleteList( index ); - end; - end; + var + _ThreadItem : TThreadItem; // '_' ‚̓Nƒ‰ƒX‚̃vƒƒpƒeƒB‚Æ‚©‚Ô‚Á‚Ä‚é‚Ì‚Å + boardItem : TBoard; + begin + Result := True; + boardItem := TBoard( inInstance ); + + boardItem.IntData := boardItem.IntData + 1; + if boardItem.IntData < (boardItem.Count shr 2) then + index := boardItem.GetIndexFromURL( string( inURL ) ) + else + index := boardItem.GetIndexFromURL( string( inURL ), True ); + if index = -1 then begin + //V‚µ‚¢ƒXƒŒƒbƒh + _ThreadItem := TThreadItem.Create( boardItem.BoardPlugIn, boardItem, string( inURL ) ); + + _ThreadItem.Title := string( inTitle ); + _ThreadItem.AllResCount := inCount; + _ThreadItem.ParentBoard := Board; + _ThreadItem.No := boardItem.IntData; + _ThreadItem.RoundDate := ZERO_DATE; + _ThreadItem.LastModified := ZERO_DATE; + _ThreadItem.AgeSage := gasNew; + boardItem.Add(_ThreadItem); + end else begin + //‡ˆÊ‚ªã‚ª‚Á‚Ä‚¢‚ê‚ÎAge‚É‚·‚é + if boardItem.Items[index].No > boardItem.IntData then + boardItem.Items[index].AgeSage := gasAge + //‡ˆÊ‚ªã‚ª‚Á‚Ä‚È‚¢‚¯‚ǁAƒŒƒX‚ª‚‚¢‚Ä‚½‚çASage‚É + else if boardItem.Items[index].AllResCount <> inCount then + boardItem.Items[index].AgeSage := gasSage + //‡ˆÊã‚ª‚Á‚Ä‚È‚¢‚µAƒŒƒX‚Ì‘Œ¸‚à–³‚¯‚ê‚΁ANone + else + boardItem.Items[index].AgeSage := gasNone; + + boardItem.Items[index].No := boardItem.IntData; + boardItem.Items[index].AllResCount := inCount; + end; + + end; begin - Board.ListData := TList.Create; +{$IFDEF DEBUG} + st := GetTickCount; + Writeln('SAVELIST'); +{$ENDIF} + //Board.ListData := TList.Create; Body := TStringList.Create; try //ƒ_ƒEƒ“ƒ[ƒh“úŽžÝ’èiƒ[ƒJƒ‹“úŽžj @@ -943,109 +978,124 @@ begin //ƒT[ƒoãƒtƒ@ƒCƒ‹‚̍XVŽžÝ’è Board.LastModified := LastModified; - if Board.IsBoardPlugInAvailable then begin - // V‚µ‚¢ƒŠƒXƒg‚ðì¬‚·‚é - // V‚µ‚¢ƒŠƒXƒg‚Ɍ¢ƒŠƒXƒg‚̃ƒO‚ª‚ ‚é‚È‚ç‚»‚ê‚ðV‚µ‚¢ƒŠƒXƒg‚ɒljÁ - // ŒÃ‚¢ƒƒO‚ª‚È‚¯‚ê‚΁AV‚½‚ɃXƒŒƒIƒuƒWƒFƒNƒg‚ðì¬ - Board.IntData := 0; - Board.BoardPlugIn.EnumThread( DWORD( Board ), @MakeThreadCallBack ); - - // V‚µ‚¢ƒŠƒXƒg‚É–³‚©‚Á‚½ƒAƒCƒeƒ€‚ðV‚µ‚¢ƒŠƒXƒg‚ɒljÁ - for i := 0 to Board.Count - 1 do begin - if Board.Items[i].IsLogFile then begin - Board.IntData := Board.IntData + 1; - Board.Items[i].No := Board.IntData; - Board.Items[i].AllResCount := Board.Items[i].Count; - Board.Items[i].NewResCount := 0; - Board.Items[i].AgeSage := gasNone; - Board.ListData.Add( Board.Items[i] ); - end; - end; - - // ŒÃ‚¢ƒŠƒXƒg‚ðÁ‚·iƒŠƒXƒg‚̂݁BƒXƒŒƒIƒuƒWƒFƒNƒgŽ©‘̂͏Á‚³‚È‚¢j - for i := Board.Count - 1 downto 0 do - Board.DeleteList( i ); - - // V‚µ‚¢ƒŠƒXƒg‚ðƒ{[ƒhƒIƒuƒWƒFƒNƒg‚ɒljÁ - for i := 0 to Board.ListData.Count - 1 do - Board.Add( TThreadItem(Board.ListData[i]) ); - end else begin - //V‚µ‚¢ƒŠƒXƒg‚ðì¬‚·‚é - //V‚µ‚¢ƒŠƒXƒg‚Ɍ¢ƒŠƒXƒg‚̃ƒO‚ª‚ ‚é‚È‚ç‚»‚ê‚ðV‚µ‚¢ƒŠƒXƒg‚ɒljÁ - //ŒÃ‚¢ƒƒO‚ª‚È‚¯‚ê‚΁AV‚½‚ɃXƒŒƒIƒuƒWƒFƒNƒg‚ðì¬ - Body.Text := Content; - NumCount := 0; - for i := 0 to Body.Count - 1 do begin - //if i = 0 then Continue; //‚Ps–ڂ̓Xƒe[ƒ^ƒXs‚Ì‚½‚ߏˆ—‚È‚µ - - Rec := GikoSys.DivideSubject(Body[i]); - Rec.FFileName := Trim(Rec.FFileName); - if (Rec.FTitle = '') and (Rec.FCount = 0) then Continue; - Inc(NumCount); - index := Board.GetIndex(Rec.FFileName); - if index = -1 then begin - //V‚µ‚¢ƒXƒŒƒbƒh - NewItem := TThreadItem.Create; - NewItem.FileName := Rec.FFileName; - NewItem.Title := Rec.FTitle; - // NewItem.Count := Rec.FCount; - NewItem.AllResCount := Rec.FCount; - NewItem.ParentBoard := Board; - NewItem.No := NumCount; - NewItem.RoundDate := ZERO_DATE; - NewItem.LastModified := ZERO_DATE; - NewItem.AgeSage := gasNew; - Board.ListData.Add(NewItem); - end else begin - //Board.Items[index].Count := Count; - //Board.Items[index].Count := Rec.FCount; - if Board.Items[index].No > NumCount then - Board.Items[index].AgeSage := gasAge - else if Board.Items[index].AllResCount < Rec.FCount then - Board.Items[index].AgeSage := gasSage - else - Board.Items[index].AgeSage := gasNone; - - - Board.Items[index].No := NumCount; - Board.Items[index].AllResCount := Rec.FCount; - // if not Board.Items[index].IsLogFile then - // Board.Items[index].Count := Rec.FCount; - Board.ListData.Add(Board.Items[index]); - Board.DeleteList(index); - end; - end; - - //V‚µ‚¢ƒŠƒXƒg‚É–³‚©‚Á‚½ƒAƒCƒeƒ€‚ðV‚µ‚¢ƒŠƒXƒg‚ɒljÁ - for i := 0 to Board.Count - 1 do begin - if Board.Items[i].IsLogFile then begin - inc(NumCount); - Board.Items[i].No := NumCount; - Board.Items[i].AllResCount := Board.Items[i].Count; - Board.Items[i].NewResCount := 0; - Board.Items[i].AgeSage := gasNone; - Board.ListData.Add(Board.Items[i]); - end; - end; - - //ŒÃ‚¢ƒŠƒXƒg‚ðÁ‚·iƒŠƒXƒg‚̂݁BƒXƒŒƒIƒuƒWƒFƒNƒgŽ©‘̂͏Á‚³‚È‚¢j - for i := Board.Count - 1 downto 0 do - Board.DeleteList(i); - - //V‚µ‚¢ƒŠƒXƒg‚ðƒ{[ƒhƒIƒuƒWƒFƒNƒg‚ɒljÁ - for i := 0 to Board.ListData.Count - 1 do - Board.Add(TThreadItem(Board.ListData[i])); - - //ƒŠƒXƒg(subject.txt)‚ð•Û‘¶ - // GikoSys.ForceDirectoriesEx(GikoSys.GetLogDir + Board.BBSID); - // Body.SaveToFile(GikoSys.GetSubjectFileName(Board.BBSID)); - GikoSys.ForceDirectoriesEx(ExtractFilePath(Board.GetSubjectFileName)); - Body.SaveToFile(Board.GetSubjectFileName); - end; + + //dat—Ž‚¿ƒXƒŒ‚̃\[ƒg‡‚ðŒˆ’è‚·‚邽‚߂Ƀ\[ƒg‚·‚é + if GikoSys.Setting.DatOchiSortIndex >= 0 then begin + Sort.SetSortNoFlag(true); + Sort.SetSortOrder(GikoSys.Setting.DatOchiSortOrder); + Sort.SetSortIndex(GikoSys.Setting.DatOchiSortIndex); + //Sort.SortNonAcquiredCountFlag := GikoSys.Setting.NonAcquiredCount; + Board.CustomSort(ThreadItemSortProc); + end; + +{$IFDEF DEBUG} + rt := GetTickCount - st; + Writeln('END Sortd' + IntToStr(rt) + ' ms'); +{$ENDIF} + + for i := Board.Count - 1 downto 0 do + Board.Items[i].AgeSage := gasNull; + + if Board.IsBoardPlugInAvailable then begin + // V‚µ‚¢ƒŠƒXƒg‚ðì¬‚·‚é + // V‚µ‚¢ƒŠƒXƒg‚Ɍ¢ƒŠƒXƒg‚̃ƒO‚ª‚ ‚é‚È‚ç‚»‚ê‚ðV‚µ‚¢ƒŠƒXƒg‚ɒljÁ + // ŒÃ‚¢ƒƒO‚ª‚È‚¯‚ê‚΁AV‚½‚ɃXƒŒƒIƒuƒWƒFƒNƒg‚ðì¬ + Board.IntData := 0; +{$IFDEF DEBUG} + rt := GetTickCount - st; + Writeln('Start Enum' + IntToStr(rt) + ' ms'); +{$ENDIF} + + //‚±‚ꂪ’x‚¢@—v‰ü‘P + Board.BeginUpdate; + Board.BoardPlugIn.EnumThread( DWORD( Board ), @MakeThreadCallBack ); + Board.EndUpdate; + +{$IFDEF DEBUG} + rt := GetTickCount - st; + Writeln('End Enum' + IntToStr(rt) + ' ms'); +{$ENDIF} + + //ŒÃ‚¢ƒŠƒXƒg‚É‚µ‚©‚È‚¢‚â‚‚ç‚ðíœ + for i := Board.Count - 1 downto 0 do begin + if( Board.Items[i].AgeSage = gasNull )and not (Board.Items[i].IsLogFile) then + Board.Delete(i); + end; + + // V‚µ‚¢ƒŠƒXƒg‚É–³‚©‚Á‚½ƒAƒCƒeƒ€‚ðV‚µ‚¢ƒŠƒXƒg‚ɒljÁ + for i := 0 to Board.Count - 1 do begin + if(Board.Items[i].AgeSage = gasNull) and (Board.Items[i].IsLogFile) then begin + Board.IntData := Board.IntData + 1; + Board.Items[i].No := Board.IntData; + Board.Items[i].AllResCount := Board.Items[i].Count; + Board.Items[i].NewResCount := 0; + Board.Items[i].AgeSage := gasArch; + end; + end; + + end else begin + //V‚µ‚¢ƒŠƒXƒg‚ðì¬‚·‚é + //V‚µ‚¢ƒŠƒXƒg‚Ɍ¢ƒŠƒXƒg‚̃ƒO‚ª‚ ‚é‚È‚ç‚»‚ê‚ðV‚µ‚¢ƒŠƒXƒg‚ɒljÁ + //ŒÃ‚¢ƒƒO‚ª‚È‚¯‚ê‚΁AV‚½‚ɃXƒŒƒIƒuƒWƒFƒNƒg‚ðì¬ + Body.Text := Content; + NumCount := 0; + for i := 0 to Body.Count - 1 do begin + Rec := GikoSys.DivideSubject(Body[i]); + Rec.FFileName := Trim(Rec.FFileName); + if (Rec.FTitle = '') and (Rec.FCount = 0) then Continue; + Inc(NumCount); + index := Board.GetIndexFromFileName(Rec.FFileName); + if index = -1 then begin + //V‚µ‚¢ƒXƒŒƒbƒh + NewItem := TThreadItem.Create( + nil, + Board, + GikoSys.Get2chBoard2ThreadURL( Board, ChangeFileExt( Rec.FFileName, '' ) ) ); + NewItem.Title := Rec.FTitle; + NewItem.AllResCount := Rec.FCount; + NewItem.ParentBoard := Board; + NewItem.No := NumCount; + NewItem.RoundDate := ZERO_DATE; + NewItem.LastModified := ZERO_DATE; + NewItem.AgeSage := gasNew; + Board.Add(NewItem); + end else begin + if Board.Items[index].No > NumCount then + Board.Items[index].AgeSage := gasAge + else if Board.Items[index].AllResCount < Rec.FCount then + Board.Items[index].AgeSage := gasSage + else + Board.Items[index].AgeSage := gasNone; + + Board.Items[index].No := NumCount; + Board.Items[index].AllResCount := Rec.FCount; + end; + end; + //ŒÃ‚¢ƒŠƒXƒg‚̍폜 + for i := Board.Count - 1 downto 0 do begin + if( Board.Items[i].AgeSage = gasNull )and not (Board.Items[i].IsLogFile) then + Board.Delete(i); + end; + + //V‚µ‚¢ƒŠƒXƒg‚É–³‚©‚Á‚½ƒAƒCƒeƒ€‚̍XV + for i := 0 to Board.Count - 1 do begin + if( Board.Items[i].AgeSage = gasNull )and (Board.Items[i].IsLogFile) then begin + inc(NumCount); + Board.Items[i].No := NumCount; + Board.Items[i].AllResCount := Board.Items[i].Count; + Board.Items[i].NewResCount := 0; + Board.Items[i].AgeSage := gasArch; + end; + end; + //ƒŠƒXƒg(subject.txt)‚ð•Û‘¶ + GikoSys.ForceDirectoriesEx(ExtractFilePath(Board.GetSubjectFileName)); + Body.SaveToFile(Board.GetSubjectFileName); + end; finally Body.Free; - Board.ListData.Free; end; + + end; {procedure TDownloadItem.SaveListFile; @@ -1135,66 +1185,136 @@ end; } procedure TDownloadItem.SaveItemFile; var - Body: TStringList; + Body, oldBody: TStringList; Cnt: Integer; OldCnt: Integer; FileName: string; ini: TMemIniFile; Res: TResRec; NewRes: Integer; + finish : Boolean; + loopCnt : Integer; + LastIdx : Integer; begin - if Trim(Content) = '' then - Exit; FileName := ThreadItem.GetThreadFileName; - GikoSys.ForceDirectoriesEx(ExtractFilePath(FileName)); -// Cnt := 0; - Body := TStringList.Create; - try -// if FileExists(FileName) and (ResponseCode = 206) then begin - if FileExists(FileName) and (State = gdsDiffComplete) then begin -// Body.Text := Content; -// if Body.Count > 0 then -// Body.Delete(0); -// Content := Body.Text; - Body.LoadFromFile(FileName); - OldCnt := Body.Count; - Body.Text := Body.Text + Content; - Body.SaveToFile(FileName); - NewRes := Body.Count - OldCnt; - Cnt := Body.Count; - end else begin - Body.Text := Content; -// if Body.Count > 0 then -// Body.Delete(0); - Body.SaveToFile(FileName); + //if not ThreadItem.IsBoardPlugInAvailable then begin + if not ThreadItem.ParentBoard.IsBoardPlugInAvailable then begin + if Trim(Content) = '' then + Exit; - if ThreadItem.Title = '' then begin - Res := GikoSys.DivideStrLine(Body[0]); - ThreadItem.Title := Res.FTitle; + GikoSys.ForceDirectoriesEx(ExtractFilePath(FileName)); + + // Cnt := 0; + Body := TStringList.Create; + NewRes := 0; + OldCnt := 0; + try + // if FileExists(FileName) and (ResponseCode = 206) then begin + if FileExists(FileName) and (State = gdsDiffComplete) then begin + loopCnt := 10; + repeat + finish := true; + try + Body.LoadFromFile(FileName); + OldCnt := Body.Count; + Body.Text := Body.Text + Content; + Body.SaveToFile(FileName); + NewRes := Body.Count - OldCnt; + except + on E:EFOpenError do begin + sleep(10); + Dec(loopCnt); + if loopCnt > 0 then + finish := false; + end; + end; + until finish; + //Cnt := Body.Count; + end else begin + if IsAbone then begin + // ‚ ‚ځ[‚ñ‚ðŒŸo‚µ‚½‚Ì‚Å‚±‚±‚Ü‚Å“Ç‚ñ‚¾‚ƐV’…ƒŒƒX”Ԃ̂‚¯‚È‚¨‚µ + oldBody := TStringList.Create; + try + loopCnt := 10; + repeat + finish := true; + try + oldBody.LoadFromFile(FileName); + except + on E:EFOpenError do begin + sleep(10); + Dec(loopCnt); + if loopCnt > 0 then + finish := false + else + finish := true; + end; + end; + until finish; + + Body.Text := Content; + if (ThreadItem.Kokomade > 0) and (ThreadItem.Kokomade <= oldBody.Count) then begin + ThreadItem.Kokomade := Body.IndexOf(oldBody.Strings[ ThreadItem.Kokomade - 1 ]); + if ThreadItem.Kokomade <> -1 then ThreadItem.Kokomade := ThreadItem.Kokomade + 1; + end; + + LastIdx := oldBody.Count; + repeat + Dec(LastIdx); + OldCnt := Body.IndexOf(oldBody.Strings[ LastIdx ]) + 1; + until ( OldCnt <> 0 ) or (LastIdx = 0); + + if OldCnt >= Body.Count then OldCnt := Body.Count - 1; + NewRes := Body.Count - OldCnt; + + // ‚±‚±‚Ü‚Å“Ç‚ñ‚¾‚ªV’…ƒŒƒX”Ô‚ð’´‚³‚È‚¢‚悤‚É(ˆÙíI—¹Žž‚̃ŠƒJƒoƒŠ) + if ThreadItem.Kokomade > OldCnt then begin + if OldCnt > 0 then + ThreadItem.Kokomade := OldCnt + else + ThreadItem.Kokomade := 1; + end; + + finally + oldBody.Free; + end; + + end else begin + Body.Text := Content; + //ThreadItem.Count := 0; + OldCnt := 0; + NewRes := Body.Count; + //Cnt := Body.Count; + end; + // if Body.Count > 0 then + // Body.Delete(0); + Body.SaveToFile(FileName); + + if ThreadItem.Title = '' then begin + THTMLCreate.DivideStrLine(Body[0], @Res); + ThreadItem.Title := Res.FTitle; + end; + ThreadItem.Size := 0; end; - ThreadItem.Size := 0; - //ThreadItem.Count := 0; - ThreadItem.AllResCount := 0; - ThreadItem.NewResCount := 0; - OldCnt := 0; - NewRes := Body.Count; Cnt := Body.Count; + finally + Body.Free; end; - Cnt := Body.Count; - finally - Body.Free; + + ThreadItem.Size := ThreadItem.Size + ContentLength; + ThreadItem.LastModified := LastModified; + ThreadItem.Count := Cnt; + //ThreadItem.AllResCount := Cnt; + ThreadItem.NewResCount := NewRes; + ThreadItem.NewReceive := OldCnt + 1; end; - ThreadItem.RoundDate := Now; - ThreadItem.Size := ThreadItem.Size + ContentLength; - ThreadItem.LastModified := LastModified; - ThreadItem.Count := Cnt; - ThreadItem.AllResCount := Cnt; - ThreadItem.NewResCount := NewRes; + ThreadItem.AllResCount := ThreadItem.Count; ThreadItem.IsLogFile := True; - ThreadItem.NewReceive := OldCnt + 1; - ThreadItem.UnRead := True; - ThreadItem.ParentBoard.UnRead := ThreadItem.ParentBoard.UnRead + 1; + ThreadItem.RoundDate := Now; + if not ThreadItem.UnRead then begin + ThreadItem.UnRead := True; + end; // if ThreadItem.RoundNo = 6 then // ThreadItem.RoundNo := 0; @@ -1211,7 +1331,7 @@ begin ini.WriteInteger('Setting', 'NewResCount', ThreadItem.NewResCount); ini.WriteInteger('Setting', 'NewReceive', ThreadItem.NewReceive); // ini.WriteInteger('Setting', 'RoundNo', ThreadItem.RoundNo); - ini.WriteBool('Setting', 'Round', ThreadItem.Round); +// ini.WriteBool('Setting', 'Round', ThreadItem.Round); ini.WriteBool('Setting', 'UnRead', ThreadItem.UnRead); ini.UpdateFile; finally