1 library ShitarabaPlugIn;
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',
16 MojuUtils in '..\..\MojuUtils.pas';
21 // =========================================================================
22 // TShitarabaThreadItem
23 // =========================================================================
24 TShitarabaThreadItem = class(TThreadItem)
26 FIsTemporary : Boolean;
30 constructor Create( inInstance : DWORD );
31 destructor Destroy; override;
34 function Download : TDownloadState;
35 function Write( inName : string; inMail : string; inMessage : string ) : TDownloadState;
36 function GetRes( inNo : Integer ) : string;
37 function GetDat( inNo : Integer ) : string;
38 function GetHeader( inOptionalHeader : string ) : string;
39 function GetFooter( inOptionalFooter : string ) : string;
40 function GetBoardURL : string;
44 function ReadURL : string;
47 // =========================================================================
48 // TShitarabaBoardItem
49 // =========================================================================
50 TShitarabaBoardItem = class(TBoardItem)
52 FIsTemporary : Boolean;
56 constructor Create( inInstance : DWORD );
57 destructor Destroy; override;
60 function Download : TDownloadState;
61 function CreateThread( inSubject : string; inName : string; inMail : string; inMessage : string ) : TDownloadState;
62 function ToThreadURL( inFileName : string ) : string;
63 procedure EnumThread( inCallBack : TBoardItemEnumThreadCallBack );
65 function SubjectURL : string;
69 LOG_DIR = 'Shitaraba\';
70 SUBJECT_NAME = 'subject.txt';
72 PLUGIN_NAME = 'Shitaraba';
75 RELEASE_VERSION = 'beta';
78 // =========================================================================
80 // =========================================================================
82 // *************************************************************************
83 //
\83e
\83\93\83|
\83\89\83\8a\82È
\83p
\83X
\82Ì
\8eæ
\93¾
84 // *************************************************************************
85 function TemporaryFile : string;
87 tempPath : array [0..MAX_PATH] of char;
90 GetTempPath( SizeOf(tempPath), tempPath );
92 Result := tempPath + IntToStr( Random( $7fffffff ) );
93 until not FileExists( Result );
97 // *************************************************************************
98 //
\82µ
\82½
\82ç
\82Î
\97p
\83\8d\83O
\83t
\83H
\83\8b\83_
\8eæ
\93¾
99 // *************************************************************************
100 function MyLogFolder : string;
106 if Length( folder ) = 0 then
109 Result := folder + LOG_DIR;
113 (*************************************************************************
114 *
\83f
\83B
\83\8c\83N
\83g
\83\8a\82ª
\91¶
\8dÝ
\82·
\82é
\82©
\83`
\83F
\83b
\83N
115 *************************************************************************)
116 function DirectoryExistsEx(const Name: string): Boolean;
120 Code := GetFileAttributes(PChar(Name));
121 Result := (Code <> -1) and (FILE_ATTRIBUTE_DIRECTORY and Code <> 0);
124 (*************************************************************************
125 *
\83f
\83B
\83\8c\83N
\83g
\83\8a\8dì
\90¬
\81i
\95¡
\90\94\8aK
\91w
\91Î
\89\9e\81j
126 *************************************************************************)
127 function ForceDirectoriesEx(Dir: string): Boolean;
130 if Length(Dir) = 0 then
131 raise Exception.Create('
\83t
\83H
\83\8b\83_
\82ª
\8dì
\90¬
\8fo
\97\88\82Ü
\82¹
\82ñ');
132 Dir := ExcludeTrailingPathDelimiter(Dir);
133 if (Length(Dir) < 3) or DirectoryExistsEx(Dir)
134 or (ExtractFilePath(Dir) = Dir) then Exit; // avoid 'xyz:\' problem.
135 Result := ForceDirectoriesEx(ExtractFilePath(Dir)) and CreateDir(Dir);
138 //
\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
139 procedure ExtractHttpFields(
140 const chrSep : TSysCharSet;
141 const chrWhite : TSysCharSet;
142 const strValue : string;
143 var strResult : TStringList;
144 unknownFlag : boolean = false
147 last, p, strLen : Integer;
150 strLen := Length( strValue );
157 if strValue[ p ] in chrSep then
159 strResult.Add( Copy( strValue, last, p - last ) );
168 strResult.Add( Copy( strValue, last, strLen - last + 1 ) );
172 \rfunction HttpEncode(
173 \r const strValue : string
181 kHexCode : array [0..15] of char = (
182 '0', '1', '2', '3', '4', '5', '6', '7',
183 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' );
186 strLen := Length( strValue );
192 case strValue[ i ] of
193 '0' .. '9', 'a' .. 'z', 'A' .. 'Z', '*', '-', '.', '@', '_':
195 strResult := strResult + strValue[ i ];
199 b := Integer( strValue[ i ] );
200 strResult := strResult + '%'
201 + kHexCode[ b div $10 ]
202 + kHexCode[ b mod $10 ];
216 // =========================================================================
218 // =========================================================================
220 // *************************************************************************
221 //
\83v
\83\89\83O
\83C
\83\93\82Ì
\83o
\81[
\83W
\83\87\83\93\82ð
\97v
\8b\81\82³
\82ê
\82½
222 // *************************************************************************
223 procedure OnVersionInfo(
224 var outAgent : PChar; //
\83o
\81[
\83W
\83\87\83\93\82ð
\88ê
\90Ø
\8aÜ
\82Ü
\82È
\82¢
\8f\83\90\88\82È
\96¼
\8fÌ
225 var outMajor : DWORD; //
\83\81\83W
\83\83\81[
\83o
\81[
\83W
\83\87\83\93
226 var outMinor : DWORD; //
\83}
\83C
\83i
\81[
\83o
\81[
\83W
\83\87\83\93
227 var outRelease : PChar; //
\83\8a\83\8a\81[
\83X
\92i
\8aK
\96¼
228 var outRevision : DWORD //
\83\8a\83r
\83W
\83\87\83\93\83i
\83\93\83o
\81[
233 outAgent := CreateResultString( PChar( PLUGIN_NAME ) );
234 outMajor := MAJOR_VERSION;
235 outMinor := MINOR_VERSION;
236 outRelease := CreateResultString( PChar( RELEASE_VERSION ) );
237 outRevision := REVISION_VERSION;
248 // *************************************************************************
249 //
\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©
250 // *************************************************************************
251 function OnAcceptURL(
252 inURL : PChar //
\94»
\92f
\82ð
\8bÂ
\82¢
\82Å
\82¢
\82é URL
253 ): TAcceptType; stdcall; // URL
\82Ì
\8eí
\97Þ
256 uriList : TStringList;
259 BBS_HOST = 'www.shitaraba.com';
260 THREAD_MARK = '/cgi-bin/read.cgi?';
264 //
\83z
\83X
\83g
\96¼
\82ª www.shitaraba.com
\82Å
\8fI
\82í
\82é
\8fê
\8d\87\82Í
\8eó
\82¯
\95t
\82¯
\82é
\82æ
\82¤
\82É
\82µ
\82Ä
\82¢
\82é
265 uri := TIdURI.Create( inURL );
266 uriList := TStringList.Create;
268 ExtractHttpFields( ['/'], [], uri.Path, uriList );
269 foundPos := AnsiPos( BBS_HOST, uri.Host );
270 if (foundPos > 0) and (Length( uri.Host ) - foundPos + 1 = Length( BBS_HOST )) then begin
271 foundPos := AnsiPos( THREAD_MARK, inURL );
274 else if (uriList.Count > 1) and (uri.Path <> '/') then //
\8dÅ
\8cã
\82ª '/'
\82Å
\95Â
\82ß
\82ç
\82ê
\82Ä
\82é
\82È
\82ç 3
279 Result := atNoAccept;
286 Result := atNoAccept;
293 // =========================================================================
294 // TShitarabaThreadItem
295 // =========================================================================
297 // *************************************************************************
298 //
\83R
\83\93\83X
\83g
\83\89\83N
\83^
299 // *************************************************************************
300 constructor TShitarabaThreadItem.Create(
305 uriList : TStringList;
310 OnDownload := Download;
314 OnGetHeader := GetHeader;
315 OnGetFooter := GetFooter;
316 OnGetBoardURL := GetBoardURL;
319 FIsTemporary := False;
321 URL := ReadURL + '&ls=100';
323 uri := TIdURI.Create( URL );
324 uriList := TStringList.Create;
326 // http://www.shitaraba.com/cgi-bin/read.cgi?key=1032678843_1&bbs=jbbs
329 Copy( uri.Params, AnsiPos( '?', uri.Params ) + 1, Length( uri.Params ) ), uriList );
330 FileName := uriList.Values[ 'key' ] + '.dat';
331 FilePath := MyLogFolder + uriList.Values[ 'bbs' ] + '\' + uriList.Values[ 'key' ] + '.dat';
332 IsLogFile := FileExists( FilePath );
340 // *************************************************************************
341 //
\83f
\83X
\83g
\83\89\83N
\83^
342 // *************************************************************************
343 destructor TShitarabaThreadItem.Destroy;
348 //
\88ê
\8e\9e\83t
\83@
\83C
\83\8b\82Ì
\8fê
\8d\87\82Í
\8dí
\8f\9c\82·
\82é
350 DeleteFile( FilePath );
356 // *************************************************************************
357 //
\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½
358 // *************************************************************************
359 function TShitarabaThreadItem.Download : TDownloadState;
364 responseCode : Longint;
365 logStream : TFileStream;
367 uriList : TStringList;
369 downResult : TStringList;
377 uri := TIdURI.Create( URL );
378 uriList := TStringList.Create;
380 // http://www.shitaraba.com/cgi-bin/read.cgi?key=1032678843_1&bbs=jbbs
383 Copy( uri.Params, AnsiPos( '?', uri.Params ) + 1, Length( uri.Params ) ), uriList );
384 FileName := uriList.Values[ 'key' ] + '.dat';
385 if MyLogFolder = '' then begin
386 //
\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¶
387 FilePath := TemporaryFile;
388 FIsTemporary := True;
390 FilePath := MyLogFolder + uriList.Values[ 'bbs' ] + '\' + uriList.Values[ 'key' ] + '.dat';
391 FIsTemporary := False;
394 //
\95Û
\91¶
\97p
\82Ì
\83f
\83B
\83\8c\83N
\83g
\83\8a\82ð
\8c@
\82é
395 ForceDirectoriesEx( Copy( FilePath, 1, LastDelimiter( '\', FilePath ) ) );
397 if FileExists( FilePath ) then
398 logStream := TFileStream.Create( FilePath, fmOpenReadWrite or fmShareDenyWrite )
400 logStream := TFileStream.Create( FilePath, fmCreate or fmShareDenyWrite );
402 //
\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Í
403 // InternalDownload
\82É
\94C
\82¹
\82é
\82±
\82Æ
\82ª
\8fo
\97\88\82é
404 modified := LastModified;
405 // http://www.shitaraba.com/cgi-bin/read.cgi?key=1032678843_1&bbs=jbbs
406 // http://www.shitaraba.com/bbs/jbbs/dat/1032678843_1.dat
408 uri.Protocol + '://' + uri.Host + '/bbs/' +
409 uriList.Values[ 'bbs' ] + '/dat/' + uriList.Values[ 'key' ] + '.dat';
410 //
\82 \82Ú
\81[
\82ñ
\83`
\83F
\83b
\83N
\82Ì
\82½
\82ß 1
\83o
\83C
\83g
\91O
\82©
\82ç
\8eæ
\93¾
\82·
\82é
411 //
\81¦
\83\8d\83O
\82Æ
\8eI
\82Ì dat
\82Í
\89ü
\8ds
\83R
\81[
\83h
\82ª
\88á
\82¤
\82½
\82ß
\83t
\83@
\83C
\83\8b\83T
\83C
\83Y
\82ª
\95Ï
\82í
\82Á
\82Ä
\82¢
\82é
\82±
\82Æ
\82É
\92\8d\88Ó
412 responseCode := InternalDownload( PChar( datURL ), modified, tmp, Max( 0, Size - 1 ) );
415 if (responseCode = 200) or (responseCode = 206) then begin
416 downResult := TStringList.Create;
418 tmpLen := StrLen( tmp );
420 if Count = 0 then begin
421 Result := dsComplete;
422 tmpText := CustomStringReplace( string( tmp ), '¡÷¡®', ',');
423 downResult.Text := EUCtoSJIS( string( tmpText ) );
424 logStream.Position := logStream.Size;
425 logStream.Write( PChar( downResult.Text )^, Length( downResult.Text ) );
427 NewReceive := Count + 1;
428 Count := Count + downResult.Count;
429 NewResCount := downResult.Count;
431 end else if LF = tmp^ then begin
432 //
\90V
\8bK
\81A
\82Ü
\82½
\82Í
\92Ç
\8bL
433 Result := dsDiffComplete;
434 tmpText := CustomStringReplace( string( tmp + 1 ), '¡÷¡®', ',');
435 downResult.Text := EUCtoSJIS( string( tmpText ) );
436 logStream.Position := logStream.Size;
437 logStream.Write( PChar( downResult.Text )^, Length( downResult.Text ) );
439 NewReceive := Count + 1;
440 Count := Count + downResult.Count;
441 NewResCount := downResult.Count;
442 Size := Size + tmpLen - 1;
445 Result := dsDiffComplete;
447 modified := LastModified;
448 responseCode := InternalDownload(
449 PChar( datURL ), modified, tmp2, 0, Size );
450 tmpText := CustomStringReplace( string( tmp2 ) + string( tmp ), '¡÷¡®', ',');
451 downResult.Text := EUCtoSJIS( tmpText );
452 logStream.Position := 0;
453 logStream.Write( PChar( downResult.Text )^, Length( downResult.Text ) );
455 LastModified := modified;
456 if downResult.Count > Count then
457 NewReceive := Count + 1
460 Count := downResult.Count;
461 NewResCount := Count - NewReceive + 1;
462 Size := StrLen( tmp2 ) + tmpLen;
465 LastModified := modified;
469 end else if responseCode = 304 then begin
470 Result := dsNotModify;
473 DisposeResultString( tmp );
485 // *************************************************************************
486 //
\8f\91\82«
\8d\9e\82Ý
\82ð
\8ew
\8e¦
\82³
\82ê
\82½
487 // *************************************************************************
488 function TShitarabaThreadItem.Write(
489 inName : string; //
\96¼
\91O(
\83n
\83\93\83h
\83\8b)
490 inMail : string; //
\83\81\81[
\83\8b\83A
\83h
\83\8c\83X
491 inMessage : string //
\96{
\95¶
492 ) : TDownloadState; //
\8f\91\82«
\8d\9e\82Ý
\82ª
\90¬
\8c÷
\82µ
\82½
\82©
\82Ç
\82¤
\82©
497 uriList : TStringList;
500 uri := TIdURI.Create( URL );
501 uriList := TStringList.Create;
505 Copy( uri.Params, AnsiPos( '?', uri.Params ) + 1, Length( uri.Params ) ), uriList );
507 // http://cgi.shitaraba.com/cgi-bin/bbs.cgi
509 'FROM=' + HttpEncode( SJIStoEUC( inName ) ) +
510 '&mail=' + HttpEncode( SJIStoEUC( inMail ) ) +
511 '&MESSAGE=' + HttpEncode( SJIStoEUC( inMessage ) ) +
512 '&BBS=' + uriList.Values[ 'bbs' ] +
513 '&KEY=' + uriList.Values[ 'key' ] +
514 '&submit=' + HttpEncode( SJIStoEUC( '
\82©
\82«
\82±
\82Þ' ) );
516 //
\93Æ
\8e©
\82É
\92Ê
\90M
\82µ
\82È
\82¢
\8fê
\8d\87\82Í InternalPost
\82É
\94C
\82¹
\82é
\82±
\82Æ
\82ª
\8fo
\97\88\82é
517 InternalPost( PChar( 'http://cgi.shitaraba.com/cgi-bin/bbs.cgi' ), PChar( postData ), postResult );
518 DisposeResultString( postResult );
528 // *************************************************************************
529 //
\83\8c\83X
\94Ô
\8d\86 inNo
\82É
\91Î
\82·
\82é html
\82ð
\97v
\8b\81\82³
\82ê
\82½
530 // *************************************************************************
531 function TShitarabaThreadItem.GetRes(
532 inNo : Integer //
\97v
\8b\81\82³
\82ê
\82½
\83\8c\83X
\94Ô
\8d\86
533 ) : string; //
\91Î
\89\9e\82·
\82é HTML
539 //
\93Æ
\8e©
\82É
\83t
\83B
\83\8b\83^
\83\8a\83\93\83O
\82ð
\8ds
\82í
\82È
\82¢
\8fê
\8d\87\82Í
540 // InternalAbon
\82¨
\82æ
\82Ñ Dat2HTML
\82É
\94C
\82¹
\82é
\82±
\82Æ
\82ª
\8fo
\97\88\82é
542 if FDat = nil then begin
543 //
\83\8d\83O
\82É
\91¶
\8dÝ
\82µ
\82È
\82¢
\82Ì
\82Å
\82±
\82Ì
\82Ü
\82Ü
\8fI
\97¹
548 res := FDat[ inNo - 1 ];
549 tmp := InternalAbonForOne( PChar( res ), PChar( FilePath ),inNo );
551 Result := Dat2HTML( string( tmp ), inNo );
553 DisposeResultString( tmp );
558 // *************************************************************************
559 //
\83\8c\83X
\94Ô
\8d\86 inNo
\82É
\91Î
\82·
\82é Dat
\82ð
\97v
\8b\81\82³
\82ê
\82½
560 // *************************************************************************
561 function TShitarabaThreadItem.GetDat(
562 inNo : Integer //
\97v
\8b\81\82³
\82ê
\82½
\83\8c\83X
\94Ô
\8d\86
563 ) : string; //
\82Q
\82¿
\82á
\82ñ
\82Ë
\82é
\82ÌDat
\8c`
\8e®
567 if FDat = nil then begin
568 //
\83\8d\83O
\82É
\91¶
\8dÝ
\82µ
\82È
\82¢
\82Ì
\82Å
\82±
\82Ì
\82Ü
\82Ü
\8fI
\97¹
573 Result := FDat[ inNo - 1 ];
580 // *************************************************************************
581 //
\83X
\83\8c\83b
\83h
\82Ì
\83w
\83b
\83_ html
\82ð
\97v
\8b\81\82³
\82ê
\82½
582 // *************************************************************************
583 function TShitarabaThreadItem.GetHeader(
584 inOptionalHeader : string
588 //
\93Æ
\8e©
\82É
\83t
\83B
\83\8b\83^
\83\8a\83\93\83O
\82ð
\8ds
\82í
\82È
\82¢
\8fê
\8d\87\82Í
589 // InternalHeader
\82É
\94C
\82¹
\82é
\82±
\82Æ
\82ª
\8fo
\97\88\82é
590 Result := InternalHeader(
591 '<meta http-equiv="Content-type" content="text/html; charset=Shift_JIS">' +
595 // GetRes
\82ð
\8cÄ
\82Î
\82ê
\82é
\82±
\82Æ
\82ª
\97\
\91z
\82³
\82ê
\82é
\82Ì
\82Å FDat
\82ð
\90¶
\90¬
\82µ
\82Ä
\82¨
\82
604 // *************************************************************************
605 //
\83X
\83\8c\83b
\83h
\82Ì
\83t
\83b
\83^ html
\82ð
\97v
\8b\81\82³
\82ê
\82½
606 // *************************************************************************
607 function TShitarabaThreadItem.GetFooter(
608 inOptionalFooter : string
612 //
\93Æ
\8e©
\82É
\83t
\83B
\83\8b\83^
\83\8a\83\93\83O
\82ð
\8ds
\82í
\82È
\82¢
\8fê
\8d\87\82Í
613 // InternalFooter
\82É
\94C
\82¹
\82é
\82±
\82Æ
\82ª
\8fo
\97\88\82é
614 Result := InternalFooter( inOptionalFooter );
616 //
\82à
\82¤ GetRes
\82Í
\8cÄ
\82Î
\82ê
\82È
\82¢
\82Æ
\8ev
\82¤
\82Ì
\82Å FDat
\82ð
\8aJ
\95ú
\82µ
\82Ä
\82¨
\82
624 // *************************************************************************
625 //
\82±
\82Ì ThreadItem
\82ª
\91®
\82·
\82é
\94Â
\82Ì URL
\82ð
\97v
\8b\81\82³
\82ê
\82½
626 // *************************************************************************
627 function TShitarabaThreadItem.GetBoardURL : string;
630 uriList : TStringList;
633 uri := TIdURI.Create( URL );
634 uriList := TStringList.Create;
636 // http://www.shitaraba.com/cgi-bin/read.cgi?key=1032678843_1&bbs=jbbs
637 // http://www.shitaraba.com/bbs/jbbs/
640 Copy( uri.Params, AnsiPos( '?', uri.Params ) + 1, Length( uri.Params ) ), uriList );
641 FileName := uriList.Values[ 'key' ] + '.dat';
642 Result := CreateResultString(
643 uri.Protocol + '://' + uri.Host + '/bbs/' + uriList.Values[ 'bbs' ] + '/' );
651 // *************************************************************************
653 // *************************************************************************
654 procedure TShitarabaThreadItem.LoadDat;
657 if FDat = nil then begin
658 if IsLogFile then begin
659 // dat
\82Ì
\93Ç
\82Ý
\8d\9e\82Ý
660 FDat := TStringList.Create;
661 FDat.LoadFromFile( FilePath );
667 // *************************************************************************
669 // *************************************************************************
670 procedure TShitarabaThreadItem.FreeDat;
673 if FDat <> nil then begin
680 // *************************************************************************
681 //
\88À
\91S
\82È( '/'
\82Å
\8fI
\82í
\82é )
\93Ç
\82Ý
\8d\9e\82Ý
\82Ì URL
682 // *************************************************************************
683 function TShitarabaThreadItem.ReadURL : string;
686 uriList : TStringList;
690 foundPos := AnsiPos( '?', URL );
691 if foundPos > 0 then begin
692 uri := TIdURI.Create( URL );
693 uriList := TStringList.Create;
695 ExtractHttpFields( ['&'], [], Copy( URL, foundPos + 1, MaxInt ), uriList );
696 // http://www.shitaraba.com/cgi-bin/read.cgi?key=1032678843_1&bbs=jbbs
698 uri.Protocol + '://' + uri.Host + '/cgi-bin/read.cgi?' +
699 'bbs=' + uriList.Values[ 'BBS' ] + '&key=' + uriList.Values[ 'KEY' ];
708 // *************************************************************************
709 // TThreadItem
\82ª
\90¶
\90¬
\82³
\82ê
\82½
\8fê
\8d\87\82Ì
\8f\88\92u(TShitarabaThreadItem
\82ð
\90¶
\90¬
\82·
\82é)
710 // *************************************************************************
711 procedure ThreadItemOnCreateOfTShitarabaThreadItem(
715 threadItem : TShitarabaThreadItem;
718 threadItem := TShitarabaThreadItem.Create( inInstance );
719 ThreadItemSetLong( inInstance, tipContext, DWORD( threadItem ) );
723 // *************************************************************************
724 // TThreadItem
\82ª
\94j
\8aü
\82³
\82ê
\82½
\8fê
\8d\87\82Ì
\8f\88\92u(TShitarabaThreadItem
\82ð
\94j
\8aü
\82·
\82é)
725 // *************************************************************************
726 procedure ThreadItemOnDisposeOfTShitarabaThreadItem(
730 threadItem : TShitarabaThreadItem;
733 threadItem := TShitarabaThreadItem( ThreadItemGetLong( inInstance, tipContext ) );
738 // =========================================================================
739 // TShitarabaBoardItem
740 // =========================================================================
742 // *************************************************************************
743 //
\83R
\83\93\83X
\83g
\83\89\83N
\83^
744 // *************************************************************************
745 constructor TShitarabaBoardItem.Create(
750 uriList : TStringList;
755 OnDownload := Download;
756 OnCreateThread := CreateThread;
757 OnEnumThread := EnumThread;
758 OnFileName2ThreadURL := ToThreadURL;
761 FIsTemporary := False;
764 uri := TIdURI.Create( SubjectURL );
765 uriList := TStringList.Create;
767 ExtractHttpFields( ['/', '?'], [], uri.Path, uriList );
768 // http://www.shitaraba.com/bbs/jbbs/
769 FilePath := MyLogFolder + uriList[ 2 ] + '\' + uri.Document;
770 IsLogFile := FileExists( FilePath );
778 // *************************************************************************
779 //
\83f
\83X
\83g
\83\89\83N
\83^
780 // *************************************************************************
781 destructor TShitarabaBoardItem.Destroy;
784 if FDat <> nil then begin
792 //
\88ê
\8e\9e\83t
\83@
\83C
\83\8b\82Ì
\8fê
\8d\87\82Í
\8dí
\8f\9c\82·
\82é
794 DeleteFile( FilePath );
800 // *************************************************************************
801 //
\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½
802 // *************************************************************************
803 function TShitarabaBoardItem.Download : TDownloadState;
807 responseCode : Longint;
809 uriList : TStringList;
815 if FDat <> nil then begin
822 FDat := TStringList.Create;
823 uri := TIdURI.Create( SubjectURL );
824 uriList := TStringList.Create;
825 //
\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Í
826 // InternalDownload
\82É
\94C
\82¹
\82é
\82±
\82Æ
\82ª
\8fo
\97\88\82é
827 modified := LastModified;
828 responseCode := InternalDownload( PChar( uri.URI ), modified, downResult );
830 if responseCode = 200 then begin
832 //
\83p
\83X
\82ð
\8eZ
\8fo
833 ExtractHttpFields( ['/', '?'], [], uri.Path, uriList );
834 if MyLogFolder = '' then begin
835 //
\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¶
836 FilePath := TemporaryFile;
837 FIsTemporary := True;
839 FilePath := MyLogFolder + uriList[ 2 ] + '\' + uri.Document;
840 FIsTemporary := False
843 //
\95Û
\91¶
\97p
\82Ì
\83f
\83B
\83\8c\83N
\83g
\83\8a\82ð
\8c@
\82é
844 ForceDirectoriesEx( Copy( FilePath, 1, LastDelimiter( '\', FilePath ) ) );
846 // EUC
\82ð Shift_JIS
\82É
847 tmpText := CustomStringReplace( string( downResult ), '¡÷¡®', ',');
848 FDat.Text := EUCtoSJIS( tmpText );
850 FDat.SaveToFile( FilePath );
854 LastModified := modified;
860 Result := dsComplete;
863 DisposeResultString( downResult );
868 // *************************************************************************
869 //
\83X
\83\8c\97§
\82Ä
\82ð
\8ew
\8e¦
\82³
\82ê
\82½
870 // *************************************************************************
871 function TShitarabaBoardItem.CreateThread(
872 inSubject : string; //
\83X
\83\8c\83^
\83C
873 inName : string; //
\96¼
\91O(
\83n
\83\93\83h
\83\8b)
874 inMail : string; //
\83\81\81[
\83\8b\83A
\83h
\83\8c\83X
875 inMessage : string //
\96{
\95¶
876 ) : TDownloadState; //
\8f\91\82«
\8d\9e\82Ý
\82ª
\90¬
\8c÷
\82µ
\82½
\82©
\82Ç
\82¤
\82©
882 uriList : TStringList;
885 uri := TIdURI.Create( URL );
886 uriList := TStringList.Create;
888 ExtractHttpFields( ['/', '?'], [], uri.Path, uriList );
890 postURL := 'http://cgi.shitaraba.com/cgi-bin/bbs.cgi';
892 'subject=' + HttpEncode( SJIStoEUC( inSubject ) ) +
893 '&FROM=' + HttpEncode( SJIStoEUC( inName ) ) +
894 '&mail=' + HttpEncode( SJIStoEUC( inMail ) ) +
895 '&MESSAGE=' + HttpEncode( SJIStoEUC( inMessage ) ) +
896 '&bbs=' + uriList[ 2 ] +
897 '&submit=' + HttpEncode( SJIStoEUC( '
\90V
\8bK
\83X
\83\8c\83b
\83h
\8dì
\90¬' ) );
899 //
\93Æ
\8e©
\82É
\92Ê
\90M
\82µ
\82È
\82¢
\8fê
\8d\87\82Í InternalPost
\82É
\94C
\82¹
\82é
\82±
\82Æ
\82ª
\8fo
\97\88\82é
900 InternalPost( PChar( postURL ), PChar( postData ), postResult );
901 DisposeResultString( postResult );
911 // *************************************************************************
912 //
\83X
\83\8c\88ê
\97\97\82Ì URL
\82©
\82ç
\83X
\83\8c\83b
\83h
\82Ì URL
\82ð
\93±
\82«
\8fo
\82·
913 // *************************************************************************
914 function TShitarabaBoardItem.ToThreadURL(
915 inFileName : string //
\83X
\83\8c\83b
\83h
\83t
\83@
\83C
\83\8b\96¼
916 ) : string; //
\83X
\83\8c\83b
\83h
\82Ì URL
920 uriList : TStringList;
924 found := AnsiPos( '.', inFileName );
926 inFileName := Copy( inFileName, 1, found - 1 );
928 uri := TIdURI.Create( SubjectURL );
929 uriList := TStringList.Create;
932 // http://www.shitaraba.com/cgi-bin/read.cgi?key=1032678843_1&bbs=jbbs
933 // http://www.shitaraba.com/bbs/jbbs/
934 ExtractHttpFields( ['/', '?'], [], uri.Path, uriList );
935 threadURL := uri.Protocol + '://' + uri.Host + '/cgi-bin/read.cgi?' +
936 'bbs=' + uriList[ 2 ] + '&key=' + inFileName + '&ls=100';
948 // *************************************************************************
949 //
\82±
\82Ì
\94Â
\82É
\82¢
\82
\82Â
\82Ì
\83X
\83\8c\82ª
\82 \82é
\82©
\97v
\8b\81\82³
\82ê
\82½
950 // *************************************************************************
951 procedure TShitarabaBoardItem.EnumThread(
952 inCallBack : TBoardItemEnumThreadCallBack
956 uriList : TStringList;
958 lineRec : TStringList;
962 if FDat = nil then begin
963 FDat := TStringList.Create;
964 uri := TIdURI.Create( SubjectURL );
965 uriList := TStringList.Create;
967 //
\83p
\83X
\82ð
\8eZ
\8fo
968 ExtractHttpFields( ['/', '?'], [], uri.Path, uriList );
969 FilePath := MyLogFolder + uriList[ 2 ] + '\' + uri.Document;
970 if FileExists( FilePath ) then
971 //
\93Ç
\82Ý
\8d\9e\82Ý
972 FDat.LoadFromFile( FilePath );
979 lineRec := TStringList.Create;
981 bound := FDat.Count - 1;
982 for i := 0 to bound do begin
983 lineRec.Text := CustomStringReplace( FDat[ i ], '<>', #10 );
984 //StringReplace( FDat[ i ], '<>', #10, [ rfReplaceAll ] );
987 PChar( ToThreadURL( lineRec[ 0 ] ) ),
988 PChar( lineRec[ 1 ] ),
989 StrToInt( lineRec[ 2 ] ) ) then
1000 // *************************************************************************
1001 //
\83X
\83\8c\88ê
\97\97\82Ì URL
\82ð
\8b\81\82ß
\82é
1002 // *************************************************************************
1003 function TShitarabaBoardItem.SubjectURL : string;
1006 uriList : TStringList;
1009 uri := TIdURI.Create( URL );
1010 uriList := TStringList.Create;
1012 if uri.Document <> SUBJECT_NAME then begin
1013 if Copy( URL, Length( URL ), 1 ) = '/' then
1014 Result := URL + SUBJECT_NAME
1016 Result := URL + '/' + SUBJECT_NAME;
1018 //
\82±
\82±
\82É
\82Í
\97\88\82È
\82¢
\82Æ
\8ev
\82¤
\82¯
\82Ç
1028 // *************************************************************************
1029 // TBoardItem
\82ª
\90¶
\90¬
\82³
\82ê
\82½
\8fê
\8d\87\82Ì
\8f\88\92u(TShitarabaBoardItem
\82ð
\90¶
\90¬
\82·
\82é)
1030 // *************************************************************************
1031 procedure BoardItemOnCreateOfTShitarabaBoardItem(
1035 boardItem : TShitarabaBoardItem;
1038 boardItem := TShitarabaBoardItem.Create( inInstance );
1039 BoardItemSetLong( inInstance, bipContext, DWORD( boardItem ) );
1043 // *************************************************************************
1044 // TBoardItem
\82ª
\94j
\8aü
\82³
\82ê
\82½
\8fê
\8d\87\82Ì
\8f\88\92u(TShitarabaBoardItem
\82ð
\94j
\8aü
\82·
\82é)
1045 // *************************************************************************
1046 procedure BoardItemOnDisposeOfTShitarabaBoardItem(
1050 boardItem : TShitarabaBoardItem;
1053 boardItem := TShitarabaBoardItem( BoardItemGetLong( inInstance, bipContext ) );
1060 // =========================================================================
1061 //
\83G
\83\93\83g
\83\8a\83|
\83C
\83\93\83g
1062 // =========================================================================
1064 ul_reason_for_call : DWORD
1070 case ul_reason_for_call of
1075 module := GetModuleHandle( nil );
1077 LoadInternalAPI( module );
1078 LoadInternalFilePathAPI( module );
1079 LoadInternalThreadItemAPI( module );
1080 LoadInternalBoardItemAPI( module );
1082 // =====
\83C
\83\93\83X
\83^
\83\93\83X
\82Ì
\8eæ
\82è
\88µ
\82¢
\82ð TThreadItem
\82©
\82ç TShitarabaThreadItem
\82É
\95Ï
\8dX
\82·
\82é
1083 ThreadItemOnCreate := ThreadItemOnCreateOfTShitarabaThreadItem;
1084 ThreadItemOnDispose := ThreadItemOnDisposeOfTShitarabaThreadItem;
1085 // =====
\83C
\83\93\83X
\83^
\83\93\83X
\82Ì
\8eæ
\82è
\88µ
\82¢
\82ð TBoardItem
\82©
\82ç TShitarabaBoardItem
\82É
\95Ï
\8dX
\82·
\82é
1086 BoardItemOnCreate := BoardItemOnCreateOfTShitarabaBoardItem;
1087 BoardItemOnDispose := BoardItemOnDisposeOfTShitarabaBoardItem;
1106 DllProc := @DLLEntry;
1107 DLLEntry( DLL_PROCESS_ATTACH );