Develop and Download Open Source Software

Browse CVS Repository

Diff of /gikonavigoeson/gikonavi/ItemDownload.pas

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph | View Patch Patch

revision 1.6 by yoffy, Fri Oct 31 15:01:46 2003 UTC revision 1.6.2.2 by yoffy, Thu Sep 9 16:20:33 2004 UTC
# Line 3  unit ItemDownload; Line 3  unit ItemDownload;
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, ExternalBoardPlugInMain,
9            Sort;
10    
11  type  type
12          TDownloadItem = class;          TDownloadItem = class;
# Line 15  type Line 16  type
16          TGikoDLProgress = (gdpStd, gdpAll, gdpDatOchi, gdpOfflaw);          TGikoDLProgress = (gdpStd, gdpAll, gdpDatOchi, gdpOfflaw);
17    
18          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;
19          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;
20          TGikoWorkEndEvent = procedure(Sender: TObject; AWorkMode: TWorkMode; ID: Integer) of object;          TGikoWorkEndEvent = procedure(Sender: TObject; AWorkMode: TWorkMode; ID: Integer) of object;
21          TDownloadEndEvent = procedure(Sender: TObject; Item: TDownloadItem) of object;          TDownloadEndEvent = procedure(Sender: TObject; Item: TDownloadItem) of object;
22          TDownloadMsgEvent = procedure(Sender: TObject; Item: TDownloadItem; Msg: string; Icon: TGikoMessageIcon) of object;          TDownloadMsgEvent = procedure(Sender: TObject; Item: TDownloadItem; Msg: string; Icon: TGikoMessageIcon) of object;
# Line 41  type Line 42  type
42                  FOnWorkEnd: TGikoWorkEndEvent;                  FOnWorkEnd: TGikoWorkEndEvent;
43                  FOnDownloadEnd: TDownloadEndEvent;                  FOnDownloadEnd: TDownloadEndEvent;
44                  FOnDownloadMsg: TDownloadMsgEvent;                  FOnDownloadMsg: TDownloadMsgEvent;
45                    FDownloadTitle: string;
46    
47                  procedure FireDownloadEnd;                  procedure FireDownloadEnd;
48                  procedure FireDownloadMsg;                  procedure FireDownloadMsg;
# Line 49  type Line 51  type
51                  procedure WorkEnd(Sender: TObject; AWorkMode: TWorkMode);                  procedure WorkEnd(Sender: TObject; AWorkMode: TWorkMode);
52                  procedure Work(Sender: TObject; AWorkMode: TWorkMode; const AWorkCount: Integer);                  procedure Work(Sender: TObject; AWorkMode: TWorkMode; const AWorkCount: Integer);
53                  function ParseCgiStatus(Content: string): TCgiStatus;                  function ParseCgiStatus(Content: string): TCgiStatus;
54      function CgiDownload(ItemType: TGikoDownloadType; URL: string; Modified: TDateTime): Boolean;                  function CgiDownload(ItemType: TGikoDownloadType; URL: string; Modified: TDateTime): Boolean;
55                  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;
56                  function DeleteStatusLine(Content: string): string;                  function DeleteStatusLine(Content: string): string;
57          protected          protected
# Line 58  type Line 60  type
60                  property Item: TDownloadItem read FItem write FItem;                  property Item: TDownloadItem read FItem write FItem;
61                  property Number: Integer read FNumber write FNumber;                  property Number: Integer read FNumber write FNumber;
62                  constructor Create(CreateSuspended: Boolean);                  constructor Create(CreateSuspended: Boolean);
63                  destructor Destroy; override;                                  destructor Destroy; override;
64                  procedure Abort;                  procedure Abort;
65                  property OnWork: TGikoWorkEvent read FOnWork write FOnWork;                  property OnWork: TGikoWorkEvent read FOnWork write FOnWork;
66                  property OnWorkBegin: TGikoWorkBeginEvent read FOnWorkBegin write FOnWorkBegin;                  property OnWorkBegin: TGikoWorkBeginEvent read FOnWorkBegin write FOnWorkBegin;
# Line 79  type Line 81  type
81                  FResponseCode: Smallint;                  FResponseCode: Smallint;
82                  FState: TGikoDownloadState;                  FState: TGikoDownloadState;
83                  FErrText: string;                  FErrText: string;
84                    FForceDownload: Boolean;
85                    FIsAbone : Boolean;
86          public          public
87                  procedure SaveListFile;                  procedure SaveListFile;
88                  procedure SaveItemFile;                  procedure SaveItemFile;
# Line 93  type Line 97  type
97                  property ResponseCode: Smallint read FResponseCode write FResponseCode;                  property ResponseCode: Smallint read FResponseCode write FResponseCode;
98                  property State: TGikoDownloadState read FState write FState;                  property State: TGikoDownloadState read FState write FState;
99                  property ErrText: string read FErrText write FErrText;                  property ErrText: string read FErrText write FErrText;
100                    property ForceDownload: Boolean read FForceDownload write FForceDownload;
101                    property IsAbone : Boolean read FIsAbone write FIsAbone;
102          end;          end;
103    
104  implementation  implementation
# Line 109  end; Line 115  end;
115    
116  destructor TDownloadThread.Destroy;  destructor TDownloadThread.Destroy;
117  begin  begin
118        FIndy.Request.CustomHeaders.Clear;
119        FIndy.Request.RawHeaders.Clear;
120        FIndy.Request.Clear;
121        FIndy.Response.CustomHeaders.Clear;
122        FIndy.Response.RawHeaders.Clear;
123        FIndy.Response.Clear;
124        FIndy.ProxyParams.Clear;
125          FIndy.Free;          FIndy.Free;
126          inherited;          inherited;
127  end;  end;
# Line 116  end; Line 129  end;
129  function RFC1123_Date(aDate : TDateTime) : String;  function RFC1123_Date(aDate : TDateTime) : String;
130  const  const
131           StrWeekDay : String = 'MonTueWedThuFriSatSun';           StrWeekDay : String = 'MonTueWedThuFriSatSun';
132           StrMonth   : String = 'JanFebMarAprMayJunJulAugSepOctNovDec';           StrMonth        : String = 'JanFebMarAprMayJunJulAugSepOctNovDec';
133  var  var
134           Year, Month, Day       : Word;           Year, Month, Day                        : Word;
135           Hour, Min,   Sec, MSec : Word;           Hour, Min,      Sec, MSec : Word;
136           DayOfWeek              : Word;           DayOfWeek                                                      : Word;
137  begin  begin
138           DecodeDate(aDate, Year, Month, Day);           DecodeDate(aDate, Year, Month, Day);
139           DecodeTime(aDate, Hour, Min,   Sec, MSec);           DecodeTime(aDate, Hour, Min,    Sec, MSec);
140           DayOfWeek := ((Trunc(aDate) - 2) mod 7);           DayOfWeek := ((Trunc(aDate) - 2) mod 7);
141           Result := Copy(StrWeekDay, 1 + DayOfWeek * 3, 3) + ', ' +           Result := Copy(StrWeekDay, 1 + DayOfWeek * 3, 3) + ', ' +
142                                                   Format('%2.2d %s %4.4d %2.2d:%2.2d:%2.2d',                                                   Format('%2.2d %s %4.4d %2.2d:%2.2d:%2.2d',
# Line 143  var Line 156  var
156          Idx: Integer;          Idx: Integer;
157          ATitle: string;          ATitle: string;
158          DownloadResult: Boolean;          DownloadResult: Boolean;
159          Abone: Boolean;          foundPos: Integer;
160    foundPos: Integer;          boardPlugIn     : TBoardPlugIn;
161            listContent     : string;
162            lastContent             : string;
163            logFile                         : TFileStream;
164            adjustMargin    : Integer;
165    const
166            ADJUST_MARGIN   = 16;
167  begin  begin
168          while not Terminated do begin          while not Terminated do begin
169                    //===== プラグイン
170                    FAbort := False;
171                    boardPlugIn := nil;
172                    ExternalBoardManager.OnWork                             := Work;
173                    ExternalBoardManager.OnWorkBegin        := WorkBegin;
174                    ExternalBoardManager.OnWorkEnd          := WorkEnd;
175    
176                    FDownloadTitle := '';
177                    case FItem.FDownType of
178                    gdtBoard:
179                            begin
180                                    FDownloadTitle := FItem.FBoard.Title;
181                                    if FItem.FBoard <> nil then begin
182                                            if FItem.FBoard.IsBoardPlugInAvailable then begin
183                                                    boardPlugIn     := FItem.FBoard.BoardPlugIn;
184                                                    Item.State      := TGikoDownloadState( boardPlugIn.DownloadBoard( DWORD( FItem.FBoard ) ) );
185                                            end;
186                                    end;
187                            end;
188                    gdtThread:
189                            begin
190                                    FDownloadTitle := FItem.FThreadItem.Title;
191                                    if FItem.FThreadItem <> nil then begin
192                                            if FItem.FThreadItem.IsBoardPlugInAvailable then begin
193                                                    boardPlugIn     := FItem.FThreadItem.BoardPlugIn;
194                                                    Item.State      := TGikoDownloadState( boardPlugIn.DownloadThread( DWORD( FItem.FThreadItem ) ) );
195                                            end;
196                                    end;
197                            end;
198                    end;
199                    if Length(FDownloadTitle) = 0 then
200                            FDownloadTitle := '(名称不明)';
201    
202                    if boardPlugIn <> nil then begin
203                            if FAbort then begin
204                                    Item.State := gdsAbort;
205                            end;
206                            if Assigned( OnDownloadEnd ) then
207                                    Synchronize( FireDownloadEnd );
208                            if Terminated then
209                                    Break;
210    
211                            Suspend;
212                            Continue;
213                    end;
214    
215                    //===== プラグインを使用しない場合
216                  FAbort := False;                  FAbort := False;
217                  FIndy.Request.CustomHeaders.Clear;                  FIndy.Request.CustomHeaders.Clear;
218                  FIndy.Response.Clear;                  FIndy.Response.Clear;
219                  FIndy.Request.Clear;                  FIndy.Request.Clear;
220        FIndy.ProxyParams.Clear;
221        FIndy.Disconnect;
222                  FIndy.Request.UserAgent := GikoSys.GetUserAgent;                  FIndy.Request.UserAgent := GikoSys.GetUserAgent;
223                  FIndy.RecvBufferSize := Gikosys.Setting.RecvBufferSize;                  FIndy.RecvBufferSize := Gikosys.Setting.RecvBufferSize;
224                  FIndy.ProxyParams.BasicAuthentication := False;                  FIndy.ProxyParams.BasicAuthentication := False;
# Line 188  begin Line 256  begin
256                          {$ENDIF}                          {$ENDIF}
257                  end;                  end;
258    
259                    adjustMargin := 0;
260                    if Item.DownType = gdtThread then begin
261                            if FileExists( Item.ThreadItem.GetThreadFileName ) then begin
262                                    // dat ファイルの最後を読み出す
263                                    SetLength( lastContent, ADJUST_MARGIN + 1 );
264                                    logFile := TFileStream.Create( Item.ThreadItem.GetThreadFileName, fmOpenRead or fmShareDenyWrite );
265                                    try
266                                            logFile.Seek( -(ADJUST_MARGIN + 1), soFromEnd );
267                                            logFile.Read( lastContent[ 1 ], ADJUST_MARGIN + 1 );
268                                            lastContent := StringReplace( lastContent, #13, '', [] );       // CR の削除
269                                    finally
270                                            logFile.Free;
271                                    end;
272                            end else begin
273            lastContent := '';
274                            end;
275                            adjustMargin := Length( lastContent );
276                    end;
277    
278                  FIndy.Request.ContentRangeStart := 0;                  FIndy.Request.ContentRangeStart := 0;
279                  FIndy.Request.LastModified := ZERO_DATE;                  FIndy.Request.LastModified := ZERO_DATE;
280                  ResStream := TMemoryStream.Create;                  ResStream := TMemoryStream.Create;
# Line 207  begin Line 294  begin
294                                          Writeln('Modified: ' + FloatToStr(Item.Board.LastModified));                                          Writeln('Modified: ' + FloatToStr(Item.Board.LastModified));
295                                          {$ENDIF}                                          {$ENDIF}
296                                          URL := Item.Board.GetReadCgiURL;                                          URL := Item.Board.GetReadCgiURL;
297                                          Modified := Item.Board.LastModified;                                          if Item.ForceDownload then begin
298                                                    // 強制取得
299                                                    ATitle := Item.Board.Title;
300                                                    if ATitle = '' then
301                                                            ATitle := '(名称不明)';
302                                                    FMsg := '★強制取得を行います - [' + ATitle + ']';
303                                                    FIcon := gmiWhat;
304                                                    if Assigned(OnDownloadMsg) then
305                                                            Synchronize(FireDownloadMsg);
306                                                    Modified := ZERO_DATE
307                                            end else begin
308                                                    Modified := Item.Board.LastModified;
309                                            end;
310                                  end else if Item.DownType = gdtThread then begin                                  end else if Item.DownType = gdtThread then begin
311                                          {$IFDEF DEBUG}                                          {$IFDEF DEBUG}
312                                          Writeln('DAT取得');                                          Writeln('DAT取得');
# Line 215  begin Line 314  begin
314                                          Writeln('Modified: ' + FloatToStr(Item.ThreadItem.LastModified));                                          Writeln('Modified: ' + FloatToStr(Item.ThreadItem.LastModified));
315                                          {$ENDIF}                                          {$ENDIF}
316                                          URL := Item.ThreadItem.GetDatURL;                                          URL := Item.ThreadItem.GetDatURL;
317                                          Modified := Item.ThreadItem.LastModified;                                          if Item.ForceDownload then begin
318                                          if Item.ThreadItem.Size > 0 then begin                                                  // 強制取得
319                                                  {$IFDEF DEBUG}                                                  ATitle := Item.ThreadItem.Title;
320                                                  Writeln('RangeStart: ' + IntToStr(Item.ThreadItem.Size));                                                  if ATitle = '' then
321                                                  {$ENDIF}                                                          ATitle := '(名称不明)';
322                                                  //あぼーんチェックのため1バイト前から取得                                                  FMsg := '★強制取得を行います - [' + ATitle + ']';
323                                                  RangeStart := Item.ThreadItem.Size;                                                  FIcon := gmiWhat;
324                                                  AdjustLen := -1;                                                  if FileExists(ChangeFileExt(Item.FThreadItem.GetThreadFileName,'.NG')) = true then
325                                                            DeleteFile(ChangeFileExt(Item.FThreadItem.GetThreadFileName,'.NG'));
326                                                    if Assigned(OnDownloadMsg) then
327                                                            Synchronize(FireDownloadMsg);
328                                                    Modified := ZERO_DATE;
329                                                    RangeStart := 0;
330                                                    AdjustLen := 0;
331                                            end else begin
332                                                    Modified := Item.ThreadItem.LastModified;
333                                                    if Item.ThreadItem.Size > 0 then begin
334                                                            {$IFDEF DEBUG}
335                                                            Writeln('RangeStart: ' + IntToStr(Item.ThreadItem.Size));
336                                                            {$ENDIF}
337                                                            // あぼーんチェックのため adjustMargin バイト前から取得
338                                                            RangeStart := Item.ThreadItem.Size;
339                                                            AdjustLen := -adjustMargin;
340                                                    end;
341                                          end;                                          end;
342                                  end;                                  end;
343                                  Abone := False;                                  Item.IsAbone := False;
344                                  DownloadResult := DatDownload(Item.DownType, URL, Modified, RangeStart, AdjustLen);                                  DownloadResult := DatDownload(Item.DownType, URL, Modified, RangeStart, AdjustLen);
345                                  {$IFDEF DEBUG}                                  {$IFDEF DEBUG}
346                                  Writeln('ResponseCode: ' + IntToStr(FIndy.ResponseCode));                                  Writeln('ResponseCode: ' + IntToStr(FIndy.ResponseCode));
347                                  {$ENDIF}                                  {$ENDIF}
348                                  if Item.DownType = gdtThread then begin                                  if Item.DownType = gdtThread then begin
349                                          if Item.ResponseCode = 416 then begin                                          if Item.ResponseCode = 416 then begin
350                                                  Abone := True;                                                  Item.IsAbone := True;
351                                                  DownloadResult := True;                                                  DownloadResult := True;
352                                          end else if DownloadResult and (AdjustLen = -1) and (Item.Content[1] <> #10) then                                          end else if DownloadResult and (AdjustLen < 0) then begin
353                                                  Abone := True;                                                  if Copy( Item.Content, 1, adjustMargin ) <> lastContent then
354                                                            Item.IsAbone := True;
355                                            end;
356                                  end;                                  end;
357    
358                                  if Trim(FIndy.Response.RawHeaders.Values['Date']) <> '' then begin                                  if Trim(FIndy.Response.RawHeaders.Values['Date']) <> '' then begin
# Line 249  begin Line 366  begin
366                                          {$IFDEF DEBUG}                                          {$IFDEF DEBUG}
367                                          Writeln('Date:' + FIndy.Response.RawHeaders.Values['Date']);                                          Writeln('Date:' + FIndy.Response.RawHeaders.Values['Date']);
368                                          {$ENDIF}                                          {$ENDIF}
369                                          if Abone then begin                                          if Item.IsAbone then begin
370                                                  {$IFDEF DEBUG}                                                  {$IFDEF DEBUG}
371                                                  Writeln('あぼーん検出');                                                  Writeln('あぼーん検出');
372                                                  {$ENDIF}                                                  {$ENDIF}
# Line 261  begin Line 378  begin
378                                                  AdjustLen := 0;                                                  AdjustLen := 0;
379                                                  FMsg := '★「あぼーん」を検出したので再取得を行います - [' + ATitle + ']';                                                  FMsg := '★「あぼーん」を検出したので再取得を行います - [' + ATitle + ']';
380                                                  FIcon := gmiWhat;                                                  FIcon := gmiWhat;
381                          if FileExists(ChangeFileExt(Item.FThreadItem.GetThreadFileName,'.NG')) = true then                                                  if FileExists(ChangeFileExt(Item.FThreadItem.GetThreadFileName,'.NG')) = true then
382                                                  DeleteFile(ChangeFileExt(Item.FThreadItem.GetThreadFileName,'.NG'));                                                          DeleteFile(ChangeFileExt(Item.FThreadItem.GetThreadFileName,'.NG'));
383                                                  if Assigned(OnDownloadMsg) then                                                  if Assigned(OnDownloadMsg) then
384                                                          Synchronize(FireDownloadMsg);                                                          Synchronize(FireDownloadMsg);
385                                                  if not DatDownload(Item.DownType, URL, ZERO_DATE, RangeStart, AdjustLen) then                                                  if not DatDownload(Item.DownType, URL, ZERO_DATE, RangeStart, AdjustLen) then
# Line 271  begin Line 388  begin
388                                                  Writeln('あぼーん再取得後');                                                  Writeln('あぼーん再取得後');
389                                                  Writeln('ResponseCode: ' + IntToStr(Item.ResponseCode));                                                  Writeln('ResponseCode: ' + IntToStr(Item.ResponseCode));
390                                                  {$ENDIF}                                                  {$ENDIF}
391                                          end else if (Item.DownType = gdtThread) and (AdjustLen = -1) and (Item.Content[1] = #10) then begin                                          end else if (Item.DownType = gdtThread) and (AdjustLen < 0) then begin
392                                                  //差分取得かつ1バイト目がLFの場合(正常取得)は頭のLFを削除                                                  // 差分取得が出来た場合はあぼーんチェック用に取得した余分なサイズを削除
393                                                  Item.Content := Copy(Item.Content, 2, Length(Item.Content));                                                  Item.Content := Copy(Item.Content, adjustMargin + 1, MaxInt);
394                                          end;                                          end;
395                                  end else begin                                  end else begin
396                                          Item.State := gdsError;                                          Item.State := gdsError;
# Line 410  begin Line 527  begin
527                                                          Idx := Pos(' ', Item.ErrText);                                                          Idx := Pos(' ', Item.ErrText);
528                                                          if Idx <> 0 then begin                                                          if Idx <> 0 then begin
529                                                                  URL := Copy(Item.ErrText, Idx + 1, Length(Item.ErrText));                                                                  URL := Copy(Item.ErrText, Idx + 1, Length(Item.ErrText));
530                                                                  if Pos('../', URL) = 1 then                                                                  if Pos( '://', URL ) = 0 then begin
531                                                                          URL := Copy(URL, 4, Length(URL));                                                                          if Pos('../', URL) = 1 then
532                                                                  URL := GikoSys.UrlToServer(Item.ThreadItem.ParentBoard.URL) + URL;                                                                                  URL := Copy(URL, 4, MaxInt );
533                                                                            if Pos( '/', URL ) = 1 then
534                                                                                    URL := Copy( URL, 2, MaxInt );
535                                                                            URL := GikoSys.UrlToServer(Item.ThreadItem.ParentBoard.URL) + URL;
536                                                                    end;
537                                                                  Modified := Item.ThreadItem.LastModified;                                                                  Modified := Item.ThreadItem.LastModified;
538                                                                  RangeStart := 0;                                                                  RangeStart := 0;
539                                                                  AdjustLen := 0;                                                                  AdjustLen := 0;
# Line 439  begin Line 560  begin
560                                          end;                                          end;
561                                  end;                                  end;
562    
                                 {$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}  
   
563                                  case Item.ResponseCode of                                  case Item.ResponseCode of
564                                          200: Item.State := gdsComplete;                                          200: Item.State := gdsComplete;
565                                          206: Item.State := gdsDiffComplete;                                          206: Item.State := gdsDiffComplete;
# Line 549  begin Line 636  begin
636                                  Synchronize(FireDownloadEnd);                                  Synchronize(FireDownloadEnd);
637                          ResStream.Free;                          ResStream.Free;
638                  end;                  end;
639    
640                    FIndy.Request.CustomHeaders.Clear;
641            FIndy.Request.RawHeaders.Clear;
642            FIndy.Request.Clear;
643            FIndy.Response.CustomHeaders.Clear;
644            FIndy.Response.RawHeaders.Clear;
645                    FIndy.Response.Clear;
646                FIndy.ProxyParams.Clear;
647    
648                  if Terminated then Break;                  if Terminated then Break;
649                  Suspend;                  Suspend;
650          end;          end;
# Line 568  begin Line 664  begin
664                  FIndy.Request.LastModified := modified - OffsetFromUTC;                  FIndy.Request.LastModified := modified - OffsetFromUTC;
665          end;          end;
666          FIndy.Request.AcceptEncoding := '';          FIndy.Request.AcceptEncoding := '';
667    FIndy.Request.Accept := 'text/html';          FIndy.Request.Accept := 'text/html';
668          ResStream := TMemoryStream.Create;          ResStream := TMemoryStream.Create;
669          try          try
670                  try                  try
# Line 598  begin Line 694  begin
694                                  Item.ErrText := E.Message;                                  Item.ErrText := E.Message;
695                                  Result := False;                                  Result := False;
696                                  ResponseCode := -1;                                  ResponseCode := -1;
697                  Screen.Cursor := crDefault;                                  Screen.Cursor := crDefault;
698                          end;                          end;
699                          on E: EIdConnectException do begin                          on E: EIdConnectException do begin
700                                  Item.Content := '';                                  Item.Content := '';
# Line 607  begin Line 703  begin
703                                  Item.ErrText := E.Message;                                  Item.ErrText := E.Message;
704                                  Result := False;                                  Result := False;
705                                  ResponseCode := -1;                                  ResponseCode := -1;
706                  Screen.Cursor := crDefault;                                  Screen.Cursor := crDefault;
707                          end;                          end;
708                          on E: Exception do begin                          on E: Exception do begin
709                                  {$IFDEF DEBUG}                                  {$IFDEF DEBUG}
# Line 620  begin Line 716  begin
716                                  Item.ErrText := E.Message;                                  Item.ErrText := E.Message;
717                                  ResponseCode := FIndy.ResponseCode;                                  ResponseCode := FIndy.ResponseCode;
718                                  Result := False;                                  Result := False;
719          Screen.Cursor := crDefault;                                  Screen.Cursor := crDefault;
720                          end;                          end;
721                  end;                  end;
722          finally          finally
# Line 692  begin Line 788  begin
788                                  Item.ErrText := E.Message;                                  Item.ErrText := E.Message;
789                                  Result := False;                                  Result := False;
790                                  ResponseCode := -1;                                  ResponseCode := -1;
791                  Screen.Cursor := crDefault;                                  Screen.Cursor := crDefault;
792                          end;                          end;
793                          on E: EIdConnectException do begin                          on E: EIdConnectException do begin
794                                  Item.Content := '';                                  Item.Content := '';
# Line 701  begin Line 797  begin
797                                  Item.ErrText := E.Message;                                  Item.ErrText := E.Message;
798                                  Result := False;                                  Result := False;
799                                  ResponseCode := -1;                                  ResponseCode := -1;
800                  Screen.Cursor := crDefault;                                  Screen.Cursor := crDefault;
801                          end;                          end;
802                          on E: Exception do begin                          on E: Exception do begin
803                                  {$IFDEF DEBUG}                                  {$IFDEF DEBUG}
# Line 714  begin Line 810  begin
810                                  Item.ErrText := E.Message;                                  Item.ErrText := E.Message;
811                                  ResponseCode := FIndy.ResponseCode;                                  ResponseCode := FIndy.ResponseCode;
812                                  Result := False;                                  Result := False;
813                  Screen.Cursor := crDefault;                                  Screen.Cursor := crDefault;
814                          end;                          end;
815                  end;                  end;
816          finally          finally
# Line 745  procedure TDownloadThread.Abort; Line 841  procedure TDownloadThread.Abort;
841  begin  begin
842          FAbort := True;          FAbort := True;
843          FIndy.DisconnectSocket;          FIndy.DisconnectSocket;
844            if socket <> nil then begin
845                    socket.DisconnectSocket;
846            end;
847  end;  end;
848    
849  procedure TDownloadThread.WorkBegin(Sender: TObject; AWorkMode: TWorkMode; const AWorkCountMax: Integer);  procedure TDownloadThread.WorkBegin(Sender: TObject; AWorkMode: TWorkMode; const AWorkCountMax: Integer);
850  begin  begin
851          if Assigned(OnWorkBegin) then          if Assigned(OnWorkBegin) then
852                  OnWorkBegin(Sender, AWorkMode, AWorkCountMax, FNumber);                  OnWorkBegin(Sender, AWorkMode, AWorkCountMax, FNumber, FDownloadTitle);
853  end;  end;
854    
855  procedure TDownloadThread.WorkEnd(Sender: TObject; AWorkMode: TWorkMode);  procedure TDownloadThread.WorkEnd(Sender: TObject; AWorkMode: TWorkMode);
# Line 778  begin Line 877  begin
877  // [-INCR] (Incorrect)の場合はすべてのデータ  // [-INCR] (Incorrect)の場合はすべてのデータ
878  // [-ERR (テキスト)]の場合はなんかエラー  // [-ERR (テキスト)]の場合はなんかエラー
879  // 例:+OK 23094/512K  // 例:+OK 23094/512K
880  //     -INCR 23094/512K  //               -INCR 23094/512K
881  //     -ERR そんな板ないです  //               -ERR そんな板ないです
882          Idx := AnsiPos(#10, Content);          Idx := AnsiPos(#10, Content);
883          StatusLine := Copy(Content, 0, Idx);          StatusLine := Copy(Content, 0, Idx);
884    
# Line 842  var Line 941  var
941          i: Integer;          i: Integer;
942          index: Integer;          index: Integer;
943          NewItem: TThreadItem;          NewItem: TThreadItem;
         NewList: TList;  
 //      SaveCount: Integer;  
944          NumCount: Integer;          NumCount: Integer;
945          Body: TStringList;          Body: TStringList;
946          Rec: TSubjectRec;          Rec: TSubjectRec;
947            function MakeThreadCallBack(
948                    inInstance      : DWORD;        // TBoardItem のインスタンス
949                    inURL                           : PChar;        // スレッドの URL
950                    inTitle                 : PChar;        // スレタイ
951                    inCount                 : DWORD         // レスの数
952            ) : Boolean; stdcall;           // 列挙を続けるなら True
953            var
954                    _ThreadItem     : TThreadItem;  // '_' はクラスのプロパティとかぶってるので
955                    boardItem               : TBoard;
956            begin
957                    Result          := True;
958                    boardItem       := TBoard( inInstance );
959    
960                    boardItem.IntData := boardItem.IntData + 1;
961                    index := boardItem.GetIndexFromURL( string( inURL ) );
962                    if index = -1 then begin
963                            //新しいスレッド
964                            _ThreadItem := TThreadItem.Create( boardItem.BoardPlugIn, string( inURL ) );
965    
966                            _ThreadItem.Title                                       := string( inTitle );
967                            _ThreadItem.AllResCount         := inCount;
968                            _ThreadItem.ParentBoard         := Board;
969                            _ThreadItem.No                                          := boardItem.IntData;
970                            _ThreadItem.RoundDate           := ZERO_DATE;
971                            _ThreadItem.LastModified        := ZERO_DATE;
972                            _ThreadItem.AgeSage                             := gasNew;
973                            boardItem.Add(_ThreadItem);
974                    end else begin
975                            if boardItem.Items[index].No > boardItem.IntData then
976                                    boardItem.Items[index].AgeSage := gasAge
977                            else if boardItem.Items[index].AllResCount < inCount then
978                                    boardItem.Items[index].AgeSage := gasSage
979                            else
980                                    boardItem.Items[index].AgeSage := gasNone;
981    
982                            boardItem.Items[index].No                                               := boardItem.IntData;
983                            boardItem.Items[index].AllResCount      := inCount;
984                    end;
985            end;
986  begin  begin
987          NewList := TList.Create;          //Board.ListData := TList.Create;
988          Body := TStringList.Create;          Body := TStringList.Create;
989          try          try
990                  //ダウンロード日時設定(ローカル日時)                  //ダウンロード日時設定(ローカル日時)
# Line 856  begin Line 992  begin
992                  //サーバ上ファイルの更新時刻設定                  //サーバ上ファイルの更新時刻設定
993                  Board.LastModified := LastModified;                  Board.LastModified := LastModified;
994    
995                  //新しいリストを作成する                  //dat落ちスレのソート順を決定するためにソートする
996                  //新しいリストに古いリストのログがあるならそれを新しいリストに追加                  if GikoSys.Setting.DatOchiSortIndex >= 0 then begin
997                  //古いログがなければ、新たにスレオブジェクトを作成                          Sort.SortNoFlag := true;
998                  Body.Text := Content;                          Sort.SortOrder := GikoSys.Setting.DatOchiSortOrder;
999                  NumCount := 0;                          Sort.SortIndex := GikoSys.Setting.DatOchiSortIndex;
1000                  for i := 0 to Body.Count - 1 do begin                          //Sort.SortNonAcquiredCountFlag := GikoSys.Setting.NonAcquiredCount;
1001                          //if i = 0 then Continue;       //1行目はステータス行のため処理なし                          Board.CustomSort(ThreadItemSortProc);
1002                    end;
                         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  
                                 //新しいスレッド  
                                 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;  
                                 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;  
1003    
1004                    for i := Board.Count - 1 downto 0 do
1005                            Board.Items[i].AgeSage := gasNull;
1006    
1007                                  Board.Items[index].No := NumCount;                  if Board.IsBoardPlugInAvailable then begin
1008                                  Board.Items[index].AllResCount := Rec.FCount;                          // 新しいリストを作成する
1009  //                              if not Board.Items[index].IsLogFile then                          // 新しいリストに古いリストのログがあるならそれを新しいリストに追加
1010  //                                      Board.Items[index].Count := Rec.FCount;                          // 古いログがなければ、新たにスレオブジェクトを作成
1011                                  NewList.Add(Board.Items[index]);                          Board.IntData := 0;
1012                                  Board.DeleteList(index);                          Board.BoardPlugIn.EnumThread( DWORD( Board ), @MakeThreadCallBack );
1013    
1014                //古いリストにしかないやつらを削除
1015                            for i := Board.Count - 1 downto 0 do begin
1016                                    if( Board.Items[i].AgeSage = gasNull )and not (Board.Items[i].IsLogFile) then
1017                                            Board.Delete(i);
1018                          end;                          end;
                 end;  
1019    
1020                  //新しいリストに無かったアイテムを新しいリストに追加                          // 新しいリストに無かったアイテムを新しいリストに追加
1021                  for i := 0 to Board.Count - 1 do begin                          for i := 0 to Board.Count - 1 do begin
1022                          if Board.Items[i].IsLogFile then begin                                  if(Board.Items[i].AgeSage = gasNull) and (Board.Items[i].IsLogFile) then begin
1023                                  inc(NumCount);                                          Board.IntData := Board.IntData + 1;
1024                                  Board.Items[i].No := NumCount;                                          Board.Items[i].No                                               := Board.IntData;
1025                                  Board.Items[i].AllResCount := Board.Items[i].Count;                                          Board.Items[i].AllResCount      := Board.Items[i].Count;
1026                                  Board.Items[i].NewResCount := 0;                                          Board.Items[i].NewResCount      := 0;
1027                                  Board.Items[i].AgeSage := gasNone;                                          Board.Items[i].AgeSage                  := gasNone;
1028                                  NewList.Add(Board.Items[i]);                                  end;
1029                          end;                          end;
1030                  end;                  end else begin
1031                            //新しいリストを作成する
1032                  //古いリストを消す(リストのみ。スレオブジェクト自体は消さない)                          //新しいリストに古いリストのログがあるならそれを新しいリストに追加
1033                  for i := Board.Count - 1 downto 0 do                          //古いログがなければ、新たにスレオブジェクトを作成
1034                          Board.DeleteList(i);                          Body.Text := Content;
1035                            NumCount := 0;
1036                            for i := 0 to Body.Count - 1 do begin
1037                                    Rec := GikoSys.DivideSubject(Body[i]);
1038                                    Rec.FFileName := Trim(Rec.FFileName);
1039                                    if (Rec.FTitle = '') and (Rec.FCount = 0) then Continue;
1040                                    Inc(NumCount);
1041                                    index := Board.GetIndexFromFileName(Rec.FFileName);
1042                                    if index = -1 then begin
1043                                            //新しいスレッド
1044                                            NewItem := TThreadItem.Create(
1045                            nil, GikoSys.Get2chBoard2ThreadURL( Board, ChangeFileExt( Rec.FFileName, '' ) ) );
1046                                            NewItem.Title := Rec.FTitle;
1047                                            NewItem.AllResCount := Rec.FCount;
1048                                            NewItem.ParentBoard := Board;
1049                                            NewItem.No := NumCount;
1050                                            NewItem.RoundDate := ZERO_DATE;
1051                                            NewItem.LastModified := ZERO_DATE;
1052                                            NewItem.AgeSage := gasNew;
1053                                            Board.Add(NewItem);
1054                                    end else begin
1055                                            if Board.Items[index].No > NumCount then
1056                                                    Board.Items[index].AgeSage := gasAge
1057                                            else if Board.Items[index].AllResCount < Rec.FCount then
1058                                                    Board.Items[index].AgeSage := gasSage
1059                                            else
1060                                                    Board.Items[index].AgeSage := gasNone;
1061    
1062                  //新しいリストをボードオブジェクトに追加                                          Board.Items[index].No := NumCount;
1063                  for i := 0 to NewList.Count - 1 do                                          Board.Items[index].AllResCount := Rec.FCount;
1064                          Board.Add(TThreadItem(NewList[i]));                                  end;
1065                            end;
1066                            //古いリストの削除
1067                            for i := Board.Count - 1 downto 0 do begin
1068                                    if( Board.Items[i].AgeSage = gasNull )and not (Board.Items[i].IsLogFile) then
1069                                            Board.Delete(i);
1070                            end;
1071    
1072                  //リスト(subject.txt)を保存                          //新しいリストに無かったアイテムの更新
1073  //              GikoSys.ForceDirectoriesEx(GikoSys.GetLogDir + Board.BBSID);                          for i := 0 to Board.Count - 1 do begin
1074  //              Body.SaveToFile(GikoSys.GetSubjectFileName(Board.BBSID));                                  if( Board.Items[i].AgeSage = gasNull )and (Board.Items[i].IsLogFile) then begin
1075                  GikoSys.ForceDirectoriesEx(ExtractFilePath(Board.GetSubjectFileName));                                          inc(NumCount);
1076                  Body.SaveToFile(Board.GetSubjectFileName);                                          Board.Items[i].No := NumCount;
1077                                            Board.Items[i].AllResCount := Board.Items[i].Count;
1078                                            Board.Items[i].NewResCount := 0;
1079                                            Board.Items[i].AgeSage := gasNone;
1080                                    end;
1081                            end;
1082                            //リスト(subject.txt)を保存
1083                            GikoSys.ForceDirectoriesEx(ExtractFilePath(Board.GetSubjectFileName));
1084                            Body.SaveToFile(Board.GetSubjectFileName);
1085                    end;
1086          finally          finally
1087                  Body.Free;                  Body.Free;
                 NewList.Free;  
1088          end;          end;
1089    
1090    
1091  end;  end;
1092    
1093  {procedure TDownloadItem.SaveListFile;  {procedure TDownloadItem.SaveListFile;
# Line 1027  var Line 1184  var
1184          ini: TMemIniFile;          ini: TMemIniFile;
1185          Res: TResRec;          Res: TResRec;
1186          NewRes: Integer;          NewRes: Integer;
1187            finish : Boolean;
1188            loopCnt : Integer;
1189            KokoTxt : string;
1190            KokoIdx : Integer;
1191            NewTxt  : string;
1192            NewIdx  : Integer;
1193            LastTxt : string;
1194            LastIdx : Integer;
1195  begin  begin
         if Trim(Content) = '' then  
                 Exit;  
1196          FileName := ThreadItem.GetThreadFileName;          FileName := ThreadItem.GetThreadFileName;
         GikoSys.ForceDirectoriesEx(ExtractFilePath(FileName));  
1197    
1198  //      Cnt := 0;          if not ThreadItem.IsBoardPlugInAvailable then begin
1199          Body := TStringList.Create;                  if Trim(Content) = '' then
1200          try                          Exit;
1201  //              if FileExists(FileName) and (ResponseCode = 206) then begin  
1202                  if FileExists(FileName) and (State = gdsDiffComplete) then begin                  GikoSys.ForceDirectoriesEx(ExtractFilePath(FileName));
1203  //                      Body.Text := Content;  
1204  //                      if Body.Count > 0 then                  //      Cnt := 0;
1205  //                              Body.Delete(0);                  Body := TStringList.Create;
1206  //                      Content := Body.Text;                  NewRes := 0;
1207                          Body.LoadFromFile(FileName);                  OldCnt := 0;
1208                          OldCnt := Body.Count;                  try
1209                          Body.Text := Body.Text + Content;                  //              if FileExists(FileName) and (ResponseCode = 206) then begin
1210                          Body.SaveToFile(FileName);                          if FileExists(FileName) and (State = gdsDiffComplete) then begin
1211                          NewRes := Body.Count - OldCnt;                  //                      Body.Text := Content;
1212                          Cnt := Body.Count;                  //                      if Body.Count > 0 then
1213                  end else begin                  //                              Body.Delete(0);
1214                          Body.Text := Content;                  //                      Content := Body.Text;
1215  //                      if Body.Count > 0 then                                  loopCnt := 10;
1216  //                              Body.Delete(0);                                  repeat
1217                          Body.SaveToFile(FileName);                                          finish := true;
1218                                            try
1219                          if ThreadItem.Title = '' then begin                                                  Body.LoadFromFile(FileName);
1220                                  Res := GikoSys.DivideStrLine(Body[0]);                                                  OldCnt := Body.Count;
1221                                  ThreadItem.Title := Res.FTitle;                                                  Body.Text := Body.Text + Content;
1222                                                    Body.SaveToFile(FileName);
1223                                                    NewRes := Body.Count - OldCnt;
1224                                            except
1225                                                    on E:EFOpenError do begin
1226                                                            sleep(10);
1227                                                            finish := false;
1228                                                            Dec(loopCnt);
1229                                                    end;
1230                                            end;
1231                                    until finish and ( loopCnt > 0 );
1232                                    //Cnt := Body.Count;
1233                            end else begin
1234                                    if IsAbone then begin
1235                                            // あぼーんを検出したのでここまで読んだと新着レス番のつけなおし
1236                                            loopCnt := 10;
1237                                            repeat
1238                                                    finish := true;
1239                                                    try
1240                                                            Body.LoadFromFile(FileName);
1241                                                    except
1242                                                            on E:EFOpenError do begin
1243                                                                    sleep(10);
1244                                                                    finish := false;
1245                                                                    Dec(loopCnt);
1246                                                            end;
1247                                                    end;
1248                                            until finish and ( loopCnt > 0 );
1249                                            LastTxt := Body.Strings[ Body.Count - 1 ];
1250                                            if ThreadItem.Kokomade > 0 then begin
1251                                                    KokoTxt := Body.Strings[ ThreadItem.Kokomade - 1 ];
1252                                            end;
1253                                            if ThreadItem.NewReceive > 0 then begin
1254                                                    NewTxt := Body.Strings[ ThreadItem.NewReceive - 1 ];
1255                                            end;
1256    
1257                                            Body.Text := Content;
1258                                            Body.Find( LastTxt, LastIdx );
1259                                            OldCnt := LastIdx + 1;
1260                                            NewRes := Body.Count - OldCnt;
1261    
1262                                            if ThreadItem.Kokomade > 0 then begin
1263                                                    Body.Find( KokoTxt, KokoIdx );
1264                                                    ThreadItem.Kokomade := KokoIdx + 1;
1265                                            end;
1266                                            if ThreadItem.NewReceive > 0 then begin
1267                                                    Body.Find( NewTxt, NewIdx );
1268                                                    Inc( NewIdx );
1269                                                    if OldCnt < NewIdx then begin
1270                                                            OldCnt := NewIdx;
1271                                                            NewRes := Body.Count - NewIdx;
1272                                                    end;
1273                                            end;
1274                                    end else begin
1275                                            Body.Text := Content;
1276                                            //ThreadItem.Count := 0;
1277                                            OldCnt := 0;
1278                                            NewRes := Body.Count;
1279                                            //Cnt := Body.Count;
1280                                    end;
1281            //                      if Body.Count > 0 then
1282            //                              Body.Delete(0);
1283                                    Body.SaveToFile(FileName);
1284    
1285                                    if ThreadItem.Title = '' then begin
1286                                            Res := GikoSys.DivideStrLine(Body[0]);
1287                                            ThreadItem.Title := Res.FTitle;
1288                                    end;
1289                                    ThreadItem.Size := 0;
1290                          end;                          end;
                         ThreadItem.Size := 0;  
                         //ThreadItem.Count := 0;  
                         ThreadItem.AllResCount := 0;  
                         ThreadItem.NewResCount := 0;  
                         OldCnt := 0;  
                         NewRes := Body.Count;  
1291                          Cnt := Body.Count;                          Cnt := Body.Count;
1292                    finally
1293                            Body.Free;
1294                  end;                  end;
1295                  Cnt := Body.Count;  
1296          finally                  ThreadItem.Size := ThreadItem.Size + ContentLength;
1297                  Body.Free;                  ThreadItem.LastModified := LastModified;
1298                    ThreadItem.Count := Cnt;
1299                    //ThreadItem.AllResCount := Cnt;
1300                    ThreadItem.NewResCount := NewRes;
1301                    ThreadItem.NewReceive := OldCnt + 1;
1302          end;          end;
1303          ThreadItem.RoundDate := Now;          ThreadItem.AllResCount := ThreadItem.Count;
         ThreadItem.Size := ThreadItem.Size + ContentLength;  
         ThreadItem.LastModified := LastModified;  
         ThreadItem.Count := Cnt;  
         ThreadItem.AllResCount := Cnt;  
         ThreadItem.NewResCount := NewRes;  
1304          ThreadItem.IsLogFile := True;          ThreadItem.IsLogFile := True;
1305          ThreadItem.NewReceive := OldCnt + 1;          ThreadItem.RoundDate := Now;
1306          ThreadItem.UnRead := True;          ThreadItem.UnRead := True;
1307          ThreadItem.ParentBoard.UnRead := ThreadItem.ParentBoard.UnRead + 1;          ThreadItem.ParentBoard.UnRead := ThreadItem.ParentBoard.UnRead + 1;
1308  //      if ThreadItem.RoundNo = 6 then  //      if ThreadItem.RoundNo = 6 then

Legend:
Removed from v.1.6  
changed lines
  Added in v.1.6.2.2

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26