1 library ShitarabaJBBSPlugIn;
5 \82µ
\82½
\82ç
\82Î
\8f\88\97\9d\83\86\83j
\83b
\83g
9 Windows, SysUtils, Classes, Math, DateUtils,
11 PlugInMain in 'PlugInMain.pas',
12 ThreadItem in 'ThreadItem.pas',
13 BoardItem in 'BoardItem.pas',
14 FilePath in 'FilePath.pas',
15 Y_TextConverter in 'Y_TextConverter.pas';
20 // =========================================================================
21 // TShitarabaThreadItem
22 // =========================================================================
23 TShitarabaThreadItem = class(TThreadItem)
25 FIsTemporary : Boolean;
29 constructor Create( inInstance : DWORD );
30 destructor Destroy; override;
33 function Download : TDownloadState;
34 function Write( inName : string; inMail : string; inMessage : string ) : TDownloadState;
35 function GetRes( inNo : Integer ) : string;
36 function GetHeader( inOptionalHeader : string ) : string;
37 function GetFooter( inOptionalFooter : string ) : string;
38 function GetBoardURL : string;
42 function ReadURL : string;
43 function WriteURL : string;
46 // =========================================================================
47 // TShitarabaBoardItem
48 // =========================================================================
49 TShitarabaBoardItem = class(TBoardItem)
51 FIsTemporary : Boolean;
55 constructor Create( inInstance : DWORD );
56 destructor Destroy; override;
59 function Download : TDownloadState;
60 function CreateThread( inSubject : string; inName : string; inMail : string; inMessage : string ) : TDownloadState;
61 function ToThreadURL( inFileName : string ) : string;
62 procedure EnumThread( inCallBack : TBoardItemEnumThreadCallBack );
64 function SubjectURL : string;
68 LOG_DIR = 'ShitarabaJBBS\';
69 SUBJECT_NAME = 'subject.txt';
71 PLUGIN_NAME = 'ShitarabaJBBS';
74 RELEASE_VERSION = 'beta';
75 REVISION_VERSION = 11;
77 // =========================================================================
79 // =========================================================================
81 // *************************************************************************
82 //
\83e
\83\93\83|
\83\89\83\8a\82È
\83p
\83X
\82Ì
\8eæ
\93¾
83 // *************************************************************************
84 function TemporaryFile : string;
86 tempPath : array [0..MAX_PATH] of char;
89 GetTempPath( SizeOf(tempPath), tempPath );
91 Result := tempPath + IntToStr( Random( $7fffffff ) );
92 until not FileExists( Result );
96 // *************************************************************************
97 //
\82µ
\82½
\82ç
\82Î
\97p
\83\8d\83O
\83t
\83H
\83\8b\83_
\8eæ
\93¾
98 // *************************************************************************
99 function MyLogFolder : string;
105 if Length( folder ) = 0 then
108 Result := folder + LOG_DIR;
112 (*************************************************************************
113 *
\83f
\83B
\83\8c\83N
\83g
\83\8a\82ª
\91¶
\8dÝ
\82·
\82é
\82©
\83`
\83F
\83b
\83N
114 *************************************************************************)
115 function DirectoryExistsEx(const Name: string): Boolean;
119 Code := GetFileAttributes(PChar(Name));
120 Result := (Code <> -1) and (FILE_ATTRIBUTE_DIRECTORY and Code <> 0);
123 (*************************************************************************
124 *
\83f
\83B
\83\8c\83N
\83g
\83\8a\8dì
\90¬
\81i
\95¡
\90\94\8aK
\91w
\91Î
\89\9e\81j
125 *************************************************************************)
126 function ForceDirectoriesEx(Dir: string): Boolean;
129 if Length(Dir) = 0 then
130 raise Exception.Create('
\83t
\83H
\83\8b\83_
\82ª
\8dì
\90¬
\8fo
\97\88\82Ü
\82¹
\82ñ');
131 Dir := ExcludeTrailingPathDelimiter(Dir);
132 if (Length(Dir) < 3) or DirectoryExistsEx(Dir)
133 or (ExtractFilePath(Dir) = Dir) then Exit; // avoid 'xyz:\' problem.
134 Result := ForceDirectoriesEx(ExtractFilePath(Dir)) and CreateDir(Dir);
137 //
\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
138 procedure ExtractHttpFields(
139 const chrSep : TSysCharSet;
140 const chrWhite : TSysCharSet;
141 const strValue : string;
142 var strResult : TStringList;
143 unknownFlag : boolean = false
146 last, p, strLen : Integer;
149 strLen := Length( strValue );
156 if strValue[ p ] in chrSep then
158 strResult.Add( Copy( strValue, last, p - last ) );
167 strResult.Add( Copy( strValue, last, strLen - last + 1 ) );
171 \rfunction HttpEncode(
172 \r const strValue : string
180 kHexCode : array [0..15] of char = (
181 '0', '1', '2', '3', '4', '5', '6', '7',
182 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' );
185 strLen := Length( strValue );
191 case strValue[ i ] of
192 '0' .. '9', 'a' .. 'z', 'A' .. 'Z', '*', '-', '.', '@', '_':
194 strResult := strResult + strValue[ i ];
198 b := Integer( strValue[ i ] );
199 strResult := strResult + '%'
200 + kHexCode[ b div $10 ]
201 + kHexCode[ b mod $10 ];
215 // =========================================================================
217 // =========================================================================
219 // *************************************************************************
220 //
\83v
\83\89\83O
\83C
\83\93\82Ì
\83o
\81[
\83W
\83\87\83\93\82ð
\97v
\8b\81\82³
\82ê
\82½
221 // *************************************************************************
222 procedure OnVersionInfo(
223 var outAgent : PChar; //
\83o
\81[
\83W
\83\87\83\93\82ð
\88ê
\90Ø
\8aÜ
\82Ü
\82È
\82¢
\8f\83\90\88\82È
\96¼
\8fÌ
224 var outMajor : DWORD; //
\83\81\83W
\83\83\81[
\83o
\81[
\83W
\83\87\83\93
225 var outMinor : DWORD; //
\83}
\83C
\83i
\81[
\83o
\81[
\83W
\83\87\83\93
226 var outRelease : PChar; //
\83\8a\83\8a\81[
\83X
\92i
\8aK
\96¼
227 var outRevision : DWORD //
\83\8a\83r
\83W
\83\87\83\93\83i
\83\93\83o
\81[
232 outAgent := CreateResultString( PChar( PLUGIN_NAME ) );
233 outMajor := MAJOR_VERSION;
234 outMinor := MINOR_VERSION;
235 outRelease := CreateResultString( PChar( RELEASE_VERSION ) );
236 outRevision := REVISION_VERSION;
247 // *************************************************************************
248 //
\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©
249 // *************************************************************************
250 function OnAcceptURL(
251 inURL : PChar //
\94»
\92f
\82ð
\8bÂ
\82¢
\82Å
\82¢
\82é URL
252 ): TAcceptType; stdcall; // URL
\82Ì
\8eí
\97Þ
255 uriList : TStringList;
258 BBS_HOST = 'jbbs.shitaraba.com';
259 THREAD_MARK = '/bbs/read.cgi';
263 //
\83z
\83X
\83g
\96¼
\82ª jbbs.shitaraba.com
\82Å
\8fI
\82í
\82é
\8fê
\8d\87\82Í
\8eó
\82¯
\95t
\82¯
\82é
\82æ
\82¤
\82É
\82µ
\82Ä
\82¢
\82é
264 uri := TIdURI.Create( inURL );
265 uriList := TStringList.Create;
267 ExtractHttpFields( ['/'], [], uri.Path, uriList );
268 foundPos := Pos( BBS_HOST, uri.Host );
269 if (foundPos > 0) and (Length( uri.Host ) - foundPos + 1 = Length( BBS_HOST )) then begin
270 foundPos := Pos( THREAD_MARK, inURL );
273 else if uriList.Count > 2 then //
\8dÅ
\8cã
\82ª '/'
\82Å
\95Â
\82ß
\82ç
\82ê
\82Ä
\82é
\82È
\82ç 4
278 Result := atNoAccept;
285 Result := atNoAccept;
292 // =========================================================================
293 // TShitarabaThreadItem
294 // =========================================================================
296 // *************************************************************************
297 //
\83R
\83\93\83X
\83g
\83\89\83N
\83^
298 // *************************************************************************
299 constructor TShitarabaThreadItem.Create(
304 uriList : TStringList;
309 OnDownload := Download;
312 OnGetHeader := GetHeader;
313 OnGetFooter := GetFooter;
314 OnGetBoardURL := GetBoardURL;
317 FIsTemporary := False;
320 uri := TIdURI.Create( ReadURL );
321 uriList := TStringList.Create;
323 ExtractHttpFields( ['/', '?'], [], uri.Path, uriList );
324 FileName := uriList[ 5 ] + '.dat';
325 FilePath := MyLogFolder + uriList[ 3 ] + '\' + uriList[ 4 ] + '\' + uriList[ 5 ] + '.dat';
326 IsLogFile := FileExists( FilePath );
334 // *************************************************************************
335 //
\83f
\83X
\83g
\83\89\83N
\83^
336 // *************************************************************************
337 destructor TShitarabaThreadItem.Destroy;
342 //
\88ê
\8e\9e\83t
\83@
\83C
\83\8b\82Ì
\8fê
\8d\87\82Í
\8dí
\8f\9c\82·
\82é
344 DeleteFile( FilePath );
350 // *************************************************************************
351 //
\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½
352 // *************************************************************************
353 function TShitarabaThreadItem.Download : TDownloadState;
357 downResult : TStringList;
358 responseCode : Longint;
359 logStream : TFileStream;
361 uriList : TStringList;
367 uri := TIdURI.Create( ReadURL );
368 uriList := TStringList.Create;
370 ExtractHttpFields( ['/', '?'], [], uri.Path, uriList );
371 FileName := uriList[ 5 ] + '.dat';
372 // http://jbbs.shitaraba.com/bbs/rawmode.cgi/game/1578/1067968274/l100
373 // protocol://host/1/2/3/4/5/uriList.Count - 1
374 if MyLogFolder = '' then begin
375 //
\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¶
376 FilePath := TemporaryFile;
377 FIsTemporary := True;
379 FilePath := MyLogFolder + uriList[ 3 ] + '\' + uriList[ 4 ] + '\' + uriList[ 5 ] + '.dat';
380 FIsTemporary := False;
387 //
\95Û
\91¶
\97p
\82Ì
\83f
\83B
\83\8c\83N
\83g
\83\8a\82ð
\8c@
\82é
388 ForceDirectoriesEx( Copy( FilePath, 1, LastDelimiter( '\', FilePath ) ) );
390 //
\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Í
391 // InternalDownload
\82É
\94C
\82¹
\82é
\82±
\82Æ
\82ª
\8fo
\97\88\82é
392 modified := LastModified;
393 datURL := ReadURL + IntToStr( Count + 1 ) + '-'; //
\90V
\92\85\82Ì
\82Ý
394 responseCode := InternalDownload( PChar( datURL ), modified, tmp, 0 );
397 if (responseCode = 200) or (responseCode = 206) then begin
398 downResult := TStringList.Create;
400 downResult.Text := EUCtoSJIS( string( tmp ) );
402 if downResult.Count > 0 then begin
403 if FileExists( FilePath ) then
404 logStream := TFileStream.Create( FilePath, fmOpenReadWrite or fmShareDenyWrite )
406 logStream := TFileStream.Create( FilePath, fmCreate or fmShareDenyWrite );
408 logStream.Position := logStream.Size;
409 logStream.Write( PChar( downResult.Text )^, Length( downResult.Text ) );
414 NewReceive := Count + 1;
415 Count := Count + downResult.Count;
416 NewResCount := downResult.Count;
417 Size := Size + Length( downResult.Text );
419 // CGI
\82©
\82ç
\82Í
\90³
\82µ
\82¢
\93ú
\95t
\82ª
\93¾
\82ç
\82ê
\82È
\82¢
\82Ì
\82Å
\8c»
\8dÝ
\82É
\90Ý
\92è
421 NewResCount := downResult.Count;
428 Result := dsDiffComplete;
430 Result := dsNotModify;
435 end else if responseCode = 304 then begin
436 Result := dsNotModify;
439 DisposeResultString( tmp );
444 // *************************************************************************
445 //
\8f\91\82«
\8d\9e\82Ý
\82ð
\8ew
\8e¦
\82³
\82ê
\82½
446 // *************************************************************************
447 function TShitarabaThreadItem.Write(
448 inName : string; //
\96¼
\91O(
\83n
\83\93\83h
\83\8b)
449 inMail : string; //
\83\81\81[
\83\8b\83A
\83h
\83\8c\83X
450 inMessage : string //
\96{
\95¶
451 ) : TDownloadState; //
\8f\91\82«
\8d\9e\82Ý
\82ª
\90¬
\8c÷
\82µ
\82½
\82©
\82Ç
\82¤
\82©
456 uriList : TStringList;
457 responseCode : Integer;
460 uri := TIdURI.Create( URL );
461 uriList := TStringList.Create;
463 ExtractHttpFields( ['/', '?'], [], uri.Path, uriList );
465 // http://jbbs.shitaraba.com/bbs/read.cgi/game/1578/1067968274/l100
467 'NAME=' + HttpEncode( SJIStoEUC( inName ) ) +
468 '&MAIL=' + HttpEncode( SJIStoEUC( inMail ) ) +
469 '&MESSAGE=' + HttpEncode( SJIStoEUC( inMessage ) ) +
470 '&BBS=' + uriList[ 4 ] +
471 '&KEY=' + uriList[ 5 ] +
472 '&DIR=' + uriList[ 3 ] +
473 '&TIME=' + IntToStr( DateTimeToUnix( Now ) ) +
474 '&submit=' + HttpEncode( SJIStoEUC( '
\8f\91\82«
\8d\9e\82Þ' ) );
476 //
\93Æ
\8e©
\82É
\92Ê
\90M
\82µ
\82È
\82¢
\8fê
\8d\87\82Í InternalPost
\82É
\94C
\82¹
\82é
\82±
\82Æ
\82ª
\8fo
\97\88\82é
477 responseCode := InternalPost( PChar( WriteURL ), PChar( postData ), postResult );
479 if (responseCode = 200) or
480 ((responseCode = 302) and (Length( Trim( postResult ) ) = 0)) then begin
484 if Assigned( InternalPrint ) then
485 InternalPrint( postResult );
488 DisposeResultString( postResult );
497 // *************************************************************************
498 //
\83\8c\83X
\94Ô
\8d\86 inNo
\82É
\91Î
\82·
\82é html
\82ð
\97v
\8b\81\82³
\82ê
\82½
499 // *************************************************************************
500 function TShitarabaThreadItem.GetRes(
501 inNo : Integer //
\97v
\8b\81\82³
\82ê
\82½
\83\8c\83X
\94Ô
\8d\86
502 ) : string; //
\91Î
\89\9e\82·
\82é HTML
508 //
\93Æ
\8e©
\82É
\83t
\83B
\83\8b\83^
\83\8a\83\93\83O
\82ð
\8ds
\82í
\82È
\82¢
\8fê
\8d\87\82Í
509 // InternalAbon
\82¨
\82æ
\82Ñ Dat2HTML
\82É
\94C
\82¹
\82é
\82±
\82Æ
\82ª
\8fo
\97\88\82é
511 if FDat = nil then begin
512 //
\83\8d\83O
\82É
\91¶
\8dÝ
\82µ
\82È
\82¢
\82Ì
\82Å
\82±
\82Ì
\82Ü
\82Ü
\8fI
\97¹
516 res := Copy( FDat[ inNo - 1 ], Pos( '<>', FDat[ inNo - 1 ] ) + 2, MaxInt );
517 tmp := InternalAbonForOne( PChar( res ), PChar( FilePath ),inNo );
519 Result := Dat2HTML( string( tmp ), inNo );
521 DisposeResultString( tmp );
526 // *************************************************************************
527 //
\83X
\83\8c\83b
\83h
\82Ì
\83w
\83b
\83_ html
\82ð
\97v
\8b\81\82³
\82ê
\82½
528 // *************************************************************************
529 function TShitarabaThreadItem.GetHeader(
530 inOptionalHeader : string
534 //
\93Æ
\8e©
\82É
\83t
\83B
\83\8b\83^
\83\8a\83\93\83O
\82ð
\8ds
\82í
\82È
\82¢
\8fê
\8d\87\82Í
535 // InternalHeader
\82É
\94C
\82¹
\82é
\82±
\82Æ
\82ª
\8fo
\97\88\82é
536 Result := InternalHeader(
537 '<meta http-equiv="Content-type" content="text/html; charset=Shift_JIS">' +
541 // GetRes
\82ð
\8cÄ
\82Î
\82ê
\82é
\82±
\82Æ
\82ª
\97\
\91z
\82³
\82ê
\82é
\82Ì
\82Å FDat
\82ð
\90¶
\90¬
\82µ
\82Ä
\82¨
\82
550 // *************************************************************************
551 //
\83X
\83\8c\83b
\83h
\82Ì
\83t
\83b
\83^ html
\82ð
\97v
\8b\81\82³
\82ê
\82½
552 // *************************************************************************
553 function TShitarabaThreadItem.GetFooter(
554 inOptionalFooter : string
558 //
\93Æ
\8e©
\82É
\83t
\83B
\83\8b\83^
\83\8a\83\93\83O
\82ð
\8ds
\82í
\82È
\82¢
\8fê
\8d\87\82Í
559 // InternalFooter
\82É
\94C
\82¹
\82é
\82±
\82Æ
\82ª
\8fo
\97\88\82é
560 Result := InternalFooter( inOptionalFooter );
562 //
\82à
\82¤ GetRes
\82Í
\8cÄ
\82Î
\82ê
\82È
\82¢
\82Æ
\8ev
\82¤
\82Ì
\82Å FDat
\82ð
\8aJ
\95ú
\82µ
\82Ä
\82¨
\82
570 // *************************************************************************
571 //
\82±
\82Ì ThreadItem
\82ª
\91®
\82·
\82é
\94Â
\82Ì URL
\82ð
\97v
\8b\81\82³
\82ê
\82½
572 // *************************************************************************
573 function TShitarabaThreadItem.GetBoardURL : string;
576 uriList : TStringList;
579 uri := TIdURI.Create( ReadURL );
580 uriList := TStringList.Create;
582 ExtractHttpFields( ['/', '?'], [], uri.Path, uriList );
583 FileName := uriList[ 5 ] + '.dat';
584 // http://jbbs.shitaraba.com/bbs/read.cgi/game/1578/1067968274/l100
585 // http://jbbs.shitaraba.com/game/1000/subject.txt
586 Result := CreateResultString(
587 uri.Protocol + '://' + uri.Host + '/' + uriList[ 3 ] + '/' + uriList[ 4 ] + '/' );
595 // *************************************************************************
597 // *************************************************************************
598 procedure TShitarabaThreadItem.LoadDat;
601 if FDat = nil then begin
602 if IsLogFile then begin
603 // dat
\82Ì
\93Ç
\82Ý
\8d\9e\82Ý
604 FDat := TStringList.Create;
605 FDat.LoadFromFile( FilePath );
611 // *************************************************************************
613 // *************************************************************************
614 procedure TShitarabaThreadItem.FreeDat;
617 if FDat <> nil then begin
624 // *************************************************************************
625 //
\88À
\91S
\82È( '/'
\82Å
\8fI
\82í
\82é )
\93Ç
\82Ý
\8d\9e\82Ý
\82Ì URL
626 // *************************************************************************
627 function TShitarabaThreadItem.ReadURL : string;
630 uriList : TStringList;
635 foundPos := Pos( '?', URL );
636 if foundPos > 0 then begin
638 uri := TIdURI.Create( URL );
639 uriList := TStringList.Create;
641 ExtractHttpFields( ['/'], [], uri.Path, uriList );
643 ExtractHttpFields( ['&'], [], Copy( URL, foundPos + 1, MaxInt ), uriList );
644 // http://jbbs.shitaraba.com/bbs/read.cgi?DIR=game&BBS=1578&KEY=1067968274
646 uri.Protocol + '://' + uri.Host + '/bbs/rawmode.cgi/' +
647 dir + '/' + uriList.Values[ 'BBS' ] + '/' + uriList.Values[ 'KEY' ] + '/';
653 if Copy( URL, Length( URL ), 1 ) = '/' then
654 uri := TIdURI.Create( URL )
656 uri := TIdURI.Create( URL + '/' );
657 uriList := TStringList.Create;
659 ExtractHttpFields( ['/'], [], uri.Path, uriList );
660 // http://jbbs.shitaraba.com/bbs/read.cgi/game/1578/1067968274/l100
662 uri.Protocol + '://' + uri.Host + '/bbs/rawmode.cgi/' +
663 uriList[ 3 ] + '/' + uriList[ 4 ] + '/' + uriList[ 5 ] + '/';
672 // *************************************************************************
673 //
\88À
\91S
\82È( '/'
\82Å
\8fI
\82í
\82é )
\8f\91\82«
\8d\9e\82Ý
\82Ì URL
674 // *************************************************************************
675 function TShitarabaThreadItem.WriteURL : string;
678 uriList : TStringList;
681 if Copy( URL, Length( URL ), 1 ) = '/' then
682 uri := TIdURI.Create( URL )
684 uri := TIdURI.Create( URL + '/' );
685 uriList := TStringList.Create;
687 ExtractHttpFields( ['/', '?'], [], uri.Path, uriList );
688 // http://jbbs.shitaraba.com/bbs/read.cgi/game/1578/1067968274/l100
690 uri.Protocol + '://' + uri.Host + '/bbs/write.cgi/' +
691 uriList[ 3 ] + '/' + uriList[ 4 ] + '/' + uriList[ 5 ] + '/';
699 // *************************************************************************
700 // TThreadItem
\82ª
\90¶
\90¬
\82³
\82ê
\82½
\8fê
\8d\87\82Ì
\8f\88\92u(TShitarabaThreadItem
\82ð
\90¶
\90¬
\82·
\82é)
701 // *************************************************************************
702 procedure ThreadItemOnCreateOfTShitarabaThreadItem(
706 threadItem : TShitarabaThreadItem;
709 threadItem := TShitarabaThreadItem.Create( inInstance );
710 ThreadItemSetLong( inInstance, tipContext, DWORD( threadItem ) );
714 // *************************************************************************
715 // TThreadItem
\82ª
\94j
\8aü
\82³
\82ê
\82½
\8fê
\8d\87\82Ì
\8f\88\92u(TShitarabaThreadItem
\82ð
\94j
\8aü
\82·
\82é)
716 // *************************************************************************
717 procedure ThreadItemOnDisposeOfTShitarabaThreadItem(
721 threadItem : TShitarabaThreadItem;
724 threadItem := TShitarabaThreadItem( ThreadItemGetLong( inInstance, tipContext ) );
729 // =========================================================================
730 // TShitarabaBoardItem
731 // =========================================================================
733 // *************************************************************************
734 //
\83R
\83\93\83X
\83g
\83\89\83N
\83^
735 // *************************************************************************
736 constructor TShitarabaBoardItem.Create(
741 uriList : TStringList;
746 OnDownload := Download;
747 OnCreateThread := CreateThread;
748 OnEnumThread := EnumThread;
749 OnFileName2ThreadURL := ToThreadURL;
752 FIsTemporary := False;
755 uri := TIdURI.Create( SubjectURL );
756 uriList := TStringList.Create;
758 ExtractHttpFields( ['/', '?'], [], uri.Path, uriList );
759 // http://jbbs.shitaraba.com/game/1000/subject.txt
760 FilePath := MyLogFolder + uriList[ 1 ] + '\' + uriList[ 2 ] + '\' + uri.Document;
761 IsLogFile := FileExists( FilePath );
769 // *************************************************************************
770 //
\83f
\83X
\83g
\83\89\83N
\83^
771 // *************************************************************************
772 destructor TShitarabaBoardItem.Destroy;
775 if FDat <> nil then begin
783 //
\88ê
\8e\9e\83t
\83@
\83C
\83\8b\82Ì
\8fê
\8d\87\82Í
\8dí
\8f\9c\82·
\82é
785 DeleteFile( FilePath );
791 // *************************************************************************
792 //
\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½
793 // *************************************************************************
794 function TShitarabaBoardItem.Download : TDownloadState;
798 responseCode : Longint;
800 uriList : TStringList;
805 if FDat <> nil then begin
812 FDat := TStringList.Create;
813 uri := TIdURI.Create( SubjectURL );
814 uriList := TStringList.Create;
815 //
\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Í
816 // InternalDownload
\82É
\94C
\82¹
\82é
\82±
\82Æ
\82ª
\8fo
\97\88\82é
817 modified := LastModified;
818 responseCode := InternalDownload( PChar( uri.URI ), modified, downResult );
820 if responseCode = 200 then begin
822 //
\83p
\83X
\82ð
\8eZ
\8fo
823 ExtractHttpFields( ['/', '?'], [], uri.Path, uriList );
824 if MyLogFolder = '' then begin
825 //
\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¶
826 FilePath := TemporaryFile;
827 FIsTemporary := True;
829 FilePath := MyLogFolder + uriList[ 1 ] + '\' + uriList[ 2 ] + '\' + uri.Document;
830 FIsTemporary := False
833 //
\95Û
\91¶
\97p
\82Ì
\83f
\83B
\83\8c\83N
\83g
\83\8a\82ð
\8c@
\82é
834 ForceDirectoriesEx( Copy( FilePath, 1, LastDelimiter( '\', FilePath ) ) );
836 // EUC
\82ð Shift_JIS
\82É
837 FDat.Text := EUCtoSJIS( string( downResult ) );
839 FDat.SaveToFile( FilePath );
843 LastModified := modified;
849 Result := dsComplete;
852 DisposeResultString( downResult );
857 // *************************************************************************
858 //
\83X
\83\8c\97§
\82Ä
\82ð
\8ew
\8e¦
\82³
\82ê
\82½
859 // *************************************************************************
860 function TShitarabaBoardItem.CreateThread(
861 inSubject : string; //
\83X
\83\8c\83^
\83C
862 inName : string; //
\96¼
\91O(
\83n
\83\93\83h
\83\8b)
863 inMail : string; //
\83\81\81[
\83\8b\83A
\83h
\83\8c\83X
864 inMessage : string //
\96{
\95¶
865 ) : TDownloadState; //
\8f\91\82«
\8d\9e\82Ý
\82ª
\90¬
\8c÷
\82µ
\82½
\82©
\82Ç
\82¤
\82©
871 uriList : TStringList;
872 responseCode : Integer;
875 uri := TIdURI.Create( URL );
876 uriList := TStringList.Create;
878 ExtractHttpFields( ['/', '?'], [], uri.Path, uriList );
880 // http://jbbs.shitaraba.com/bbs/write.cgi/game/1578/new/
881 // http://jbbs.shitaraba.com/game/1000/subject.txt
883 uri.Protocol + '://' + uri.Host + '/bbs/write.cgi/' +
884 uriList[ 1 ] + '/' + uriList[ 2 ] + '/new/';
886 'SUBJECT=' + HttpEncode( SJIStoEUC( inSubject ) ) +
887 '&NAME=' + HttpEncode( SJIStoEUC( inName ) ) +
888 '&MAIL=' + HttpEncode( SJIStoEUC( inMail ) ) +
889 '&MESSAGE=' + HttpEncode( SJIStoEUC( inMessage ) ) +
890 '&BBS=' + uriList[ 4 ] +
891 '&DIR=' + uriList[ 3 ] +
892 '&TIME=' + IntToStr( DateTimeToUnix( Now ) ) +
893 '&submit=' + HttpEncode( SJIStoEUC( '
\90V
\8bK
\8f\91\82«
\8d\9e\82Ý' ) );
895 //
\93Æ
\8e©
\82É
\92Ê
\90M
\82µ
\82È
\82¢
\8fê
\8d\87\82Í InternalPost
\82É
\94C
\82¹
\82é
\82±
\82Æ
\82ª
\8fo
\97\88\82é
896 responseCode := InternalPost( PChar( postURL ), PChar( postData ), postResult );
898 if (responseCode = 200) or
899 ((responseCode = 302) and (Length( Trim( postResult ) ) = 0)) then begin
903 if Assigned( InternalPrint ) then
904 InternalPrint( postResult );
907 DisposeResultString( postResult );
916 // *************************************************************************
917 //
\83X
\83\8c\88ê
\97\97\82Ì URL
\82©
\82ç
\83X
\83\8c\83b
\83h
\82Ì URL
\82ð
\93±
\82«
\8fo
\82·
918 // *************************************************************************
919 function TShitarabaBoardItem.ToThreadURL(
920 inFileName : string //
\83X
\83\8c\83b
\83h
\83t
\83@
\83C
\83\8b\96¼
921 ) : string; //
\83X
\83\8c\83b
\83h
\82Ì URL
925 uriList : TStringList;
929 found := Pos( '.', inFileName );
931 inFileName := Copy( inFileName, 1, found - 1 );
933 uri := TIdURI.Create( SubjectURL );
934 uriList := TStringList.Create;
937 ExtractHttpFields( ['/', '?'], [], uri.Path, uriList );
938 threadURL := uri.Protocol + '://' + uri.Host + '/bbs/read.cgi/' +
939 uriList[ 1 ] + '/' + uriList[ 2 ] + '/' + inFileName + '/l100';
951 // *************************************************************************
952 //
\82±
\82Ì
\94Â
\82É
\82¢
\82
\82Â
\82Ì
\83X
\83\8c\82ª
\82 \82é
\82©
\97v
\8b\81\82³
\82ê
\82½
953 // *************************************************************************
954 procedure TShitarabaBoardItem.EnumThread(
955 inCallBack : TBoardItemEnumThreadCallBack
959 uriList : TStringList;
963 if FDat = nil then begin
964 FDat := TStringList.Create;
965 uri := TIdURI.Create( SubjectURL );
966 uriList := TStringList.Create;
968 //
\83p
\83X
\82ð
\8eZ
\8fo
969 ExtractHttpFields( ['/', '?'], [], uri.Path, uriList );
970 // http://jbbs.shitaraba.com/game/1000/subject.txt
971 FilePath := MyLogFolder + uriList[ 1 ] + '\' + uriList[ 2 ] + '\' + uri.Document;
972 if FileExists( FilePath ) then
973 //
\93Ç
\82Ý
\8d\9e\82Ý
974 FDat.LoadFromFile( FilePath );
981 //
\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é
982 inherited EnumThread( inCallBack, FDat.Text );
988 // *************************************************************************
989 //
\83X
\83\8c\88ê
\97\97\82Ì URL
\82ð
\8b\81\82ß
\82é
990 // *************************************************************************
991 function TShitarabaBoardItem.SubjectURL : string;
994 uriList : TStringList;
997 uri := TIdURI.Create( URL );
998 uriList := TStringList.Create;
1000 if uri.Document <> SUBJECT_NAME then begin
1001 if Copy( URL, Length( URL ), 1 ) = '/' then
1002 Result := URL + SUBJECT_NAME
1004 Result := URL + '/' + SUBJECT_NAME;
1006 //
\82±
\82±
\82É
\82Í
\97\88\82È
\82¢
\82Æ
\8ev
\82¤
\82¯
\82Ç
1016 // *************************************************************************
1017 // TBoardItem
\82ª
\90¶
\90¬
\82³
\82ê
\82½
\8fê
\8d\87\82Ì
\8f\88\92u(TShitarabaBoardItem
\82ð
\90¶
\90¬
\82·
\82é)
1018 // *************************************************************************
1019 procedure BoardItemOnCreateOfTShitarabaBoardItem(
1023 boardItem : TShitarabaBoardItem;
1026 boardItem := TShitarabaBoardItem.Create( inInstance );
1027 BoardItemSetLong( inInstance, bipContext, DWORD( boardItem ) );
1031 // *************************************************************************
1032 // TBoardItem
\82ª
\94j
\8aü
\82³
\82ê
\82½
\8fê
\8d\87\82Ì
\8f\88\92u(TShitarabaBoardItem
\82ð
\94j
\8aü
\82·
\82é)
1033 // *************************************************************************
1034 procedure BoardItemOnDisposeOfTShitarabaBoardItem(
1038 boardItem : TShitarabaBoardItem;
1041 boardItem := TShitarabaBoardItem( BoardItemGetLong( inInstance, bipContext ) );
1048 // =========================================================================
1049 //
\83G
\83\93\83g
\83\8a\83|
\83C
\83\93\83g
1050 // =========================================================================
1052 ul_reason_for_call : DWORD
1058 case ul_reason_for_call of
1063 module := GetModuleHandle( nil );
1065 LoadInternalAPI( module );
1066 LoadInternalFilePathAPI( module );
1067 LoadInternalThreadItemAPI( module );
1068 LoadInternalBoardItemAPI( module );
1070 // =====
\83C
\83\93\83X
\83^
\83\93\83X
\82Ì
\8eæ
\82è
\88µ
\82¢
\82ð TThreadItem
\82©
\82ç TShitarabaThreadItem
\82É
\95Ï
\8dX
\82·
\82é
1071 ThreadItemOnCreate := ThreadItemOnCreateOfTShitarabaThreadItem;
1072 ThreadItemOnDispose := ThreadItemOnDisposeOfTShitarabaThreadItem;
1073 // =====
\83C
\83\93\83X
\83^
\83\93\83X
\82Ì
\8eæ
\82è
\88µ
\82¢
\82ð TBoardItem
\82©
\82ç TShitarabaBoardItem
\82É
\95Ï
\8dX
\82·
\82é
1074 BoardItemOnCreate := BoardItemOnCreateOfTShitarabaBoardItem;
1075 BoardItemOnDispose := BoardItemOnDisposeOfTShitarabaBoardItem;
1094 DllProc := @DLLEntry;
1095 DLLEntry( DLL_PROCESS_ATTACH );