1 library ShitarabaJBBSPlugIn;
5 \82µ
\82½
\82ç
\82Î
\8f\88\97\9d\83\86\83j
\83b
\83g
6 $Id: ShitarabaJBBSPlugIn.dpr,v 1.31 2004/09/28 11:01:54 h677 Exp $
10 Windows, SysUtils, Classes, Math, DateUtils, Dialogs,
12 PlugInMain in 'PlugInMain.pas',
13 ThreadItem in 'ThreadItem.pas',
14 BoardItem in 'BoardItem.pas',
15 FilePath in 'FilePath.pas',
16 Y_TextConverter in 'Y_TextConverter.pas',
17 MojuUtils in '..\..\MojuUtils.pas';
22 // =========================================================================
23 // TShitarabaThreadItem
24 // =========================================================================
25 TShitarabaThreadItem = class(TThreadItem)
27 FIsTemporary : Boolean;
31 constructor Create( inInstance : DWORD );
32 destructor Destroy; override;
35 function Download : TDownloadState;
36 function StorageDownload(Path, Document : string) : TDownloadState;
37 function Write( inName : string; inMail : string; inMessage : string ) : TDownloadState;
38 function GetRes( inNo : Integer ) : string;
39 function GetDat( inNo : Integer ) : string;
40 function GetHeader( inOptionalHeader : string ) : string;
41 function GetFooter( inOptionalFooter : string ) : string;
42 function GetBoardURL : string;
43 procedure ArrangeDownloadData( start: Integer;var Data: TStringList);
46 function BrowsableURL : string;
47 function ReadURL : string;
48 function WriteURL : string;
51 // =========================================================================
52 // TShitarabaBoardItem
53 // =========================================================================
54 TShitarabaBoardItem = class(TBoardItem)
56 FIsTemporary : Boolean;
60 constructor Create( inInstance : DWORD );
61 destructor Destroy; override;
64 function Download : TDownloadState;
65 function CreateThread( inSubject : string; inName : string; inMail : string; inMessage : string ) : TDownloadState;
66 function ToThreadURL( inFileName : string ) : string;
67 procedure EnumThread( inCallBack : TBoardItemEnumThreadCallBack );
69 function SubjectURL : string;
73 LOG_DIR = 'ShitarabaJBBS\';
74 SUBJECT_NAME = 'subject.txt';
76 PLUGIN_NAME = 'ShitarabaJBBS';
79 RELEASE_VERSION = 'alpha';
82 SYNCRONIZE_MENU_CAPTION = '
\82µ
\82½
\82ç
\82ÎJBBS
\94Â
\8dX
\90V';
85 SyncronizeMenu : HMENU;
87 // =========================================================================
89 // =========================================================================
91 // *************************************************************************
92 //
\83e
\83\93\83|
\83\89\83\8a\82È
\83p
\83X
\82Ì
\8eæ
\93¾
93 // *************************************************************************
94 function TemporaryFile : string;
96 tempPath : array [0..MAX_PATH] of char;
99 GetTempPath( SizeOf(tempPath), tempPath );
101 Result := tempPath + IntToStr( Random( $7fffffff ) );
102 until not FileExists( Result );
106 // *************************************************************************
107 //
\82µ
\82½
\82ç
\82Î
\97p
\83\8d\83O
\83t
\83H
\83\8b\83_
\8eæ
\93¾
108 // *************************************************************************
109 function MyLogFolder : string;
115 if Length( folder ) = 0 then
118 Result := folder + LOG_DIR;
119 DisposeResultString(folder);
123 (*************************************************************************
124 *
\83f
\83B
\83\8c\83N
\83g
\83\8a\82ª
\91¶
\8dÝ
\82·
\82é
\82©
\83`
\83F
\83b
\83N
125 *************************************************************************)
126 function DirectoryExistsEx(const Name: string): Boolean;
130 Code := GetFileAttributes(PChar(Name));
131 Result := (Code <> -1) and (FILE_ATTRIBUTE_DIRECTORY and Code <> 0);
134 (*************************************************************************
135 *
\83f
\83B
\83\8c\83N
\83g
\83\8a\8dì
\90¬
\81i
\95¡
\90\94\8aK
\91w
\91Î
\89\9e\81j
136 *************************************************************************)
137 function ForceDirectoriesEx(Dir: string): Boolean;
140 if Length(Dir) = 0 then
141 raise Exception.Create('
\83t
\83H
\83\8b\83_
\82ª
\8dì
\90¬
\8fo
\97\88\82Ü
\82¹
\82ñ');
142 Dir := ExcludeTrailingPathDelimiter(Dir);
143 if (Length(Dir) < 3) or DirectoryExistsEx(Dir)
144 or (ExtractFilePath(Dir) = Dir) then Exit; // avoid 'xyz:\' problem.
145 Result := ForceDirectoriesEx(ExtractFilePath(Dir)) and CreateDir(Dir);
148 //
\82Æ
\82è
\82 \82¦
\82¸
\82Ì
\91ã
\97p
\95i
\82È
\82Ì
\82Å chrWhite
\82ð
\8dl
\97¶
\82µ
\82Ä
\82¢
\82È
\82¢
\82±
\82Æ
\82É
\92\8d\88Ó
\81I
\81I
\81I
149 procedure ExtractHttpFields(
150 const chrSep : TSysCharSet;
151 const chrWhite : TSysCharSet;
152 const strValue : string;
153 var strResult : TStringList;
154 unknownFlag : boolean = false
157 last, p, strLen : Integer;
160 strLen := Length( strValue );
167 if strValue[ p ] in chrSep then
169 strResult.Add( Copy( strValue, last, p - last ) );
178 strResult.Add( Copy( strValue, last, strLen - last + 1 ) );
182 \rfunction HttpEncode(
183 \r const strValue : string
191 kHexCode : array [0..15] of char = (
192 '0', '1', '2', '3', '4', '5', '6', '7',
193 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' );
196 strLen := Length( strValue );
202 case strValue[ i ] of
203 '0' .. '9', 'a' .. 'z', 'A' .. 'Z', '*', '-', '.', '@', '_':
205 strResult := strResult + strValue[ i ];
209 b := Integer( strValue[ i ] );
210 strResult := strResult + '%'
211 + kHexCode[ b div $10 ]
212 + kHexCode[ b mod $10 ];
226 // =========================================================================
228 // =========================================================================
230 // *************************************************************************
231 //
\83v
\83\89\83O
\83C
\83\93\82ª(
\90³
\82µ
\82)
\83\8d\81[
\83h
\82³
\82ê
\82½
232 // *************************************************************************
234 inInstance : DWORD //
\83v
\83\89\83O
\83C
\83\93\82Ì
\83C
\83\93\83X
\83^
\83\93\83X
238 //
\83v
\83\89\83O
\83C
\83\93\83\81\83j
\83\85\81[
\82É
\92Ç
\89Á
239 SyncronizeMenu := AddPlugInMenu( inInstance, SYNCRONIZE_MENU_CAPTION );
243 // *************************************************************************
244 //
\83v
\83\89\83O
\83C
\83\93\82Ì
\83o
\81[
\83W
\83\87\83\93\82ð
\97v
\8b\81\82³
\82ê
\82½
245 // *************************************************************************
246 procedure OnVersionInfo(
247 var outAgent : PChar; //
\83o
\81[
\83W
\83\87\83\93\82ð
\88ê
\90Ø
\8aÜ
\82Ü
\82È
\82¢
\8f\83\90\88\82È
\96¼
\8fÌ
248 var outMajor : DWORD; //
\83\81\83W
\83\83\81[
\83o
\81[
\83W
\83\87\83\93
249 var outMinor : DWORD; //
\83}
\83C
\83i
\81[
\83o
\81[
\83W
\83\87\83\93
250 var outRelease : PChar; //
\83\8a\83\8a\81[
\83X
\92i
\8aK
\96¼
251 var outRevision : DWORD //
\83\8a\83r
\83W
\83\87\83\93\83i
\83\93\83o
\81[
256 outAgent := CreateResultString( PChar( PLUGIN_NAME ) );
257 outMajor := MAJOR_VERSION;
258 outMinor := MINOR_VERSION;
259 outRelease := CreateResultString( PChar( RELEASE_VERSION ) );
260 outRevision := REVISION_VERSION;
271 // *************************************************************************
272 //
\8ew
\92è
\82µ
\82½ URL
\82ð
\82±
\82Ì
\83v
\83\89\83O
\83C
\83\93\82Å
\8eó
\82¯
\95t
\82¯
\82é
\82©
\82Ç
\82¤
\82©
273 // *************************************************************************
274 function OnAcceptURL(
275 inURL : PChar //
\94»
\92f
\82ð
\8bÂ
\82¢
\82Å
\82¢
\82é URL
276 ): TAcceptType; stdcall; // URL
\82Ì
\8eí
\97Þ
279 uriList : TStringList;
283 BBS_HOST_OLD = 'jbbs.shitaraba.com';
284 BBS_HOST_OLD2 = 'jbbs.livedoor.com';
285 BBS_HOST = 'jbbs.livedoor.jp';
286 THREAD_MARK = '/bbs/read.cgi';
290 //
\83z
\83X
\83g
\96¼
\82ª jbbs.livedoor.com
\82Å
\8fI
\82í
\82é
\8fê
\8d\87\82Í
\8eó
\82¯
\95t
\82¯
\82é
\82æ
\82¤
\82É
\82µ
\82Ä
\82¢
\82é
291 uri := TIdURI.Create( inURL );
292 uriList := TStringList.Create;
294 if (uri.Host = BBS_HOST_OLD) or (uri.Host = BBS_HOST_OLD2) then
295 uri.Host := BBS_HOST;
297 ExtractHttpFields( ['/'], [], uri.Path, uriList );
298 if (AnsiPos( BBS_HOST, uri.Host ) > 0) and (Length( uri.Host ) - AnsiPos( BBS_HOST, uri.Host ) + 1 = Length( BBS_HOST )) then begin
299 foundPos := AnsiPos( THREAD_MARK, inURL );
303 else if (uriList.Count > 2) and (AnsiPos('.html', uri.Document) > 0) then
305 else if uriList.Count > 2 then //
\8dÅ
\8cã
\82ª '/'
\82Å
\95Â
\82ß
\82ç
\82ê
\82Ä
\82é
\82È
\82ç 4
311 Result := atNoAccept;
319 Result := atNoAccept;
324 // *************************************************************************
325 //
\82µ
\82½
\82ç
\82ÎJBBS
\94Â
\8dX
\90V
326 // *************************************************************************
327 procedure OnBoardSyncronizeMenu(
328 inHandle : HMENU //
\83\81\83j
\83\85\81[
\83n
\83\93\83h
\83\8b
348 saveText : TStringList;
349 responseCode : Longint;
355 CATEGORY_INPUT = '
\83J
\83e
\83S
\83\8a\82ð
\93ü
\97Í
\82µ
\82Ä
\82
\82¾
\82³
\82¢';
356 KEYWORD_INPUT = '
\8c\9f\8dõ
\82·
\82é
\94Â
\96¼
\82ð
\93ü
\97Í
\82µ
\82Ä
\82
\82¾
\82³
\82¢';
357 SAVEPATH_SELECT = '
\95Û
\91¶
\82·
\82é
\83t
\83@
\83C
\83\8b\96¼
\82ð
\93ü
\97Í
\82µ
\82Ä
\82
\82¾
\82³
\82¢';
358 BBS_HOST = 'http://jbbs.livedoor.com/';
363 category := 'computer';
364 success := InputQuery( SYNCRONIZE_MENU_CAPTION, CATEGORY_INPUT, category );
367 keyword := InputBox( SYNCRONIZE_MENU_CAPTION, KEYWORD_INPUT, '' );
371 VersionInfo( agent, major, minor, release, revision );
373 initdir := PreferencesFolder;
374 filter := '
\82·
\82Ä
\82×
\82Ì
\83t
\83@
\83C
\83\8b (*.*)|*.*';
375 if agent = 'gikoNavi' then begin
376 if DirectoryExists( initdir + 'Board\' ) then
377 initdir := initdir + 'Board\';
378 filter := '
\94Â
\83t
\83@
\83C
\83\8b (*.txt)|*.txt';
381 DisposeResultString( agent );
382 DisposeResultString( release );
385 success := PromptForFileName( savepath, filter, 'txt', SYNCRONIZE_MENU_CAPTION, initdir, True );
389 InternalPrint( '
\94Â
\8fî
\95ñ
\82ð
\8eæ
\93¾
\92\86\82Å
\82·' );
392 BBS_HOST + 'bbs/left_menu.cgi?CATEGORY=' + category +
393 '&WORD=' + HttpEncode( SJIStoEUC( keyword ) );
395 responseCode := InternalDownload( PChar( url ), modified, tmp );
397 if (responseCode = 200) or (responseCode = 206) then begin
398 saveText := TStringList.Create;
399 saveText.Add( '[' + keyword + ']' );
400 downResult := EUCtoSJIS( tmp );
401 found := AnsiPos( '<a ', downResult );
402 while found > 0 do begin
403 downResult := Copy( downResult, found + 3, MaxInt ); // 3 = Length( '<a ' )
404 found := AnsiPos( 'href=', downResult );
408 if downResult[ found + 5 ] = '"' then begin // 5 = Length( 'href=' )
409 downResult := Copy( downResult, found + 6, MaxInt ); // 6 = Length( 'href="' )
410 found := AnsiPos( '"', downResult );
412 downResult := Copy( downResult, found + 5, MaxInt ); // 5 = Length( 'href=' )
413 found := AnsiPos( ' ', downResult );
414 found2 := AnsiPos( '>', downResult );
415 if (found = 0) or (found2 = 0) then
416 found := Max( found, found2 )
418 found := Min( found, found2 );
420 board := Copy( downResult, 1, found - 1 );
421 downResult := Copy( downResult, found, MaxInt );
423 if board = BBS_HOST then
425 if AnsiPos( '../', board ) = 1 then
426 board := BBS_HOST + Copy( board, 1 + 3, MaxInt ); // 3 = Length( '../' )
428 found := AnsiPos( '>', downResult );
431 downResult := Copy( downResult, found + 1, MaxInt ); // 1 = Length( '>' )
433 found := AnsiPos( '</a>', downResult );
436 board := Copy( downResult, 1, found - 1 ) + '=' + board;
437 downResult := Copy( downResult, found + 4, MaxInt ); // 4 = Length( '</a>' )
439 saveText.Add( board );
441 found := AnsiPos( '<a ', downResult );
443 saveText.SaveToFile( savepath );
446 InternalPrint( PChar( '
\94Â
\8fî
\95ñ
\82Ì
\8eæ
\93¾
\82É
\8e¸
\94s
\82µ
\82Ü
\82µ
\82½(' + IntToStr( responseCode ) + ')' ) );
449 DisposeResultString( tmp );
451 InternalPrint( '
\94Â
\8fî
\95ñ
\82ð
\8eæ
\93¾
\8a®
\97¹' );
453 InternalPrint( '
\94Â
\8fî
\95ñ
\82Ì
\8eæ
\93¾
\82É
\8e¸
\94s
\82µ
\82Ü
\82µ
\82½' );
458 //
\83\81\83j
\83\85\81[
\83n
\83\93\83h
\83\89
459 procedure OnPlugInMenu(
460 inHandle : HMENU //
\83\81\83j
\83\85\81[
\83n
\83\93\83h
\83\8b
464 if inHandle = SyncronizeMenu then
465 OnBoardSyncronizeMenu( inHandle );
469 // =========================================================================
470 // TShitarabaThreadItem
471 // =========================================================================
473 // *************************************************************************
474 //
\83R
\83\93\83X
\83g
\83\89\83N
\83^
475 // *************************************************************************
476 constructor TShitarabaThreadItem.Create(
481 uriList : TStringList;
486 OnDownload := Download;
490 OnGetHeader := GetHeader;
491 OnGetFooter := GetFooter;
492 OnGetBoardURL := GetBoardURL;
495 FIsTemporary := False;
499 uri := TIdURI.Create( ReadURL );
500 uriList := TStringList.Create;
502 ExtractHttpFields( ['/', '?'], [], uri.Path, uriList );
503 if (AnsiPos('.html', uri.Document) = 0) then begin //
\92Ê
\8fí
504 if uriList[ 5 ] = 'l100' then begin
505 FileName := uriList[ 4 ] + '.dat';
506 FilePath := MyLogFolder + uriList[ 2 ] + '\' + uriList[ 3 ] + '\' + uriList[ 4 ] + '.dat';
507 IsLogFile := FileExists( FilePath );
509 FileName := uriList[ 5 ] + '.dat';
510 FilePath := MyLogFolder + uriList[ 3 ] + '\' + uriList[ 4 ] + '\' + uriList[ 5 ] + '.dat';
511 IsLogFile := FileExists( FilePath );
513 end else begin //
\89ß
\8b\8e\83\8d\83O
514 //http://jbbs.livedoor.com/game/1578/storage/1086710948.html
515 FileName := Copy(uri.Document, 1, Length(uri.Document) - 5) + '.dat';
516 FilePath := MyLogFolder + CustomStringReplace(CustomStringReplace(uri.Path, '/storage', ''), '/', '\') + FileName;
517 IsLogFile := FileExists( FilePath );
527 // *************************************************************************
528 //
\83f
\83X
\83g
\83\89\83N
\83^
529 // *************************************************************************
530 destructor TShitarabaThreadItem.Destroy;
535 //
\88ê
\8e\9e\83t
\83@
\83C
\83\8b\82Ì
\8fê
\8d\87\82Í
\8dí
\8f\9c\82·
\82é
537 DeleteFile( FilePath );
543 // *************************************************************************
544 //
\8ew
\92è
\82µ
\82½ URL
\82Ì
\83X
\83\8c\83b
\83h
\82Ì
\83_
\83E
\83\93\83\8d\81[
\83h
\82ð
\8ew
\8e¦
\82³
\82ê
\82½
545 // *************************************************************************
546 function TShitarabaThreadItem.Download : TDownloadState;
550 downResult : TStringList;
551 responseCode : Longint;
552 logStream : TFileStream;
554 uriList : TStringList;
561 uri := TIdURI.Create( ReadURL );
562 if(( AnsiPos('.html', uri.Document) >0 ) and ( AnsiPos('/storage/', uri.Path) > 0 )) then begin
563 //
\89ß
\8b\8e\83\8d\83O
564 Result := StorageDownload(uri.Path, uri.Document);
567 //
\8c»
\8dÝ
\90¶
\82«
\82Ä
\82é
\83X
\83\8c\83b
\83h
568 uriList := TStringList.Create;
570 ExtractHttpFields( ['/', '?'], [], uri.Path, uriList );
571 FileName := uriList[ 5 ] + '.dat';
572 // http://jbbs.livedoor.com/bbs/rawmode.cgi/game/1578/1067968274/l100
573 // protocol://host/1/2/3/4/5/uriList.Count - 1
574 if MyLogFolder = '' then begin
575 //
\82Ç
\82±
\82É
\95Û
\91¶
\82µ
\82Ä
\82¢
\82¢
\82Ì
\82©
\95ª
\82©
\82ç
\82È
\82¢
\82Ì
\82Å
\88ê
\8e\9e\83t
\83@
\83C
\83\8b\82É
\95Û
\91¶
576 FilePath := TemporaryFile;
577 FIsTemporary := True;
579 FilePath := MyLogFolder + uriList[ 3 ] + '\' + uriList[ 4 ] + '\' + uriList[ 5 ] + '.dat';
580 FIsTemporary := False;
587 //
\95Û
\91¶
\97p
\82Ì
\83f
\83B
\83\8c\83N
\83g
\83\8a\82ð
\8c@
\82é
588 ForceDirectoriesEx( Copy( FilePath, 1, LastDelimiter( '\', FilePath ) ) );
590 //
\93Æ
\8e©
\82É
\83_
\83E
\83\93\83\8d\81[
\83h
\82â
\83t
\83B
\83\8b\83^
\83\8a\83\93\83O
\82ð
\8ds
\82í
\82È
\82¢
\8fê
\8d\87\82Í
591 // InternalDownload
\82É
\94C
\82¹
\82é
\82±
\82Æ
\82ª
\8fo
\97\88\82é
592 modified := LastModified;
593 datURL := ReadURL + IntToStr( Count + 1 ) + '-'; //
\90V
\92\85\82Ì
\82Ý
594 responseCode := InternalDownload( PChar( datURL ), modified, tmp, 0 );
597 if (responseCode = 200) or (responseCode = 206) then begin
598 downResult := TStringList.Create;
600 tmpText := CustomStringReplace( string( tmp ), '¡÷¡®', ',' );
601 downResult.Text := EUCtoSJIS( tmpText );
602 ArrangeDownloadData(Count, downResult);
603 if downResult.Count > 0 then begin
604 if FileExists( FilePath ) then
605 logStream := TFileStream.Create( FilePath, fmOpenReadWrite or fmShareDenyWrite )
607 logStream := TFileStream.Create( FilePath, fmCreate or fmShareDenyWrite );
609 logStream.Position := logStream.Size;
610 logStream.Write( PChar( downResult.Text )^, Length( downResult.Text ) );
620 Result := dsDiffComplete;
622 Size := Size + Length( downResult.Text );
623 // CGI
\82©
\82ç
\82Í
\90³
\82µ
\82¢
\93ú
\95t
\82ª
\93¾
\82ç
\82ê
\82È
\82¢
\82Ì
\82Å
\8c»
\8dÝ
\82É
\90Ý
\92è
628 NewReceive := Count + 1;
629 Count := Count + downResult.Count;
630 NewResCount := downResult.Count;
635 Result := dsNotModify;
640 end else if responseCode = 302 then begin
641 //http://jbbs.shitaraba.com/bbs/read.cgi/game/3477/1077473358/
642 //http://jbbs.shitaraba.com/game/bbs/read.cgi?BBS=3477&KEY=1077473358
643 //http://jbbs.shitaraba.com/game/3477/storage/1077473358.html
644 //
\89ß
\8b\8e\83\8d\83O
645 uri := TIdURI.Create( ReadURL );
646 uriList := TStringList.Create;
648 ExtractHttpFields( ['/', '?'], [], uri.Path, uriList );
649 URL := uri.Protocol + '://' + uri.Host +
650 '/' + uriList[3] + '/' + uriList[4] + '/storage/' + uriList[ 5 ] + '.html';
655 uri := TIdURI.Create( ReadURL );
656 Result := StorageDownload(uri.Path, uri.Document);
658 end else if responseCode = 304 then begin
659 Result := dsNotModify;
662 DisposeResultString( tmp );
667 // *************************************************************************
668 // download
\82µ
\82Ä
\82«
\82½Dat
\82Ì
\82 \82Ú
\81[
\82ñ
\82³
\82ê
\82½
\95ª
\82ð
\95â
\8f[
\82µ
\82Ä
\81A
669 //
\83\8c\83X
\90\94\82Æ
\88ê
\92v
\82·
\82é
\82æ
\82¤
\82É
\82·
\82é
670 // *************************************************************************
671 procedure TShitarabaThreadItem.ArrangeDownloadData(
672 start: Integer; //
\90V
\8bK
\81F
\82O
\81@
\92Ç
\8bL
\81F
\91O
\89ñ
\82Ü
\82Å
\82Ì
\8eæ
\93¾
\90\94
673 var Data: TStringList //Dat
\82Ì
\83f
\81[
\83^
681 while i < Data.count + start do begin
683 tmp := Copy(Data[i - start], 1 , AnsiPos('<>', Data[ i - start ] )-1 );
686 if n > i + 1 then begin
687 Data.Insert(i - start, Format('%d<><><><><><>', [i+1]));
699 // *************************************************************************
700 //
\89ß
\8b\8e\83\8d\83O
\97pDownload
\8aÖ
\90\94
701 // *************************************************************************
702 function TShitarabaThreadItem.StorageDownload(
703 Path, Document : string
708 downResult : TStringList;
709 responseCode : Longint;
710 logStream : TFileStream;
712 //uriList : TStringList;
714 tmpText, tmpLine, tmpTitle: string;
715 tmpHTML: TStringList;
717 i, j, tS, tE: Integer;
718 tmpDatToken : array[0..6] of string;
723 //uri := TIdURI.Create( ReadURL );
725 FileName := Copy(Document, 1, Length(Document) - 5) + '.dat';
726 if MyLogFolder = '' then begin
727 //
\82Ç
\82±
\82É
\95Û
\91¶
\82µ
\82Ä
\82¢
\82¢
\82Ì
\82©
\95ª
\82©
\82ç
\82È
\82¢
\82Ì
\82Å
\88ê
\8e\9e\83t
\83@
\83C
\83\8b\82É
\95Û
\91¶
728 FilePath := TemporaryFile;
729 FIsTemporary := True;
731 FilePath := MyLogFolder
732 + CustomStringReplace(CustomStringReplace(Path, '/storage', ''), '/', '\')
735 FIsTemporary := False;
741 //
\95Û
\91¶
\97p
\82Ì
\83f
\83B
\83\8c\83N
\83g
\83\8a\82ð
\8c@
\82é
742 ForceDirectoriesEx( Copy( FilePath, 1, LastDelimiter( '\', FilePath ) ) );
746 //
\93Æ
\8e©
\82É
\83_
\83E
\83\93\83\8d\81[
\83h
\82â
\83t
\83B
\83\8b\83^
\83\8a\83\93\83O
\82ð
\8ds
\82í
\82È
\82¢
\8fê
\8d\87\82Í
747 // InternalDownload
\82É
\94C
\82¹
\82é
\82±
\82Æ
\82ª
\8fo
\97\88\82é
748 modified := LastModified;
751 responseCode := InternalDownload( PChar( datURL ), modified, tmp, 0 );
754 if (responseCode = 200) or (responseCode = 206) then begin
755 downResult := TStringList.Create;
757 tmpText := CustomStringReplace( string( tmp ), '¡÷¡®', ',' );
761 //**
\82±
\82±
\82ÅHTML
\83t
\83@
\83C
\83\8b\82ð
\82µ
\82½
\82ç
\82ÎJBBS
\82Ìdat
\8c`
\8e®
\82É
\95Ï
\8a·
\82·
\82é
762 tmpHTML := TStringList.Create;
765 tmpHTML.Text := EUCtoSJIS( tmpText );
767 for i := 0 to tmpHTML.Count - 1 do begin
768 tmpLine := AnsiLowerCase(tmpHTML[i]);
769 tS := AnsiPos('<title>', tmpLine);
770 tE := AnsiPos('</title>', tmpLine);
773 if tE - tS = 1 then begin
776 tmpTitle := Copy(tmpHTML[i], ts + 7, Length(tmpHTML[i]));
777 tmpLine := AnsiLowerCase(tmpTitle);
778 tE := AnsiPos('</title>', tmpLine);
781 tmpTitle := Copy(tmpTitle, 1, tE - 1);
784 tmpLine := AnsiLowerCase(tmpHTML[j]);
785 tE := AnsiPos('</title>', tmpLine);
786 tmpTitle := tmpTitle + tmpHTML[j];
787 while( tE = 0 ) do begin
789 if j = tmpHTML.Count then break;
790 tmpLine := AnsiLowerCase(tmpHTML[j]);
791 tE := AnsiPos('</title>', tmpLine);
792 tmpTitle := tmpTitle + tmpHTML[j];
794 if tE = 0 then tmpTitle := ''
796 tmpLine := AnsiLowerCase(tmpTitle);
797 tE := AnsiPos('</title>', tmpLine);
798 tmpTitle := Copy(tmpTitle, 1, tE - 1);
806 //
\96{
\95¶
\82Ì
\8eæ
\93¾ <DL>
\82Ì
\8e\9f\82Ì
\8ds
\82©
\82ç</DL>
\82Ì
\91O
\82Ì
\8ds
\82Ü
\82Å
807 for i := tmpHTML.Count - 1 downto 0 do begin
808 tmpLine := AnsiLowerCase(tmpHTML[i]);
809 tE := AnsiPos('</dl>', tmpLine);
811 tmpHTML[i] := COpy(tmpHTML[i], 1, tE -1);
817 for i := 0 to tmpHTML.Count - 1 do begin
818 tmpLine := AnsiLowerCase(tmpHTML[i]);
819 tS := AnsiPos('<dl>', tmpLine);
825 for i := j downto 0 do
828 //<DD><DT>
\82»
\82ê
\82¼
\82ê
\88ê
\8ds
\82É
\95Ï
\8a·
\82·
\82é
829 for i := tmpHTML.Count - 1 downto 1 do begin
830 tmpLine := AnsiLowerCase(tmpHTML[i]);
831 if (AnsiPos('<dd>', tmpLine) = 0) and (AnsiPos('<dt>', tmpLine) = 0) then begin
832 tmpLine := CustomStringReplace(tmpHTML[i-1], #13#10, '') +
833 CustomStringReplace(tmpHTML[i], #13#10, '');
834 tmpHTML.Insert(i-1, tmpLine);
835 tmpHTML.Delete(i + 1);
839 //
\8fã
\82Ü
\82Å
\82Ì
\8f\88\97\9d\82Å
\88È
\89º
\82Ì
\82æ
\82¤
\82È
\8c`
\82É
\82È
\82Á
\82Ä
\82é
840 //<dt><a name="958">958 </a>
\96¼
\91O
\81F<font color="#008800"><b>
\96¼
\82à
\96³
\82«
\8cR
\8et </b></font>
\93\8a\8de
\93ú
\81F 2004/06/30(
\90\85) 15:17 [ r1FsjJhA ]<br><dd>
\81`
\81`
841 //<dt><a name="951">951 </a>
\96¼
\91O
\81F<a href="mailto:sage"><b>
\96¼
\82à
\96³
\82«
\8cR
\8et </B></a>
\93\8a\8de
\93ú
\81F 2004/06/30(
\90\85) 12:31 [ .oGr0rtc ]<br><dd>
\81`
\81`
842 //
\8fã
\82Ì
\82æ
\82¤
\82È
\82Ì
\82ð
\89º
\82Ì
\82æ
\82¤
\82Èdat
\82Ì
\8c`
\8e®
\82É
\95Ï
\8a·
\82·
\82é
843 //
\83\8c\83X
\94Ô
\8d\86<><font color=#FF0000>HN</font><>
\83\81\83\8b\97\93<>
\93ú
\95t
\8e\9e\8d\8f<>
\96{
\95¶<>
\83^
\83C
\83g
\83\8b\81i
\82P
\82Ì
\82Ý
\81j<>ID
844 //2<>
\96¼
\82à
\96³
\82«
\8cR
\8et<>sage<>2004/06/22(
\89Î) 09:05<>
\82Q
\82°
\82Æ
\81[<><>26bmLAzg
845 for i := 0 to tmpHTML.Count - 1 do begin
846 tmpDatToken[0] := ''; tmpDatToken[1] := ''; tmpDatToken[2] := '';
847 tmpDatToken[3] := ''; tmpDatToken[4] := ''; tmpDatToken[6] := '';
848 //==
\82Ü
\82¸
\82Í
\96{
\95¶
\82ð
\8eæ
\93¾==//
849 tmpLine := AnsiLowerCase(tmpHTML[i]);
850 tS := AnsiPos('<dd>', tmpLine);
852 tmpDatToken[4] := Copy(tmpHTML[i], tS + 4, Length(tmpHTML[i]));
853 tmpHTML[i] := Copy(tmpHTML[i], 1, tS -1);
855 tmpDatToken[4] := '';
856 //====================//
857 //==
\83\8c\83X
\94Ô
\8d\86\8eæ
\93¾==//
858 tmpLine := AnsiLowerCase(tmpHTML[i]);
859 tS := AnsiPos('">', tmpLine);
860 tE := AnsiPos('</a>', tmpLine);
861 if tE > tS then begin
862 tmpDatToken[0] := Copy(tmpHTML[i], tS + 2, tE - (tS + 2) - 1);
863 tmpDatToken[0] := Trim(tmpDatToken[0]);
864 tmpHTML[i] := Copy(tmpHTML[i], tE + 4, Length(tmpHTML[i]));
866 tmpDatToken[0] := IntToStr(i);
867 tS := AnsiPos('<', tmpHTML[i]);
869 tmpHTML[i] := Copy(tmpHTML[i], tS, Length(tmpHTML[i]));
871 //====================//
872 //==
\83\81\83\8b\97\93\8eæ
\93¾==//
873 tmpLine := AnsiLowerCase(tmpHTML[i]);
874 tS := AnsiPos('<a href="mailto:', tmpLine);
875 if tS > 0 then begin //
\83\81\83\8b\97\93\83A
\83\8a
876 tE := AnsiPos('">', tmpLine);
877 tmpDatToken[2] := Copy(tmpHTML[i], tS + 16, tE - (tS + 16));
878 tmpHTML[i] := Copy(tmpHTML[i], tE + 5, Length(tmpHTML[i]));
879 tmpHTML[i] := CustomStringReplace(tmpHTML[i], '</a>', '', true);
880 end else begin //
\83\81\83\8b\97\93\96³
\82µ
881 tmpDatToken[2] := '';
883 //====================//
885 tmpLine := AnsiLowerCase(tmpHTML[i]);
886 tE := AnsiPos('
\93\8a\8de
\93ú
\81F', tmpLine);
888 tmpDatToken[1] := Trim(Copy(tmpHTML[i], 1, tE - 1 ));
889 tmpDatToken[1] := CustomStringReplace(tmpDatToken[1], '<b>', '', true);
890 tmpDatToken[1] := CustomStringReplace(tmpDatToken[1], '</b>', '', true);
891 tmpHTML[i] := Copy(tmpHTML[i], tE + 8, Length(tmpHTML[i]));
893 tmpDatToken[1] := '';
895 //====================//
896 //==
\93ú
\95t
\8e\9e\8d\8f\82Ì
\8eæ
\93¾==//
897 tmpLine := AnsiLowerCase(tmpHTML[i]);
898 tE := AnsiPos('[', tmpLine);
900 tmpDatToken[3] := Trim(Copy(tmpHTML[i], 1, tE - 1 ));
901 tmpHTML[i] := Copy(tmpHTML[i], tE + 1, Length(tmpHTML[i]));
903 tmpDatToken[3] := '';
905 //====================//
906 //==ID
\82Ì
\8eæ
\93¾==//
907 tmpLine := AnsiLowerCase(tmpHTML[i]);
908 tE := AnsiPos(']', tmpLine);
910 tmpDatToken[6] := Trim(Copy(tmpHTML[i], 1, tE - 1 ));
912 tmpDatToken[6] := '';
914 //====================//
915 tS := StrToIntDef(tmpDatToken[0], -1);
917 tmpLine := tmpDatToken[0] + '<>' + tmpDatToken[1] + '<>' + tmpDatToken[2] + '<>' +
918 tmpDatToken[3] + '<>' + tmpDatToken[4] + '<>' + tmpTitle + '<>' + tmpDatToken[6]
920 tmpLine := tmpDatToken[0] + '<>' + tmpDatToken[1] + '<>' +tmpDatToken[2] + '<>' +
921 tmpDatToken[3] + '<>' + tmpDatToken[4] + '<><>' + tmpDatToken[6];
922 tmpHTML[i] := tmpLine;
928 downResult.Text := tmpHTML.Text;
933 ArrangeDownloadData(Count, downResult);
935 if downResult.Count > 0 then begin
936 if FileExists( FilePath ) then
937 DeleteFile(FilePath);
939 logStream := TFileStream.Create( FilePath, fmCreate or fmShareDenyWrite );
941 logStream.Position := 0;
942 logStream.Write( PChar( downResult.Text )^, Length( downResult.Text ) );
948 Result := dsComplete;
950 Size := Length( downResult.Text );
951 // CGI
\82©
\82ç
\82Í
\90³
\82µ
\82¢
\93ú
\95t
\82ª
\93¾
\82ç
\82ê
\82È
\82¢
\82Ì
\82Å
\8c»
\8dÝ
\82É
\90Ý
\92è
957 Count := downResult.Count;
958 NewResCount := downResult.Count;
959 //http://jbbs.livedoor.com/bbs/read.cgi/game/1578/1086710948/l100
960 //http://jbbs.livedoor.com/game/1578/storage/1086710948.html
961 //URL := 'http://jbbs.livedoor.com/bbs/read.cgi' +
962 // CustomStringReplace(Path, '/storage', '')
964 DownloadHost := 'storage';
966 Result := dsNotModify;
971 end else if responseCode = 304 then begin
972 Result := dsNotModify;
975 DisposeResultString( tmp );
980 // *************************************************************************
981 //
\8f\91\82«
\8d\9e\82Ý
\82ð
\8ew
\8e¦
\82³
\82ê
\82½
982 // *************************************************************************
983 function TShitarabaThreadItem.Write(
984 inName : string; //
\96¼
\91O(
\83n
\83\93\83h
\83\8b)
985 inMail : string; //
\83\81\81[
\83\8b\83A
\83h
\83\8c\83X
986 inMessage : string //
\96{
\95¶
987 ) : TDownloadState; //
\8f\91\82«
\8d\9e\82Ý
\82ª
\90¬
\8c÷
\82µ
\82½
\82©
\82Ç
\82¤
\82©
992 uriList : TStringList;
993 responseCode : Integer;
996 uri := TIdURI.Create( URL );
997 uriList := TStringList.Create;
999 ExtractHttpFields( ['/', '?'], [], uri.Path, uriList );
1001 // http://jbbs.livedoor.com/bbs/read.cgi/game/1578/1067968274/l100
1003 'NAME=' + HttpEncode( SJIStoEUC( inName ) ) +
1004 '&MAIL=' + HttpEncode( SJIStoEUC( inMail ) ) +
1005 '&MESSAGE=' + HttpEncode( SJIStoEUC( inMessage ) ) +
1006 '&BBS=' + uriList[ 4 ] +
1007 '&KEY=' + uriList[ 5 ] +
1008 '&DIR=' + uriList[ 3 ] +
1009 '&TIME=' + IntToStr( DateTimeToUnix( Now ) ) +
1010 '&submit=' + HttpEncode( SJIStoEUC( '
\8f\91\82«
\8d\9e\82Þ' ) );
1012 //
\93Æ
\8e©
\82É
\92Ê
\90M
\82µ
\82È
\82¢
\8fê
\8d\87\82Í InternalPost
\82É
\94C
\82¹
\82é
\82±
\82Æ
\82ª
\8fo
\97\88\82é
1013 responseCode := InternalPost( PChar( WriteURL ), PChar( postData ), postResult );
1015 if (responseCode = 200) or
1016 ((responseCode = 302) and (Length( Trim( postResult ) ) = 0)) then begin
1017 Result := dsComplete
1020 if Assigned( InternalPrint ) then
1021 InternalPrint( postResult );
1024 DisposeResultString( postResult );
1033 // *************************************************************************
1034 //
\83\8c\83X
\94Ô
\8d\86 inNo
\82É
\91Î
\82·
\82é html
\82ð
\97v
\8b\81\82³
\82ê
\82½
1035 // *************************************************************************
1036 function TShitarabaThreadItem.GetRes(
1037 inNo : Integer //
\97v
\8b\81\82³
\82ê
\82½
\83\8c\83X
\94Ô
\8d\86
1038 ) : string; //
\91Î
\89\9e\82·
\82é HTML
1044 //
\93Æ
\8e©
\82É
\83t
\83B
\83\8b\83^
\83\8a\83\93\83O
\82ð
\8ds
\82í
\82È
\82¢
\8fê
\8d\87\82Í
1045 // InternalAbon
\82¨
\82æ
\82Ñ Dat2HTML
\82É
\94C
\82¹
\82é
\82±
\82Æ
\82ª
\8fo
\97\88\82é
1048 if FDat = nil then begin
1049 //
\83\8d\83O
\82É
\91¶
\8dÝ
\82µ
\82È
\82¢
\82Ì
\82Å
\82±
\82Ì
\82Ü
\82Ü
\8fI
\97¹
1053 res := Copy( FDat[ inNo - 1 ], AnsiPos( '<>', FDat[ inNo - 1 ] ) + 2, MaxInt );
1055 res := GetDat( inNo );
1056 if res = '' then begin
1060 tmp := InternalAbonForOne( PChar( res ), PChar( FilePath ),inNo );
1062 Result := Dat2HTML( string( tmp ), inNo );
1064 DisposeResultString( tmp );
1070 // *************************************************************************
1071 //
\83\8c\83X
\94Ô
\8d\86 inNo
\82É
\91Î
\82·
\82é Dat
\82ð
\97v
\8b\81\82³
\82ê
\82½
1072 // *************************************************************************
1073 function TShitarabaThreadItem.GetDat(
1074 inNo : Integer //
\97v
\8b\81\82³
\82ê
\82½
\83\8c\83X
\94Ô
\8d\86
1075 ) : string; //
\82Q
\82¿
\82á
\82ñ
\82Ë
\82é
\82ÌDat
\8c`
\8e®
1078 tmp : array[1..5] of string;
1083 //
\93Æ
\8e©
\82É
\83t
\83B
\83\8b\83^
\83\8a\83\93\83O
\82ð
\8ds
\82í
\82È
\82¢
\8fê
\8d\87\82Í
1084 // InternalAbon
\82¨
\82æ
\82Ñ Dat2HTML
\82É
\94C
\82¹
\82é
\82±
\82Æ
\82ª
\8fo
\97\88\82é
1086 if (FDat = nil) or (inNo - 1 < 0 ) or (inNo - 1 >= FDat.Count) then begin
1087 //
\83\8d\83O
\82É
\91¶
\8dÝ
\82µ
\82È
\82¢
\82Ì
\82Å
\82±
\82Ì
\82Ü
\82Ü
\8fI
\97¹
1092 res := Copy( FDat[ inNo - 1 ], AnsiPos( '<>', FDat[ inNo - 1 ] ) + 2, MaxInt );
1093 //
\96\96\94ö
\82ÉID
\82ª
\95\
\8e¦
\82³
\82ê
\82Ä
\82¢
\82é
\82Ì
\82Å
\82»
\82ê
\82ð
\93\8a\8de
\93ú
\82Ì
\82Æ
\82±
\82ë
\82É
\93ü
\82ê
\82é
1094 //
\96¼
\91O<>
\83\81\81[
\83\8b<>
\93ú
\95t<>
\96{
\95¶<>
\83X
\83\8c\83^
\83C<>ID
1095 for i := 0 to 4 do begin
1096 tmp[ i + 1 ] := Copy( res, 1, AnsiPos('<>', res) - 1 );
1097 Delete( res, 1, AnsiPos('<>', res) + 1 );
1099 //
\96¼
\91O<>
\83\81\81[
\83\8b<>
\93ú
\95tID<>
\96{
\95¶<>
\83X
\83\8c\83^
\83C
1100 pTmp := CreateResultString(tmp[1] + '<>' + tmp[2] + '<>' + tmp[3] + ' ' + res + '<>'+ tmp[4] + '<>' +tmp[5]);
1101 Result := string(pTmp);
1103 DisposeResultString(pTmp);
1108 // *************************************************************************
1109 //
\83X
\83\8c\83b
\83h
\82Ì
\83w
\83b
\83_ html
\82ð
\97v
\8b\81\82³
\82ê
\82½
1110 // *************************************************************************
1111 function TShitarabaThreadItem.GetHeader(
1112 inOptionalHeader : string
1116 //
\93Æ
\8e©
\82É
\83t
\83B
\83\8b\83^
\83\8a\83\93\83O
\82ð
\8ds
\82í
\82È
\82¢
\8fê
\8d\87\82Í
1117 // InternalHeader
\82É
\94C
\82¹
\82é
\82±
\82Æ
\82ª
\8fo
\97\88\82é
1118 Result := InternalHeader(
1119 '<meta http-equiv="Content-type" content="text/html; charset=Shift_JIS">' +
1123 // GetRes
\82ð
\8cÄ
\82Î
\82ê
\82é
\82±
\82Æ
\82ª
\97\
\91z
\82³
\82ê
\82é
\82Ì
\82Å FDat
\82ð
\90¶
\90¬
\82µ
\82Ä
\82¨
\82
1132 // *************************************************************************
1133 //
\83X
\83\8c\83b
\83h
\82Ì
\83t
\83b
\83^ html
\82ð
\97v
\8b\81\82³
\82ê
\82½
1134 // *************************************************************************
1135 function TShitarabaThreadItem.GetFooter(
1136 inOptionalFooter : string
1140 //
\93Æ
\8e©
\82É
\83t
\83B
\83\8b\83^
\83\8a\83\93\83O
\82ð
\8ds
\82í
\82È
\82¢
\8fê
\8d\87\82Í
1141 // InternalFooter
\82É
\94C
\82¹
\82é
\82±
\82Æ
\82ª
\8fo
\97\88\82é
1142 Result := InternalFooter( inOptionalFooter );
1144 //
\82à
\82¤ GetRes
\82Í
\8cÄ
\82Î
\82ê
\82È
\82¢
\82Æ
\8ev
\82¤
\82Ì
\82Å FDat
\82ð
\8aJ
\95ú
\82µ
\82Ä
\82¨
\82
1152 // *************************************************************************
1153 //
\82±
\82Ì ThreadItem
\82ª
\91®
\82·
\82é
\94Â
\82Ì URL
\82ð
\97v
\8b\81\82³
\82ê
\82½
1154 // *************************************************************************
1155 function TShitarabaThreadItem.GetBoardURL : string;
1158 uriList : TStringList;
1161 BBS_HOST_OLD = 'jbbs.shitaraba.com';
1162 BBS_HOST_OLD2 = 'jbbs.livedoor.com';
1163 BBS_HOST = 'jbbs.livedoor.jp';
1166 uri := TIdURI.Create( ReadURL );
1167 uriList := TStringList.Create;
1169 ExtractHttpFields( ['/', '?'], [], uri.Path, uriList );
1171 tmphost := uri.Host;
1173 if (tmphost = BBS_HOST_OLD) or (tmphost = BBS_HOST_OLD2) then
1174 tmphost := BBS_HOST;
1176 if( AnsiPos('.html', uri.Document) = 0 ) then begin //
\92Ê
\8fí
1177 FileName := uriList[ 5 ] + '.dat';
1178 // http://jbbs.livedoor.com/bbs/read.cgi/computer/351/1090404452/l100
1179 // http://jbbs.livedoor.com/bbs/read.cgi/game/1578/1067968274/l100
1180 // http://jbbs.livedoor.com/game/1000/subject.txt
1181 Result := CreateResultString(
1182 uri.Protocol + '://' + tmphost + '/' + uriList[ 3 ] + '/' + uriList[ 4 ] + '/' );
1184 //http://jbbs.livedoor.com/game/1578/storage/1086710948.html
1185 Result := CreateResultString(
1186 uri.Protocol + '://' + tmphost + CustomStringReplace(uri.Path, '/storage', ''));
1196 // *************************************************************************
1197 // FDat
\82Ì
\90¶
\90¬
1198 // *************************************************************************
1199 procedure TShitarabaThreadItem.LoadDat;
1202 if FDat = nil then begin
1203 if IsLogFile then begin
1204 // dat
\82Ì
\93Ç
\82Ý
\8d\9e\82Ý
1205 FDat := TStringList.Create;
1206 FDat.LoadFromFile( FilePath );
1212 // *************************************************************************
1213 // FDat
\82Ì
\8aJ
\95ú
1214 // *************************************************************************
1215 procedure TShitarabaThreadItem.FreeDat;
1218 if FDat <> nil then begin
1225 // *************************************************************************
1226 //
\88À
\91S
\82È
\83u
\83\89\83E
\83U
\95\
\8e¦
\97p
\82Ì URL
1227 // *************************************************************************
1228 function TShitarabaThreadItem.BrowsableURL : string;
1230 THREAD_MARK = '/bbs/read.cgi';
1233 uriList : TStringList;
1235 dir, tmphost : string;
1237 BBS_HOST_OLD = 'jbbs.shitaraba.com';
1238 BBS_HOST_OLD2 = 'jbbs.livedoor.com';
1239 BBS_HOST = 'jbbs.livedoor.jp';
1242 foundPos := AnsiPos( '?', URL );
1243 if foundPos > 0 then begin
1245 uri := TIdURI.Create( URL );
1246 uriList := TStringList.Create;
1248 ExtractHttpFields( ['/'], [], uri.Path, uriList );
1249 dir := uriList[ 1 ];
1251 tmphost := uri.Host;
1252 if (tmphost = BBS_HOST_OLD) or (tmphost = BBS_HOST_OLD2) then
1253 tmphost := BBS_HOST;
1255 ExtractHttpFields( ['&'], [], Copy( URL, foundPos + 1, MaxInt ), uriList );
1257 uri.Protocol + '://' + tmphost + '/bbs/read.cgi/' +
1258 dir + '/' + uriList.Values[ 'BBS' ] + '/' + uriList.Values[ 'KEY' ] + '/l100';
1264 if Copy( URL, Length( URL ), 1 ) = '/' then
1265 uri := TIdURI.Create( URL )
1267 uri := TIdURI.Create( URL + '/' );
1269 uriList := TStringList.Create;
1271 ExtractHttpFields( ['/'], [], uri.Path, uriList );
1273 tmphost := uri.Host;
1274 if (tmphost = BBS_HOST_OLD) or (tmphost = BBS_HOST_OLD2) then
1275 tmphost := BBS_HOST;
1277 if( AnsiPos(THREAD_MARK, URL) > 0) and (uriList.Count > 5) then begin
1279 uri.Protocol + '://' + tmphost + THREAD_MARK + '/' +
1280 uriList[ 3 ] + '/' + uriList[ 4 ] + '/' + uriList[ 5 ] + '/l100';
1282 end else if AnsiPos(THREAD_MARK, URL) = 0 then begin
1283 //
\83R
\83R
\82Å
\89ß
\8b\8e\83\8d\83O
\82©
\82Ç
\82¤
\82©
\83`
\83F
\83b
\83N
\81H
1284 if(AnsiPos('.html/', uri.Path) > 0) then begin
1285 Result := uri.Protocol + '://' + tmphost + Copy(uri.Path, 1, Length(uri.Path) - 1);
1297 // *************************************************************************
1298 //
\88À
\91S
\82È( '/'
\82Å
\8fI
\82í
\82é )
\93Ç
\82Ý
\8d\9e\82Ý
\82Ì URL
1299 // *************************************************************************
1300 function TShitarabaThreadItem.ReadURL : string;
1302 THREAD_MARK = '/bbs/read.cgi';
1305 uriList : TStringList;
1307 dir, tmphost : string;
1309 BBS_HOST_OLD = 'jbbs.shitaraba.com';
1310 BBS_HOST_OLD2 = 'jbbs.livedoor.com';
1311 BBS_HOST = 'jbbs.livedoor.jp';
1314 foundPos := AnsiPos( '?', URL );
1315 if foundPos > 0 then begin
1317 uri := TIdURI.Create( URL );
1318 uriList := TStringList.Create;
1320 ExtractHttpFields( ['/'], [], uri.Path, uriList );
1321 dir := uriList[ 1 ];
1323 tmphost := uri.Host;
1324 if (tmphost = BBS_HOST_OLD) or (tmphost = BBS_HOST_OLD2) then
1325 tmphost := BBS_HOST;
1327 ExtractHttpFields( ['&'], [], Copy( URL, foundPos + 1, MaxInt ), uriList );
1328 // http://jbbs.livedoor.com/bbs/read.cgi?DIR=game&BBS=1578&KEY=1067968274
1330 uri.Protocol + '://' + tmphost + '/bbs/rawmode.cgi/' +
1331 dir + '/' + uriList.Values[ 'BBS' ] + '/' + uriList.Values[ 'KEY' ] + '/';
1337 if Copy( URL, Length( URL ), 1 ) = '/' then
1338 uri := TIdURI.Create( URL )
1340 uri := TIdURI.Create( URL + '/' );
1341 uriList := TStringList.Create;
1343 ExtractHttpFields( ['/'], [], uri.Path, uriList );
1345 tmphost := uri.Host;
1346 if (tmphost = BBS_HOST_OLD) or (tmphost = BBS_HOST_OLD2) then
1347 tmphost := BBS_HOST;
1348 // http://jbbs.livedoor.com/bbs/read.cgi/game/1578/1067968274/l100
1349 if( AnsiPos(THREAD_MARK, URL) > 0) and (uriList.Count > 5) then begin
1351 uri.Protocol + '://' + tmphost + '/bbs/rawmode.cgi/' +
1352 uriList[ 3 ] + '/' + uriList[ 4 ] + '/' + uriList[ 5 ] + '/';
1353 end else if AnsiPos(THREAD_MARK, URL) = 0 then begin
1354 //
\83R
\83R
\82Å
\89ß
\8b\8e\83\8d\83O
\82©
\82Ç
\82¤
\82©
\83`
\83F
\83b
\83N
\81H
1355 if(AnsiPos('.html/', uri.Path) > 0) then begin
1356 Result := uri.Protocol + '://' + tmphost + Copy(uri.Path, 1, Length(uri.Path) - 1);
1368 // *************************************************************************
1369 //
\88À
\91S
\82È( '/'
\82Å
\8fI
\82í
\82é )
\8f\91\82«
\8d\9e\82Ý
\82Ì URL
1370 // *************************************************************************
1371 function TShitarabaThreadItem.WriteURL : string;
1374 uriList : TStringList;
1377 if Copy( URL, Length( URL ), 1 ) = '/' then
1378 uri := TIdURI.Create( URL )
1380 uri := TIdURI.Create( URL + '/' );
1381 uriList := TStringList.Create;
1383 ExtractHttpFields( ['/', '?'], [], uri.Path, uriList );
1384 // http://jbbs.livedoor.com/bbs/read.cgi/game/1578/1067968274/l100
1386 uri.Protocol + '://' + uri.Host + '/bbs/write.cgi/' +
1387 uriList[ 3 ] + '/' + uriList[ 4 ] + '/' + uriList[ 5 ] + '/';
1395 // *************************************************************************
1396 // TThreadItem
\82ª
\90¶
\90¬
\82³
\82ê
\82½
\8fê
\8d\87\82Ì
\8f\88\92u(TShitarabaThreadItem
\82ð
\90¶
\90¬
\82·
\82é)
1397 // *************************************************************************
1398 procedure ThreadItemOnCreateOfTShitarabaThreadItem(
1402 threadItem : TShitarabaThreadItem;
1405 threadItem := TShitarabaThreadItem.Create( inInstance );
1406 ThreadItemSetLong( inInstance, tipContext, DWORD( threadItem ) );
1410 // *************************************************************************
1411 // TThreadItem
\82ª
\94j
\8aü
\82³
\82ê
\82½
\8fê
\8d\87\82Ì
\8f\88\92u(TShitarabaThreadItem
\82ð
\94j
\8aü
\82·
\82é)
1412 // *************************************************************************
1413 procedure ThreadItemOnDisposeOfTShitarabaThreadItem(
1417 threadItem : TShitarabaThreadItem;
1420 threadItem := TShitarabaThreadItem( ThreadItemGetLong( inInstance, tipContext ) );
1425 // =========================================================================
1426 // TShitarabaBoardItem
1427 // =========================================================================
1429 // *************************************************************************
1430 //
\83R
\83\93\83X
\83g
\83\89\83N
\83^
1431 // *************************************************************************
1432 constructor TShitarabaBoardItem.Create(
1437 uriList : TStringList;
1439 BBS_HOST_OLD = 'jbbs.shitaraba.com';
1440 BBS_HOST_OLD2 = 'jbbs.livedoor.com';
1441 BBS_HOST = 'jbbs.livedoor.jp';
1446 OnDownload := Download;
1447 OnCreateThread := CreateThread;
1448 OnEnumThread := EnumThread;
1449 OnFileName2ThreadURL := ToThreadURL;
1452 FIsTemporary := False;
1455 uri := TIdURI.Create( SubjectURL );
1456 uriList := TStringList.Create;
1458 if (uri.Host = BBS_HOST_OLD) or (uri.Host = BBS_HOST_OLD2) then
1459 uri.Host := BBS_HOST;
1460 URL := uri.Protocol + '://' + uri.Host + uri.Path;
1462 ExtractHttpFields( ['/', '?'], [], uri.Path, uriList );
1463 // http://jbbs.livedoor.com/game/1000/subject.txt
1464 FilePath := MyLogFolder + uriList[ 1 ] + '\' + uriList[ 2 ] + '\' + uri.Document;
1465 IsLogFile := FileExists( FilePath );
1473 // *************************************************************************
1474 //
\83f
\83X
\83g
\83\89\83N
\83^
1475 // *************************************************************************
1476 destructor TShitarabaBoardItem.Destroy;
1479 if FDat <> nil then begin
1487 //
\88ê
\8e\9e\83t
\83@
\83C
\83\8b\82Ì
\8fê
\8d\87\82Í
\8dí
\8f\9c\82·
\82é
1488 if FIsTemporary then
1489 DeleteFile( FilePath );
1495 // *************************************************************************
1496 //
\8ew
\92è
\82µ
\82½
\83X
\83\8c\88ê
\97\97\82Ì
\83_
\83E
\83\93\83\8d\81[
\83h
\82ð
\97v
\8b\81\82³
\82ê
\82½
1497 // *************************************************************************
1498 function TShitarabaBoardItem.Download : TDownloadState;
1502 responseCode : Longint;
1504 uriList : TStringList;
1511 if FDat <> nil then begin
1518 FDat := TStringList.Create;
1519 uri := TIdURI.Create( SubjectURL );
1520 uriList := TStringList.Create;
1521 //
\93Æ
\8e©
\82É
\83_
\83E
\83\93\83\8d\81[
\83h
\82â
\83t
\83B
\83\8b\83^
\83\8a\83\93\83O
\82ð
\8ds
\82í
\82È
\82¢
\8fê
\8d\87\82Í
1522 // InternalDownload
\82É
\94C
\82¹
\82é
\82±
\82Æ
\82ª
\8fo
\97\88\82é
1523 modified := LastModified;
1524 responseCode := InternalDownload( PChar( uri.URI ), modified, downResult );
1526 if responseCode = 200 then begin
1528 //
\83p
\83X
\82ð
\8eZ
\8fo
1529 ExtractHttpFields( ['/', '?'], [], uri.Path, uriList );
1530 if MyLogFolder = '' then begin
1531 //
\82Ç
\82±
\82É
\95Û
\91¶
\82µ
\82Ä
\82¢
\82¢
\82Ì
\82©
\95ª
\82©
\82ç
\82È
\82¢
\82Ì
\82Å
\88ê
\8e\9e\83t
\83@
\83C
\83\8b\82É
\95Û
\91¶
1532 FilePath := TemporaryFile;
1533 FIsTemporary := True;
1535 FilePath := MyLogFolder + uriList[ 1 ] + '\' + uriList[ 2 ] + '\' + uri.Document;
1536 FIsTemporary := False
1539 //
\95Û
\91¶
\97p
\82Ì
\83f
\83B
\83\8c\83N
\83g
\83\8a\82ð
\8c@
\82é
1540 ForceDirectoriesEx( Copy( FilePath, 1, LastDelimiter( '\', FilePath ) ) );
1542 // EUC
\82ð Shift_JIS
\82É
1543 tmpText := CustomStringReplace( string( downResult ), '¡÷¡®', ',');
1544 FDat.Text := EUCtoSJIS( tmpText );
1545 //
\82µ
\82½
\82ç
\82Î JBBS
\82Í
\83`
\83F
\83b
\83N
\97p
\82É
\90æ
\93ª
\82Æ
\8dÅ
\8fI
\8ds
\82ª
\93¯
\82¶
1546 i := FDat.Count - 1;
1547 if i > 0 then // 1
\8cÂ
\82¾
\82Á
\82½
\82ç
\8fã
\89º
\82à
\82
\82»
\82à
\96³
\82¢
\82©
\82ç 0
\82Í
\8aÜ
\82Ü
\82¸
1548 if FDat[ 0 ] = FDat[ i ] then
1551 FDat.SaveToFile( FilePath );
1555 LastModified := modified;
1561 Result := dsComplete;
1564 DisposeResultString( downResult );
1569 // *************************************************************************
1570 //
\83X
\83\8c\97§
\82Ä
\82ð
\8ew
\8e¦
\82³
\82ê
\82½
1571 // *************************************************************************
1572 function TShitarabaBoardItem.CreateThread(
1573 inSubject : string; //
\83X
\83\8c\83^
\83C
1574 inName : string; //
\96¼
\91O(
\83n
\83\93\83h
\83\8b)
1575 inMail : string; //
\83\81\81[
\83\8b\83A
\83h
\83\8c\83X
1576 inMessage : string //
\96{
\95¶
1577 ) : TDownloadState; //
\8f\91\82«
\8d\9e\82Ý
\82ª
\90¬
\8c÷
\82µ
\82½
\82©
\82Ç
\82¤
\82©
1583 uriList : TStringList;
1584 responseCode : Integer;
1587 uri := TIdURI.Create( URL );
1588 uriList := TStringList.Create;
1590 ExtractHttpFields( ['/', '?'], [], uri.Path, uriList );
1592 // http://jbbs.livedoor.com/bbs/write.cgi/game/1578/new/
1593 // http://jbbs.livedoor.com/game/1000/subject.txt
1595 uri.Protocol + '://' + uri.Host + '/bbs/write.cgi/' +
1596 uriList[ 1 ] + '/' + uriList[ 2 ] + '/new/';
1598 'SUBJECT=' + HttpEncode( SJIStoEUC( inSubject ) ) +
1599 '&NAME=' + HttpEncode( SJIStoEUC( inName ) ) +
1600 '&MAIL=' + HttpEncode( SJIStoEUC( inMail ) ) +
1601 '&MESSAGE=' + HttpEncode( SJIStoEUC( inMessage ) ) +
1602 '&BBS=' + uriList[ 4 ] +
1603 '&DIR=' + uriList[ 3 ] +
1604 '&TIME=' + IntToStr( DateTimeToUnix( Now ) ) +
1605 '&submit=' + HttpEncode( SJIStoEUC( '
\90V
\8bK
\8f\91\82«
\8d\9e\82Ý' ) );
1607 //
\93Æ
\8e©
\82É
\92Ê
\90M
\82µ
\82È
\82¢
\8fê
\8d\87\82Í InternalPost
\82É
\94C
\82¹
\82é
\82±
\82Æ
\82ª
\8fo
\97\88\82é
1608 responseCode := InternalPost( PChar( postURL ), PChar( postData ), postResult );
1610 if (responseCode = 200) or
1611 ((responseCode = 302) and (Length( Trim( postResult ) ) = 0)) then begin
1612 Result := dsComplete
1615 if Assigned( InternalPrint ) then
1616 InternalPrint( postResult );
1619 DisposeResultString( postResult );
1628 // *************************************************************************
1629 //
\83X
\83\8c\88ê
\97\97\82Ì URL
\82©
\82ç
\83X
\83\8c\83b
\83h
\82Ì URL
\82ð
\93±
\82«
\8fo
\82·
1630 // *************************************************************************
1631 function TShitarabaBoardItem.ToThreadURL(
1632 inFileName : string //
\83X
\83\8c\83b
\83h
\83t
\83@
\83C
\83\8b\96¼
1633 ) : string; //
\83X
\83\8c\83b
\83h
\82Ì URL
1637 uriList : TStringList;
1641 found := AnsiPos( '.', inFileName );
1643 inFileName := Copy( inFileName, 1, found - 1 );
1645 uri := TIdURI.Create( SubjectURL );
1646 uriList := TStringList.Create;
1649 ExtractHttpFields( ['/', '?'], [], uri.Path, uriList );
1650 threadURL := uri.Protocol + '://' + uri.Host + '/bbs/read.cgi/' +
1651 uriList[ 1 ] + '/' + uriList[ 2 ] + '/' + inFileName + '/l100';
1652 Result := threadURL;
1663 // *************************************************************************
1664 //
\82±
\82Ì
\94Â
\82É
\82¢
\82
\82Â
\82Ì
\83X
\83\8c\82ª
\82 \82é
\82©
\97v
\8b\81\82³
\82ê
\82½
1665 // *************************************************************************
1666 procedure TShitarabaBoardItem.EnumThread(
1667 inCallBack : TBoardItemEnumThreadCallBack
1671 uriList : TStringList;
1675 if FDat = nil then begin
1676 FDat := TStringList.Create;
1677 uri := TIdURI.Create( SubjectURL );
1678 uriList := TStringList.Create;
1680 //
\83p
\83X
\82ð
\8eZ
\8fo
1681 ExtractHttpFields( ['/', '?'], [], uri.Path, uriList );
1682 // http://jbbs.livedoor.com/game/1000/subject.txt
1683 FilePath := MyLogFolder + uriList[ 1 ] + '\' + uriList[ 2 ] + '\' + uri.Document;
1684 if FileExists( FilePath ) then
1685 //
\93Ç
\82Ý
\8d\9e\82Ý
1686 FDat.LoadFromFile( FilePath );
1693 //
\93Æ
\8e©
\82É
\83t
\83B
\83\8b\83^
\83\8a\83\93\83O
\82ð
\8ds
\82í
\82È
\82¢
\8fê
\8d\87\82Í EnumThread
\82É
\94C
\82¹
\82é
\82±
\82Æ
\82ª
\8fo
\97\88\82é
1694 inherited EnumThread( inCallBack, CustomStringReplace( FDat.Text, ',', '<>' ) );
1700 // *************************************************************************
1701 //
\83X
\83\8c\88ê
\97\97\82Ì URL
\82ð
\8b\81\82ß
\82é
1702 // *************************************************************************
1703 function TShitarabaBoardItem.SubjectURL : string;
1706 uriList : TStringList;
1709 uri := TIdURI.Create( URL );
1710 uriList := TStringList.Create;
1712 if uri.Document <> SUBJECT_NAME then begin
1713 if Copy( URL, Length( URL ), 1 ) = '/' then
1714 Result := URL + SUBJECT_NAME
1716 Result := URL + '/' + SUBJECT_NAME;
1718 //
\82±
\82±
\82É
\82Í
\97\88\82È
\82¢
\82Æ
\8ev
\82¤
\82¯
\82Ç
1728 // *************************************************************************
1729 // TBoardItem
\82ª
\90¶
\90¬
\82³
\82ê
\82½
\8fê
\8d\87\82Ì
\8f\88\92u(TShitarabaBoardItem
\82ð
\90¶
\90¬
\82·
\82é)
1730 // *************************************************************************
1731 procedure BoardItemOnCreateOfTShitarabaBoardItem(
1735 boardItem : TShitarabaBoardItem;
1738 boardItem := TShitarabaBoardItem.Create( inInstance );
1739 BoardItemSetLong( inInstance, bipContext, DWORD( boardItem ) );
1743 // *************************************************************************
1744 // TBoardItem
\82ª
\94j
\8aü
\82³
\82ê
\82½
\8fê
\8d\87\82Ì
\8f\88\92u(TShitarabaBoardItem
\82ð
\94j
\8aü
\82·
\82é)
1745 // *************************************************************************
1746 procedure BoardItemOnDisposeOfTShitarabaBoardItem(
1750 boardItem : TShitarabaBoardItem;
1753 boardItem := TShitarabaBoardItem( BoardItemGetLong( inInstance, bipContext ) );
1760 // =========================================================================
1761 //
\83G
\83\93\83g
\83\8a\83|
\83C
\83\93\83g
1762 // =========================================================================
1764 ul_reason_for_call : DWORD
1770 case ul_reason_for_call of
1775 module := GetModuleHandle( nil );
1777 LoadInternalAPI( module );
1778 LoadInternalFilePathAPI( module );
1779 LoadInternalThreadItemAPI( module );
1780 LoadInternalBoardItemAPI( module );
1782 // =====
\83C
\83\93\83X
\83^
\83\93\83X
\82Ì
\8eæ
\82è
\88µ
\82¢
\82ð TThreadItem
\82©
\82ç TShitarabaThreadItem
\82É
\95Ï
\8dX
\82·
\82é
1783 ThreadItemOnCreate := ThreadItemOnCreateOfTShitarabaThreadItem;
1784 ThreadItemOnDispose := ThreadItemOnDisposeOfTShitarabaThreadItem;
1785 // =====
\83C
\83\93\83X
\83^
\83\93\83X
\82Ì
\8eæ
\82è
\88µ
\82¢
\82ð TBoardItem
\82©
\82ç TShitarabaBoardItem
\82É
\95Ï
\8dX
\82·
\82é
1786 BoardItemOnCreate := BoardItemOnCreateOfTShitarabaBoardItem;
1787 BoardItemOnDispose := BoardItemOnDisposeOfTShitarabaBoardItem;
1791 RemovePlugInMenu( SyncronizeMenu );
1810 DllProc := @DLLEntry;
1811 DLLEntry( DLL_PROCESS_ATTACH );