| 3 |
interface |
interface |
| 4 |
|
|
| 5 |
uses |
uses |
| 6 |
SysUtils, Classes, ComCtrls, Controls, Forms, IdHTTP, |
Windows, SysUtils, Classes, ComCtrls, Controls, Forms, IdHTTP, |
| 7 |
{HTTPApp,} YofUtils, IdGlobal, IdException, IdComponent, IniFiles, {DateUtils,} |
{HTTPApp,} YofUtils, IdGlobal, IdException, IdComponent, IniFiles, {DateUtils,} |
| 8 |
GikoSystem, BoardGroup, MonaUtils; |
GikoSystem, BoardGroup, MonaUtils, ExternalBoardManager; |
| 9 |
|
|
| 10 |
type |
type |
| 11 |
TDownloadItem = class; |
TDownloadItem = class; |
| 15 |
TGikoDLProgress = (gdpStd, gdpAll, gdpDatOchi, gdpOfflaw); |
TGikoDLProgress = (gdpStd, gdpAll, gdpDatOchi, gdpOfflaw); |
| 16 |
|
|
| 17 |
TGikoWorkEvent = procedure(Sender: TObject; AWorkMode: TWorkMode; const AWorkCount: Integer; ID: Integer) of object; |
TGikoWorkEvent = procedure(Sender: TObject; AWorkMode: TWorkMode; const AWorkCount: Integer; ID: Integer) of object; |
| 18 |
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; |
| 19 |
TGikoWorkEndEvent = procedure(Sender: TObject; AWorkMode: TWorkMode; ID: Integer) of object; |
TGikoWorkEndEvent = procedure(Sender: TObject; AWorkMode: TWorkMode; ID: Integer) of object; |
| 20 |
TDownloadEndEvent = procedure(Sender: TObject; Item: TDownloadItem) of object; |
TDownloadEndEvent = procedure(Sender: TObject; Item: TDownloadItem) of object; |
| 21 |
TDownloadMsgEvent = procedure(Sender: TObject; Item: TDownloadItem; Msg: string; Icon: TGikoMessageIcon) of object; |
TDownloadMsgEvent = procedure(Sender: TObject; Item: TDownloadItem; Msg: string; Icon: TGikoMessageIcon) of object; |
| 41 |
FOnWorkEnd: TGikoWorkEndEvent; |
FOnWorkEnd: TGikoWorkEndEvent; |
| 42 |
FOnDownloadEnd: TDownloadEndEvent; |
FOnDownloadEnd: TDownloadEndEvent; |
| 43 |
FOnDownloadMsg: TDownloadMsgEvent; |
FOnDownloadMsg: TDownloadMsgEvent; |
| 44 |
|
FDownloadTitle: string; |
| 45 |
|
|
| 46 |
procedure FireDownloadEnd; |
procedure FireDownloadEnd; |
| 47 |
procedure FireDownloadMsg; |
procedure FireDownloadMsg; |
| 50 |
procedure WorkEnd(Sender: TObject; AWorkMode: TWorkMode); |
procedure WorkEnd(Sender: TObject; AWorkMode: TWorkMode); |
| 51 |
procedure Work(Sender: TObject; AWorkMode: TWorkMode; const AWorkCount: Integer); |
procedure Work(Sender: TObject; AWorkMode: TWorkMode; const AWorkCount: Integer); |
| 52 |
function ParseCgiStatus(Content: string): TCgiStatus; |
function ParseCgiStatus(Content: string): TCgiStatus; |
| 53 |
function CgiDownload(ItemType: TGikoDownloadType; URL: string; Modified: TDateTime): Boolean; |
function CgiDownload(ItemType: TGikoDownloadType; URL: string; Modified: TDateTime): Boolean; |
| 54 |
function DatDownload(ItemType: TGikoDownloadType; URL: string; Modified: TDateTime; RangeStart: Integer; AdjustLen: Integer): Boolean; |
function DatDownload(ItemType: TGikoDownloadType; URL: string; Modified: TDateTime; RangeStart: Integer; AdjustLen: Integer): Boolean; |
| 55 |
function DeleteStatusLine(Content: string): string; |
function DeleteStatusLine(Content: string): string; |
| 56 |
protected |
protected |
| 59 |
property Item: TDownloadItem read FItem write FItem; |
property Item: TDownloadItem read FItem write FItem; |
| 60 |
property Number: Integer read FNumber write FNumber; |
property Number: Integer read FNumber write FNumber; |
| 61 |
constructor Create(CreateSuspended: Boolean); |
constructor Create(CreateSuspended: Boolean); |
| 62 |
destructor Destroy; override; |
destructor Destroy; override; |
| 63 |
procedure Abort; |
procedure Abort; |
| 64 |
property OnWork: TGikoWorkEvent read FOnWork write FOnWork; |
property OnWork: TGikoWorkEvent read FOnWork write FOnWork; |
| 65 |
property OnWorkBegin: TGikoWorkBeginEvent read FOnWorkBegin write FOnWorkBegin; |
property OnWorkBegin: TGikoWorkBeginEvent read FOnWorkBegin write FOnWorkBegin; |
| 110 |
|
|
| 111 |
destructor TDownloadThread.Destroy; |
destructor TDownloadThread.Destroy; |
| 112 |
begin |
begin |
| 113 |
|
FIndy.Request.CustomHeaders.Clear; |
| 114 |
|
FIndy.Request.RawHeaders.Clear; |
| 115 |
|
FIndy.Request.Clear; |
| 116 |
|
FIndy.Response.CustomHeaders.Clear; |
| 117 |
|
FIndy.Response.RawHeaders.Clear; |
| 118 |
|
FIndy.Response.Clear; |
| 119 |
|
FIndy.ProxyParams.Clear; |
| 120 |
|
|
| 121 |
FIndy.Free; |
FIndy.Free; |
| 122 |
inherited; |
inherited; |
| 123 |
end; |
end; |
| 125 |
function RFC1123_Date(aDate : TDateTime) : String; |
function RFC1123_Date(aDate : TDateTime) : String; |
| 126 |
const |
const |
| 127 |
StrWeekDay : String = 'MonTueWedThuFriSatSun'; |
StrWeekDay : String = 'MonTueWedThuFriSatSun'; |
| 128 |
StrMonth : String = 'JanFebMarAprMayJunJulAugSepOctNovDec'; |
StrMonth : String = 'JanFebMarAprMayJunJulAugSepOctNovDec'; |
| 129 |
var |
var |
| 130 |
Year, Month, Day : Word; |
Year, Month, Day : Word; |
| 131 |
Hour, Min, Sec, MSec : Word; |
Hour, Min, Sec, MSec : Word; |
| 132 |
DayOfWeek : Word; |
DayOfWeek : Word; |
| 133 |
begin |
begin |
| 134 |
DecodeDate(aDate, Year, Month, Day); |
DecodeDate(aDate, Year, Month, Day); |
| 135 |
DecodeTime(aDate, Hour, Min, Sec, MSec); |
DecodeTime(aDate, Hour, Min, Sec, MSec); |
| 136 |
DayOfWeek := ((Trunc(aDate) - 2) mod 7); |
DayOfWeek := ((Trunc(aDate) - 2) mod 7); |
| 137 |
Result := Copy(StrWeekDay, 1 + DayOfWeek * 3, 3) + ', ' + |
Result := Copy(StrWeekDay, 1 + DayOfWeek * 3, 3) + ', ' + |
| 138 |
Format('%2.2d %s %4.4d %2.2d:%2.2d:%2.2d', |
Format('%2.2d %s %4.4d %2.2d:%2.2d:%2.2d', |
| 153 |
ATitle: string; |
ATitle: string; |
| 154 |
DownloadResult: Boolean; |
DownloadResult: Boolean; |
| 155 |
Abone: Boolean; |
Abone: Boolean; |
| 156 |
foundPos: Integer; |
foundPos: Integer; |
| 157 |
|
boardPlugIn : TBoardPlugIn; |
| 158 |
|
listContent : string; |
| 159 |
begin |
begin |
| 160 |
while not Terminated do begin |
while not Terminated do begin |
| 161 |
|
//===== プラグイン |
| 162 |
|
boardPlugIn := nil; |
| 163 |
|
ExternalBoardManager.OnWork := Work; |
| 164 |
|
ExternalBoardManager.OnWorkBegin := WorkBegin; |
| 165 |
|
ExternalBoardManager.OnWorkEnd := WorkEnd; |
| 166 |
|
|
| 167 |
|
FDownloadTitle := ''; |
| 168 |
|
case FItem.FDownType of |
| 169 |
|
gdtBoard: |
| 170 |
|
begin |
| 171 |
|
FDownloadTitle := FItem.FBoard.Title; |
| 172 |
|
if FItem.FBoard <> nil then begin |
| 173 |
|
if FItem.FBoard.IsBoardPlugInAvailable then begin |
| 174 |
|
boardPlugIn := FItem.FBoard.BoardPlugIn; |
| 175 |
|
Item.State := TGikoDownloadState( boardPlugIn.DownloadBoard( DWORD( FItem.FBoard ) ) ); |
| 176 |
|
end; |
| 177 |
|
end; |
| 178 |
|
end; |
| 179 |
|
gdtThread: |
| 180 |
|
begin |
| 181 |
|
FDownloadTitle := FItem.FThreadItem.Title; |
| 182 |
|
if FItem.FThreadItem <> nil then begin |
| 183 |
|
if FItem.FThreadItem.IsBoardPlugInAvailable then begin |
| 184 |
|
boardPlugIn := FItem.FThreadItem.BoardPlugIn; |
| 185 |
|
Item.State := TGikoDownloadState( boardPlugIn.DownloadThread( DWORD( FItem.FThreadItem ) ) ); |
| 186 |
|
end; |
| 187 |
|
end; |
| 188 |
|
end; |
| 189 |
|
end; |
| 190 |
|
if Length(FDownloadTitle) = 0 then |
| 191 |
|
FDownloadTitle := '(名称不明)'; |
| 192 |
|
|
| 193 |
|
if boardPlugIn <> nil then begin |
| 194 |
|
if FAbort then |
| 195 |
|
Item.State := gdsAbort; |
| 196 |
|
if Assigned( OnDownloadEnd ) then |
| 197 |
|
Synchronize( FireDownloadEnd ); |
| 198 |
|
if Terminated then |
| 199 |
|
Break; |
| 200 |
|
|
| 201 |
|
Suspend; |
| 202 |
|
Continue; |
| 203 |
|
end; |
| 204 |
|
|
| 205 |
|
//===== プラグインを使用しない場合 |
| 206 |
FAbort := False; |
FAbort := False; |
| 207 |
FIndy.Request.CustomHeaders.Clear; |
FIndy.Request.CustomHeaders.Clear; |
| 208 |
FIndy.Response.Clear; |
FIndy.Response.Clear; |
| 209 |
FIndy.Request.Clear; |
FIndy.Request.Clear; |
| 210 |
|
FIndy.ProxyParams.Clear; |
| 211 |
|
FIndy.Disconnect; |
| 212 |
FIndy.Request.UserAgent := GikoSys.GetUserAgent; |
FIndy.Request.UserAgent := GikoSys.GetUserAgent; |
| 213 |
FIndy.RecvBufferSize := Gikosys.Setting.RecvBufferSize; |
FIndy.RecvBufferSize := Gikosys.Setting.RecvBufferSize; |
| 214 |
FIndy.ProxyParams.BasicAuthentication := False; |
FIndy.ProxyParams.BasicAuthentication := False; |
| 319 |
AdjustLen := 0; |
AdjustLen := 0; |
| 320 |
FMsg := '★「あぼーん」を検出したので再取得を行います - [' + ATitle + ']'; |
FMsg := '★「あぼーん」を検出したので再取得を行います - [' + ATitle + ']'; |
| 321 |
FIcon := gmiWhat; |
FIcon := gmiWhat; |
| 322 |
if FileExists(ChangeFileExt(Item.FThreadItem.GetThreadFileName,'.NG')) = true then |
if FileExists(ChangeFileExt(Item.FThreadItem.GetThreadFileName,'.NG')) = true then |
| 323 |
DeleteFile(ChangeFileExt(Item.FThreadItem.GetThreadFileName,'.NG')); |
DeleteFile(ChangeFileExt(Item.FThreadItem.GetThreadFileName,'.NG')); |
| 324 |
if Assigned(OnDownloadMsg) then |
if Assigned(OnDownloadMsg) then |
| 325 |
Synchronize(FireDownloadMsg); |
Synchronize(FireDownloadMsg); |
| 326 |
if not DatDownload(Item.DownType, URL, ZERO_DATE, RangeStart, AdjustLen) then |
if not DatDownload(Item.DownType, URL, ZERO_DATE, RangeStart, AdjustLen) then |
| 468 |
Idx := Pos(' ', Item.ErrText); |
Idx := Pos(' ', Item.ErrText); |
| 469 |
if Idx <> 0 then begin |
if Idx <> 0 then begin |
| 470 |
URL := Copy(Item.ErrText, Idx + 1, Length(Item.ErrText)); |
URL := Copy(Item.ErrText, Idx + 1, Length(Item.ErrText)); |
| 471 |
if Pos('../', URL) = 1 then |
if Pos( '://', URL ) = 0 then begin |
| 472 |
URL := Copy(URL, 4, Length(URL)); |
if Pos('../', URL) = 1 then |
| 473 |
URL := GikoSys.UrlToServer(Item.ThreadItem.ParentBoard.URL) + URL; |
URL := Copy(URL, 4, MaxInt ); |
| 474 |
|
if Pos( '/', URL ) = 1 then |
| 475 |
|
URL := Copy( URL, 2, MaxInt ); |
| 476 |
|
URL := GikoSys.UrlToServer(Item.ThreadItem.ParentBoard.URL) + URL; |
| 477 |
|
end; |
| 478 |
Modified := Item.ThreadItem.LastModified; |
Modified := Item.ThreadItem.LastModified; |
| 479 |
RangeStart := 0; |
RangeStart := 0; |
| 480 |
AdjustLen := 0; |
AdjustLen := 0; |
| 501 |
end; |
end; |
| 502 |
end; |
end; |
| 503 |
|
|
|
{$IFDEF DEBUG} |
|
|
if (Item.DownType = gdtThread) and (Item.ResponseCode = 302) then begin |
|
|
ATitle := Item.ThreadItem.Title; |
|
|
if ATitle = '' then |
|
|
ATitle := '(名称不明)'; |
|
|
FMsg := '★過去ログ(1)が存在しないためgoogleキャッシュから探します - [' + 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( '<dt>', Item.Content ) + Length( '<dt>' ); |
|
|
Item.Content := Copy( Item.Content, foundPos, Length( Item.Content ) ); |
|
|
foundPos := Pos( '</dl>', Item.Content ); |
|
|
If foundPos > 0 Then |
|
|
Item.Content := Copy( Item.Content, 1, foundPos - 1 ); |
|
|
Item.Content := StringReplace( Item.Content, '<dt>', '<>' + #13#10, [rfReplaceAll] ); |
|
|
Item.Content := StringReplace( Item.Content, '<a href="mailto:', '', [rfReplaceAll] ); |
|
|
Item.Content := StringReplace( Item.Content, '"><b>', '<>', [rfReplaceAll] ); |
|
|
Item.Content := StringReplace( Item.Content, '<b>', '<>', [rfReplaceAll] ); |
|
|
Item.Content := StringReplace( Item.Content, '</b></a>', '<>', [rfReplaceAll] ); |
|
|
Item.Content := StringReplace( Item.Content, '</b>', '<>', [rfReplaceAll] ); |
|
|
Item.Content := StringReplace( Item.Content, '<dd>', '<>', [rfReplaceAll] ); |
|
|
end; |
|
|
end; |
|
|
{$ENDIF} |
|
|
|
|
| 504 |
case Item.ResponseCode of |
case Item.ResponseCode of |
| 505 |
200: Item.State := gdsComplete; |
200: Item.State := gdsComplete; |
| 506 |
206: Item.State := gdsDiffComplete; |
206: Item.State := gdsDiffComplete; |
| 577 |
Synchronize(FireDownloadEnd); |
Synchronize(FireDownloadEnd); |
| 578 |
ResStream.Free; |
ResStream.Free; |
| 579 |
end; |
end; |
| 580 |
|
|
| 581 |
|
FIndy.Request.CustomHeaders.Clear; |
| 582 |
|
FIndy.Request.RawHeaders.Clear; |
| 583 |
|
FIndy.Request.Clear; |
| 584 |
|
FIndy.Response.CustomHeaders.Clear; |
| 585 |
|
FIndy.Response.RawHeaders.Clear; |
| 586 |
|
FIndy.Response.Clear; |
| 587 |
|
FIndy.ProxyParams.Clear; |
| 588 |
|
|
| 589 |
if Terminated then Break; |
if Terminated then Break; |
| 590 |
Suspend; |
Suspend; |
| 591 |
end; |
end; |
| 605 |
FIndy.Request.LastModified := modified - OffsetFromUTC; |
FIndy.Request.LastModified := modified - OffsetFromUTC; |
| 606 |
end; |
end; |
| 607 |
FIndy.Request.AcceptEncoding := ''; |
FIndy.Request.AcceptEncoding := ''; |
| 608 |
FIndy.Request.Accept := 'text/html'; |
FIndy.Request.Accept := 'text/html'; |
| 609 |
ResStream := TMemoryStream.Create; |
ResStream := TMemoryStream.Create; |
| 610 |
try |
try |
| 611 |
try |
try |
| 635 |
Item.ErrText := E.Message; |
Item.ErrText := E.Message; |
| 636 |
Result := False; |
Result := False; |
| 637 |
ResponseCode := -1; |
ResponseCode := -1; |
| 638 |
Screen.Cursor := crDefault; |
Screen.Cursor := crDefault; |
| 639 |
end; |
end; |
| 640 |
on E: EIdConnectException do begin |
on E: EIdConnectException do begin |
| 641 |
Item.Content := ''; |
Item.Content := ''; |
| 644 |
Item.ErrText := E.Message; |
Item.ErrText := E.Message; |
| 645 |
Result := False; |
Result := False; |
| 646 |
ResponseCode := -1; |
ResponseCode := -1; |
| 647 |
Screen.Cursor := crDefault; |
Screen.Cursor := crDefault; |
| 648 |
end; |
end; |
| 649 |
on E: Exception do begin |
on E: Exception do begin |
| 650 |
{$IFDEF DEBUG} |
{$IFDEF DEBUG} |
| 657 |
Item.ErrText := E.Message; |
Item.ErrText := E.Message; |
| 658 |
ResponseCode := FIndy.ResponseCode; |
ResponseCode := FIndy.ResponseCode; |
| 659 |
Result := False; |
Result := False; |
| 660 |
Screen.Cursor := crDefault; |
Screen.Cursor := crDefault; |
| 661 |
end; |
end; |
| 662 |
end; |
end; |
| 663 |
finally |
finally |
| 729 |
Item.ErrText := E.Message; |
Item.ErrText := E.Message; |
| 730 |
Result := False; |
Result := False; |
| 731 |
ResponseCode := -1; |
ResponseCode := -1; |
| 732 |
Screen.Cursor := crDefault; |
Screen.Cursor := crDefault; |
| 733 |
end; |
end; |
| 734 |
on E: EIdConnectException do begin |
on E: EIdConnectException do begin |
| 735 |
Item.Content := ''; |
Item.Content := ''; |
| 738 |
Item.ErrText := E.Message; |
Item.ErrText := E.Message; |
| 739 |
Result := False; |
Result := False; |
| 740 |
ResponseCode := -1; |
ResponseCode := -1; |
| 741 |
Screen.Cursor := crDefault; |
Screen.Cursor := crDefault; |
| 742 |
end; |
end; |
| 743 |
on E: Exception do begin |
on E: Exception do begin |
| 744 |
{$IFDEF DEBUG} |
{$IFDEF DEBUG} |
| 751 |
Item.ErrText := E.Message; |
Item.ErrText := E.Message; |
| 752 |
ResponseCode := FIndy.ResponseCode; |
ResponseCode := FIndy.ResponseCode; |
| 753 |
Result := False; |
Result := False; |
| 754 |
Screen.Cursor := crDefault; |
Screen.Cursor := crDefault; |
| 755 |
end; |
end; |
| 756 |
end; |
end; |
| 757 |
finally |
finally |
| 787 |
procedure TDownloadThread.WorkBegin(Sender: TObject; AWorkMode: TWorkMode; const AWorkCountMax: Integer); |
procedure TDownloadThread.WorkBegin(Sender: TObject; AWorkMode: TWorkMode; const AWorkCountMax: Integer); |
| 788 |
begin |
begin |
| 789 |
if Assigned(OnWorkBegin) then |
if Assigned(OnWorkBegin) then |
| 790 |
OnWorkBegin(Sender, AWorkMode, AWorkCountMax, FNumber); |
OnWorkBegin(Sender, AWorkMode, AWorkCountMax, FNumber, FDownloadTitle); |
| 791 |
end; |
end; |
| 792 |
|
|
| 793 |
procedure TDownloadThread.WorkEnd(Sender: TObject; AWorkMode: TWorkMode); |
procedure TDownloadThread.WorkEnd(Sender: TObject; AWorkMode: TWorkMode); |
| 815 |
// [-INCR] (Incorrect)の場合はすべてのデータ |
// [-INCR] (Incorrect)の場合はすべてのデータ |
| 816 |
// [-ERR (テキスト)]の場合はなんかエラー |
// [-ERR (テキスト)]の場合はなんかエラー |
| 817 |
// 例:+OK 23094/512K |
// 例:+OK 23094/512K |
| 818 |
// -INCR 23094/512K |
// -INCR 23094/512K |
| 819 |
// -ERR そんな板ないです |
// -ERR そんな板ないです |
| 820 |
Idx := AnsiPos(#10, Content); |
Idx := AnsiPos(#10, Content); |
| 821 |
StatusLine := Copy(Content, 0, Idx); |
StatusLine := Copy(Content, 0, Idx); |
| 822 |
|
|
| 879 |
i: Integer; |
i: Integer; |
| 880 |
index: Integer; |
index: Integer; |
| 881 |
NewItem: TThreadItem; |
NewItem: TThreadItem; |
|
NewList: TList; |
|
| 882 |
// SaveCount: Integer; |
// SaveCount: Integer; |
| 883 |
NumCount: Integer; |
NumCount: Integer; |
| 884 |
Body: TStringList; |
Body: TStringList; |
| 885 |
Rec: TSubjectRec; |
Rec: TSubjectRec; |
| 886 |
|
function MakeThreadCallBack( |
| 887 |
|
inInstance : DWORD; // TBoardItem のインスタンス |
| 888 |
|
inURL : PChar; // スレッドの URL |
| 889 |
|
inTitle : PChar; // スレタイ |
| 890 |
|
inCount : DWORD // レスの数 |
| 891 |
|
) : Boolean; stdcall; // 列挙を続けるなら True |
| 892 |
|
var |
| 893 |
|
_ThreadItem : TThreadItem; // '_' はクラスのプロパティとかぶってるので |
| 894 |
|
boardItem : TBoard; |
| 895 |
|
begin |
| 896 |
|
Result := True; |
| 897 |
|
boardItem := TBoard( inInstance ); |
| 898 |
|
|
| 899 |
|
boardItem.IntData := boardItem.IntData + 1; |
| 900 |
|
index := boardItem.GetIndexFromURL( string( inURL ) ); |
| 901 |
|
if index = -1 then begin |
| 902 |
|
//新しいスレッド |
| 903 |
|
_ThreadItem := TThreadItem.Create( boardItem.BoardPlugIn, string( inURL ) ); |
| 904 |
|
|
| 905 |
|
_ThreadItem.Title := string( inTitle ); |
| 906 |
|
_ThreadItem.AllResCount := inCount; |
| 907 |
|
_ThreadItem.ParentBoard := Board; |
| 908 |
|
_ThreadItem.No := boardItem.IntData; |
| 909 |
|
_ThreadItem.RoundDate := ZERO_DATE; |
| 910 |
|
_ThreadItem.LastModified := ZERO_DATE; |
| 911 |
|
_ThreadItem.AgeSage := gasNew; |
| 912 |
|
boardItem.ListData.Add( _ThreadItem ); |
| 913 |
|
end else begin |
| 914 |
|
if boardItem.Items[index].No > boardItem.IntData then |
| 915 |
|
boardItem.Items[index].AgeSage := gasAge |
| 916 |
|
else if boardItem.Items[index].AllResCount < inCount then |
| 917 |
|
boardItem.Items[index].AgeSage := gasSage |
| 918 |
|
else |
| 919 |
|
boardItem.Items[index].AgeSage := gasNone; |
| 920 |
|
|
| 921 |
|
boardItem.Items[index].No := boardItem.IntData; |
| 922 |
|
boardItem.Items[index].AllResCount := inCount; |
| 923 |
|
boardItem.ListData.Add( boardItem.Items[index] ); |
| 924 |
|
boardItem.DeleteList( index ); |
| 925 |
|
end; |
| 926 |
|
end; |
| 927 |
begin |
begin |
| 928 |
NewList := TList.Create; |
Board.ListData := TList.Create; |
| 929 |
Body := TStringList.Create; |
Body := TStringList.Create; |
| 930 |
try |
try |
| 931 |
//ダウンロード日時設定(ローカル日時) |
//ダウンロード日時設定(ローカル日時) |
| 933 |
//サーバ上ファイルの更新時刻設定 |
//サーバ上ファイルの更新時刻設定 |
| 934 |
Board.LastModified := LastModified; |
Board.LastModified := LastModified; |
| 935 |
|
|
| 936 |
//新しいリストを作成する |
if Board.IsBoardPlugInAvailable then begin |
| 937 |
//新しいリストに古いリストのログがあるならそれを新しいリストに追加 |
// 新しいリストを作成する |
| 938 |
//古いログがなければ、新たにスレオブジェクトを作成 |
// 新しいリストに古いリストのログがあるならそれを新しいリストに追加 |
| 939 |
Body.Text := Content; |
// 古いログがなければ、新たにスレオブジェクトを作成 |
| 940 |
NumCount := 0; |
Board.IntData := 0; |
| 941 |
for i := 0 to Body.Count - 1 do begin |
Board.BoardPlugIn.EnumThread( DWORD( Board ), @MakeThreadCallBack ); |
| 942 |
//if i = 0 then Continue; //1行目はステータス行のため処理なし |
|
| 943 |
|
// 新しいリストに無かったアイテムを新しいリストに追加 |
| 944 |
Rec := GikoSys.DivideSubject(Body[i]); |
for i := 0 to Board.Count - 1 do begin |
| 945 |
Rec.FFileName := Trim(Rec.FFileName); |
if Board.Items[i].IsLogFile then begin |
| 946 |
if (Rec.FTitle = '') and (Rec.FCount = 0) then Continue; |
Board.IntData := Board.IntData + 1; |
| 947 |
Inc(NumCount); |
Board.Items[i].No := Board.IntData; |
| 948 |
index := Board.GetIndex(Rec.FFileName); |
Board.Items[i].AllResCount := Board.Items[i].Count; |
| 949 |
if index = -1 then begin |
Board.Items[i].NewResCount := 0; |
| 950 |
//新しいスレッド |
Board.Items[i].AgeSage := gasNone; |
| 951 |
NewItem := TThreadItem.Create; |
Board.ListData.Add( Board.Items[i] ); |
| 952 |
NewItem.FileName := Rec.FFileName; |
end; |
| 953 |
NewItem.Title := Rec.FTitle; |
end; |
|
// 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; |
|
|
NewList.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; |
|
| 954 |
|
|
| 955 |
|
// 古いリストを消す(リストのみ。スレオブジェクト自体は消さない) |
| 956 |
|
for i := Board.Count - 1 downto 0 do |
| 957 |
|
Board.DeleteList( i ); |
| 958 |
|
|
| 959 |
|
// 新しいリストをボードオブジェクトに追加 |
| 960 |
|
for i := 0 to Board.ListData.Count - 1 do |
| 961 |
|
Board.Add( TThreadItem(Board.ListData[i]) ); |
| 962 |
|
end else begin |
| 963 |
|
//新しいリストを作成する |
| 964 |
|
//新しいリストに古いリストのログがあるならそれを新しいリストに追加 |
| 965 |
|
//古いログがなければ、新たにスレオブジェクトを作成 |
| 966 |
|
Body.Text := Content; |
| 967 |
|
NumCount := 0; |
| 968 |
|
for i := 0 to Body.Count - 1 do begin |
| 969 |
|
//if i = 0 then Continue; //1行目はステータス行のため処理なし |
| 970 |
|
|
| 971 |
|
Rec := GikoSys.DivideSubject(Body[i]); |
| 972 |
|
Rec.FFileName := Trim(Rec.FFileName); |
| 973 |
|
if (Rec.FTitle = '') and (Rec.FCount = 0) then Continue; |
| 974 |
|
Inc(NumCount); |
| 975 |
|
index := Board.GetIndexFromFileName(Rec.FFileName); |
| 976 |
|
if index = -1 then begin |
| 977 |
|
//新しいスレッド |
| 978 |
|
NewItem := TThreadItem.Create( |
| 979 |
|
nil, GikoSys.Get2chBoard2ThreadURL( Board, ChangeFileExt( Rec.FFileName, '' ) ) ); |
| 980 |
|
NewItem.Title := Rec.FTitle; |
| 981 |
|
NewItem.AllResCount := Rec.FCount; |
| 982 |
|
NewItem.ParentBoard := Board; |
| 983 |
|
NewItem.No := NumCount; |
| 984 |
|
NewItem.RoundDate := ZERO_DATE; |
| 985 |
|
NewItem.LastModified := ZERO_DATE; |
| 986 |
|
NewItem.AgeSage := gasNew; |
| 987 |
|
Board.ListData.Add(NewItem); |
| 988 |
|
end else begin |
| 989 |
|
if Board.Items[index].No > NumCount then |
| 990 |
|
Board.Items[index].AgeSage := gasAge |
| 991 |
|
else if Board.Items[index].AllResCount < Rec.FCount then |
| 992 |
|
Board.Items[index].AgeSage := gasSage |
| 993 |
|
else |
| 994 |
|
Board.Items[index].AgeSage := gasNone; |
| 995 |
|
|
| 996 |
Board.Items[index].No := NumCount; |
Board.Items[index].No := NumCount; |
| 997 |
Board.Items[index].AllResCount := Rec.FCount; |
Board.Items[index].AllResCount := Rec.FCount; |
| 998 |
// if not Board.Items[index].IsLogFile then |
Board.ListData.Add(Board.Items[index]); |
| 999 |
// Board.Items[index].Count := Rec.FCount; |
Board.DeleteList(index); |
| 1000 |
NewList.Add(Board.Items[index]); |
end; |
|
Board.DeleteList(index); |
|
| 1001 |
end; |
end; |
|
end; |
|
| 1002 |
|
|
| 1003 |
//新しいリストに無かったアイテムを新しいリストに追加 |
//新しいリストに無かったアイテムを新しいリストに追加 |
| 1004 |
for i := 0 to Board.Count - 1 do begin |
for i := 0 to Board.Count - 1 do begin |
| 1005 |
if Board.Items[i].IsLogFile then begin |
if Board.Items[i].IsLogFile then begin |
| 1006 |
inc(NumCount); |
inc(NumCount); |
| 1007 |
Board.Items[i].No := NumCount; |
Board.Items[i].No := NumCount; |
| 1008 |
Board.Items[i].AllResCount := Board.Items[i].Count; |
Board.Items[i].AllResCount := Board.Items[i].Count; |
| 1009 |
Board.Items[i].NewResCount := 0; |
Board.Items[i].NewResCount := 0; |
| 1010 |
Board.Items[i].AgeSage := gasNone; |
Board.Items[i].AgeSage := gasNone; |
| 1011 |
NewList.Add(Board.Items[i]); |
Board.ListData.Add(Board.Items[i]); |
| 1012 |
|
end; |
| 1013 |
end; |
end; |
|
end; |
|
|
|
|
|
//古いリストを消す(リストのみ。スレオブジェクト自体は消さない) |
|
|
for i := Board.Count - 1 downto 0 do |
|
|
Board.DeleteList(i); |
|
| 1014 |
|
|
| 1015 |
//新しいリストをボードオブジェクトに追加 |
//古いリストを消す(リストのみ。スレオブジェクト自体は消さない) |
| 1016 |
for i := 0 to NewList.Count - 1 do |
for i := Board.Count - 1 downto 0 do |
| 1017 |
Board.Add(TThreadItem(NewList[i])); |
Board.DeleteList(i); |
| 1018 |
|
|
| 1019 |
//リスト(subject.txt)を保存 |
//新しいリストをボードオブジェクトに追加 |
| 1020 |
// GikoSys.ForceDirectoriesEx(GikoSys.GetLogDir + Board.BBSID); |
for i := 0 to Board.ListData.Count - 1 do |
| 1021 |
// Body.SaveToFile(GikoSys.GetSubjectFileName(Board.BBSID)); |
Board.Add(TThreadItem(Board.ListData[i])); |
| 1022 |
GikoSys.ForceDirectoriesEx(ExtractFilePath(Board.GetSubjectFileName)); |
|
| 1023 |
Body.SaveToFile(Board.GetSubjectFileName); |
//リスト(subject.txt)を保存 |
| 1024 |
|
// GikoSys.ForceDirectoriesEx(GikoSys.GetLogDir + Board.BBSID); |
| 1025 |
|
// Body.SaveToFile(GikoSys.GetSubjectFileName(Board.BBSID)); |
| 1026 |
|
GikoSys.ForceDirectoriesEx(ExtractFilePath(Board.GetSubjectFileName)); |
| 1027 |
|
Body.SaveToFile(Board.GetSubjectFileName); |
| 1028 |
|
end; |
| 1029 |
finally |
finally |
| 1030 |
Body.Free; |
Body.Free; |
| 1031 |
NewList.Free; |
Board.ListData.Free; |
| 1032 |
end; |
end; |
| 1033 |
end; |
end; |
| 1034 |
|
|
| 1126 |
ini: TMemIniFile; |
ini: TMemIniFile; |
| 1127 |
Res: TResRec; |
Res: TResRec; |
| 1128 |
NewRes: Integer; |
NewRes: Integer; |
| 1129 |
|
finish : Boolean; |
| 1130 |
|
loopCnt : Integer; |
| 1131 |
begin |
begin |
|
if Trim(Content) = '' then |
|
|
Exit; |
|
| 1132 |
FileName := ThreadItem.GetThreadFileName; |
FileName := ThreadItem.GetThreadFileName; |
|
GikoSys.ForceDirectoriesEx(ExtractFilePath(FileName)); |
|
| 1133 |
|
|
| 1134 |
// Cnt := 0; |
if not ThreadItem.IsBoardPlugInAvailable then begin |
| 1135 |
Body := TStringList.Create; |
if Trim(Content) = '' then |
| 1136 |
try |
Exit; |
| 1137 |
// if FileExists(FileName) and (ResponseCode = 206) then begin |
GikoSys.ForceDirectoriesEx(ExtractFilePath(FileName)); |
| 1138 |
if FileExists(FileName) and (State = gdsDiffComplete) then begin |
|
| 1139 |
// Body.Text := Content; |
// Cnt := 0; |
| 1140 |
// if Body.Count > 0 then |
Body := TStringList.Create; |
| 1141 |
// Body.Delete(0); |
NewRes := 0; |
| 1142 |
// Content := Body.Text; |
OldCnt := 0; |
| 1143 |
Body.LoadFromFile(FileName); |
try |
| 1144 |
OldCnt := Body.Count; |
// if FileExists(FileName) and (ResponseCode = 206) then begin |
| 1145 |
Body.Text := Body.Text + Content; |
if FileExists(FileName) and (State = gdsDiffComplete) then begin |
| 1146 |
Body.SaveToFile(FileName); |
// Body.Text := Content; |
| 1147 |
NewRes := Body.Count - OldCnt; |
// if Body.Count > 0 then |
| 1148 |
Cnt := Body.Count; |
// Body.Delete(0); |
| 1149 |
end else begin |
// Content := Body.Text; |
| 1150 |
Body.Text := Content; |
loopCnt := 10; |
| 1151 |
// if Body.Count > 0 then |
repeat |
| 1152 |
// Body.Delete(0); |
finish := true; |
| 1153 |
Body.SaveToFile(FileName); |
try |
| 1154 |
|
Body.LoadFromFile(FileName); |
| 1155 |
if ThreadItem.Title = '' then begin |
OldCnt := Body.Count; |
| 1156 |
Res := GikoSys.DivideStrLine(Body[0]); |
Body.Text := Body.Text + Content; |
| 1157 |
ThreadItem.Title := Res.FTitle; |
Body.SaveToFile(FileName); |
| 1158 |
|
NewRes := Body.Count - OldCnt; |
| 1159 |
|
except |
| 1160 |
|
on E:EFOpenError do begin |
| 1161 |
|
sleep(10); |
| 1162 |
|
finish := false; |
| 1163 |
|
Dec(loopCnt); |
| 1164 |
|
end; |
| 1165 |
|
end; |
| 1166 |
|
until finish and ( loopCnt > 0 ); |
| 1167 |
|
//Cnt := Body.Count; |
| 1168 |
|
end else begin |
| 1169 |
|
Body.Text := Content; |
| 1170 |
|
// if Body.Count > 0 then |
| 1171 |
|
// Body.Delete(0); |
| 1172 |
|
Body.SaveToFile(FileName); |
| 1173 |
|
|
| 1174 |
|
if ThreadItem.Title = '' then begin |
| 1175 |
|
Res := GikoSys.DivideStrLine(Body[0]); |
| 1176 |
|
ThreadItem.Title := Res.FTitle; |
| 1177 |
|
end; |
| 1178 |
|
ThreadItem.Size := 0; |
| 1179 |
|
//ThreadItem.Count := 0; |
| 1180 |
|
ThreadItem.AllResCount := 0; |
| 1181 |
|
ThreadItem.NewResCount := 0; |
| 1182 |
|
OldCnt := 0; |
| 1183 |
|
NewRes := Body.Count; |
| 1184 |
|
//Cnt := Body.Count; |
| 1185 |
end; |
end; |
|
ThreadItem.Size := 0; |
|
|
//ThreadItem.Count := 0; |
|
|
ThreadItem.AllResCount := 0; |
|
|
ThreadItem.NewResCount := 0; |
|
|
OldCnt := 0; |
|
|
NewRes := Body.Count; |
|
| 1186 |
Cnt := Body.Count; |
Cnt := Body.Count; |
| 1187 |
|
finally |
| 1188 |
|
Body.Free; |
| 1189 |
end; |
end; |
| 1190 |
Cnt := Body.Count; |
|
| 1191 |
finally |
ThreadItem.Size := ThreadItem.Size + ContentLength; |
| 1192 |
Body.Free; |
ThreadItem.LastModified := LastModified; |
| 1193 |
|
ThreadItem.Count := Cnt; |
| 1194 |
|
//ThreadItem.AllResCount := Cnt; |
| 1195 |
|
ThreadItem.NewResCount := NewRes; |
| 1196 |
|
ThreadItem.NewReceive := OldCnt + 1; |
| 1197 |
end; |
end; |
| 1198 |
ThreadItem.RoundDate := Now; |
ThreadItem.AllResCount := ThreadItem.Count; |
|
ThreadItem.Size := ThreadItem.Size + ContentLength; |
|
|
ThreadItem.LastModified := LastModified; |
|
|
ThreadItem.Count := Cnt; |
|
|
ThreadItem.AllResCount := Cnt; |
|
|
ThreadItem.NewResCount := NewRes; |
|
| 1199 |
ThreadItem.IsLogFile := True; |
ThreadItem.IsLogFile := True; |
| 1200 |
ThreadItem.NewReceive := OldCnt + 1; |
ThreadItem.RoundDate := Now; |
| 1201 |
ThreadItem.UnRead := True; |
ThreadItem.UnRead := True; |
| 1202 |
ThreadItem.ParentBoard.UnRead := ThreadItem.ParentBoard.UnRead + 1; |
ThreadItem.ParentBoard.UnRead := ThreadItem.ParentBoard.UnRead + 1; |
| 1203 |
// if ThreadItem.RoundNo = 6 then |
// if ThreadItem.RoundNo = 6 then |
| 1218 |
// ini.WriteInteger('Setting', 'RoundNo', ThreadItem.RoundNo); |
// ini.WriteInteger('Setting', 'RoundNo', ThreadItem.RoundNo); |
| 1219 |
ini.WriteBool('Setting', 'Round', ThreadItem.Round); |
ini.WriteBool('Setting', 'Round', ThreadItem.Round); |
| 1220 |
ini.WriteBool('Setting', 'UnRead', ThreadItem.UnRead); |
ini.WriteBool('Setting', 'UnRead', ThreadItem.UnRead); |
| 1221 |
ini.UpdateFile; |
ini.UpdateFile; |
| 1222 |
finally |
finally |
| 1223 |
ini.Free; |
ini.Free; |
| 1224 |
end; |
end; |