1 library MachiBBSPlugIn;
5 \82Ü
\82¿BBS
\8f\88\97\9d\83\86\83j
\83b
\83g
6 \95¶
\8e\9a\83R
\81[
\83h
\82Ì
\95Ï
\8a·
\82É PzConv.pas [ http://plaza11.mbn.or.jp/~pz/ ]
\82ð
\8eg
\97p
\82µ
\82Ä
\82¢
\82Ü
\82·
\81B
7 \83R
\83\93\83p
\83C
\83\8b\91O
\82É
\81A
\93¯
\82¶
\83f
\83B
\83\8c\83N
\83g
\83\8a\82É
\92u
\82¢
\82Ä
\82
\82¾
\82³
\82¢
\81B
16 YofUtils in '..\..\YofUtils.pas',
17 PlugInMain in 'PlugInMain.pas',
18 ThreadItem in 'ThreadItem.pas',
19 BoardItem in 'BoardItem.pas',
20 FilePath in 'FilePath.pas';
25 // =========================================================================
26 // TMachiBBSThreadItem
27 // =========================================================================
28 TMachiBBSThreadItem = class(TThreadItem)
30 FIsTemporary : Boolean;
34 constructor Create( inInstance : DWORD );
35 destructor Destroy; override;
38 function Download : TDownloadState;
39 function GetRes( inNo : Integer ) : string;
40 function GetHeader( inOptionalHeader : string ) : string;
41 function GetFooter( inOptionalFooter : string ) : string;
43 procedure To2chDat( ioHTML : TStringList );
46 // =========================================================================
48 // =========================================================================
49 TMachiBBSBoardItem = class(TBoardItem)
51 FIsTemporary : Boolean;
55 constructor Create( inInstance : DWORD );
56 destructor Destroy; override;
59 function Download : TDownloadState;
60 function ToThreadURL( inFileName : string ) : string;
61 procedure EnumThread( inCallBack : TBoardItemEnumThreadCallBack );
65 // =========================================================================
66 //
\83T
\83u
\83W
\83F
\83N
\83g
\83\8c\83R
\81[
\83h
67 // =========================================================================
75 LOG_DIR = 'MachiBBS\';
77 PLUGIN_NAME = 'MachiBBSPlugIn';
80 RELEASE_VERSION = 'alpha';
83 // =========================================================================
85 // =========================================================================
87 // *************************************************************************
88 //
\83e
\83\93\83|
\83\89\83\8a\82È
\83p
\83X
\82Ì
\8eæ
\93¾
89 // *************************************************************************
90 function TemporaryFile : string;
92 tempPath : array [0..MAX_PATH] of char;
95 GetTempPath( SizeOf(tempPath), tempPath );
97 Result := tempPath + IntToStr( Random( $7fffffff ) );
98 until not FileExists( Result );
102 // *************************************************************************
103 //
\82Ü
\82¿BBS
\97p
\83\8d\83O
\83t
\83H
\83\8b\83_
\8eæ
\93¾
104 // *************************************************************************
105 function MyLogFolder : string;
111 if Length( folder ) = 0 then
114 Result := folder + LOG_DIR;
118 (*************************************************************************
119 *
\83f
\83B
\83\8c\83N
\83g
\83\8a\82ª
\91¶
\8dÝ
\82·
\82é
\82©
\83`
\83F
\83b
\83N
120 *************************************************************************)
121 function DirectoryExistsEx(const Name: string): Boolean;
125 Code := GetFileAttributes(PChar(Name));
126 Result := (Code <> -1) and (FILE_ATTRIBUTE_DIRECTORY and Code <> 0);
129 (*************************************************************************
130 *
\83f
\83B
\83\8c\83N
\83g
\83\8a\8dì
\90¬
\81i
\95¡
\90\94\8aK
\91w
\91Î
\89\9e\81j
131 *************************************************************************)
132 function ForceDirectoriesEx(Dir: string): Boolean;
135 if Length(Dir) = 0 then
136 raise Exception.Create('
\83t
\83H
\83\8b\83_
\82ª
\8dì
\90¬
\8fo
\97\88\82Ü
\82¹
\82ñ');
137 Dir := ExcludeTrailingPathDelimiter(Dir);
138 if (Length(Dir) < 3) or DirectoryExistsEx(Dir)
139 or (ExtractFilePath(Dir) = Dir) then Exit; // avoid 'xyz:\' problem.
140 Result := ForceDirectoriesEx(ExtractFilePath(Dir)) and CreateDir(Dir);
145 // =========================================================================
147 // =========================================================================
149 // *************************************************************************
150 //
\83v
\83\89\83O
\83C
\83\93\82Ì
\83o
\81[
\83W
\83\87\83\93\82ð
\97v
\8b\81\82³
\82ê
\82½
151 // *************************************************************************
152 procedure OnVersionInfo(
153 var outAgent : PChar; //
\83o
\81[
\83W
\83\87\83\93\82ð
\88ê
\90Ø
\8aÜ
\82Ü
\82È
\82¢
\8f\83\90\88\82È
\96¼
\8fÌ
154 var outMajor : DWORD; //
\83\81\83W
\83\83\81[
\83o
\81[
\83W
\83\87\83\93
155 var outMinor : DWORD; //
\83}
\83C
\83i
\81[
\83o
\81[
\83W
\83\87\83\93
156 var outRelease : PChar; //
\83\8a\83\8a\81[
\83X
\92i
\8aK
\96¼
157 var outRevision : DWORD //
\83\8a\83r
\83W
\83\87\83\93\83i
\83\93\83o
\81[
162 outAgent := CreateResultString( PChar( PLUGIN_NAME ) );
163 outMajor := MAJOR_VERSION;
164 outMinor := MINOR_VERSION;
165 outRelease := CreateResultString( PChar( RELEASE_VERSION ) );
166 outRevision := REVISION_VERSION;
177 // *************************************************************************
178 //
\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©
179 // *************************************************************************
180 function OnAcceptURL(
181 inURL : PChar //
\94»
\92f
\82ð
\8bÂ
\82¢
\82Å
\82¢
\82é URL
182 ): Boolean; stdcall; //
\8eó
\82¯
\95t
\82¯
\82é
\82È
\82ç True
187 BBS_HOST = 'machi.to';
191 //
\97á
\82Æ
\82µ
\82Ä
\83z
\83X
\83g
\96¼
\82ª machi.to
\82Å
\8fI
\82í
\82é
\8fê
\8d\87\82Í
\8eó
\82¯
\95t
\82¯
\82é
\82æ
\82¤
\82É
\82µ
\82Ä
\82¢
\82é
192 URI := TIdURI.Create( inURL );
194 foundPos := Pos( BBS_HOST, URI.Host );
195 Result := (foundPos > 0) and (Length( URI.Host ) - foundPos + 1 = Length( BBS_HOST ))
207 // =========================================================================
208 // TMachiBBSThreadItem
209 // =========================================================================
211 // *************************************************************************
212 //
\83R
\83\93\83X
\83g
\83\89\83N
\83^
213 // *************************************************************************
214 constructor TMachiBBSThreadItem.Create(
219 uriList : TStringList;
224 OnDownload := Download;
226 OnGetHeader := GetHeader;
227 OnGetFooter := GetFooter;
230 FIsTemporary := False;
233 uri := TIdURI.Create( URL );
234 uriList := TStringList.Create;
236 // http://hokkaido.machi.to/bbs/read.pl?BBS=hokkaidou&KEY=1061764446&LAST=50
237 YofUtils.ExtractHttpFields(
239 Copy( uri.Params, Pos( '?', uri.Params ) + 1, Length( uri.Params ) ), uriList );
240 FileName := uriList.Values[ 'KEY' ] + '.dat';
241 FilePath := MyLogFolder + uriList.Values[ 'BBS' ] + '\' + uriList.Values[ 'KEY' ] + '.dat';
242 IsLogFile := FileExists( FilePath );
250 // *************************************************************************
251 //
\83f
\83X
\83g
\83\89\83N
\83^
252 // *************************************************************************
253 destructor TMachiBBSThreadItem.Destroy;
256 if FDat <> nil then begin
264 //
\88ê
\8e\9e\83t
\83@
\83C
\83\8b\82Ì
\8fê
\8d\87\82Í
\8dí
\8f\9c\82·
\82é
266 DeleteFile( FilePath );
272 // *************************************************************************
273 //
\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½
274 // *************************************************************************
275 function TMachiBBSThreadItem.Download : TDownloadState;
279 downResult : TStringList;
280 responseCode : Longint;
281 logStream : TFileStream;
283 uriList : TStringList;
290 uri := TIdURI.Create( URL );
291 uriList := TStringList.Create;
293 YofUtils.ExtractHttpFields(
295 Copy( uri.Params, Pos( '?', uri.Params ) + 1, Length( uri.Params ) ), uriList );
296 if MyLogFolder = '' then begin
297 //
\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¶
298 FilePath := TemporaryFile;
299 FIsTemporary := True;
301 FilePath := MyLogFolder + uriList.Values[ 'BBS' ] + '\' + uriList.Values[ 'KEY' ] + '.dat';
302 FIsTemporary := False;
305 //
\95Û
\91¶
\97p
\82Ì
\83f
\83B
\83\8c\83N
\83g
\83\8a\82ð
\8c@
\82é
306 ForceDirectoriesEx( Copy( FilePath, 1, LastDelimiter( '\', FilePath ) ) );
308 if FileExists( FilePath ) then
309 logStream := TFileStream.Create( FilePath, fmOpenReadWrite or fmShareDenyWrite )
311 logStream := TFileStream.Create( FilePath, fmCreate or fmShareDenyWrite );
313 //
\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Í
314 // InternalDownload
\82É
\94C
\82¹
\82é
\82±
\82Æ
\82ª
\8fo
\97\88\82é
315 modified := LastModified;
316 // http://hokkaido.machi.to/bbs/read.pl?BBS=hokkaidou&KEY=1061764446
319 uri.Protocol + '://' + uri.Host + '/bbs/read.pl?' +
320 'BBS=' + uriList.Values[ 'BBS' ] + '&KEY=' + uriList.Values[ 'KEY' ] +
321 '&START=' + IntToStr( Count + 1 );
322 responseCode := InternalDownload( PChar( datURL ), modified, tmp, 0 );
325 if responseCode = 200 then begin
326 downResult := TStringList.Create;
328 downResult.Text := string( tmp );
330 //
\83\8c\83X
\82Ì
\8aJ
\8en
\88Ê
\92u
331 foundPos := Pos( '<dt', downResult.Text );
332 downResult.Text := Copy( downResult.Text, foundPos, Length( downResult.Text ) );
333 if foundPos > 0 then begin
334 //
\83\8c\83X
\82Ì
\8fI
\97¹
\88Ê
\92u
335 foundPos := Pos( '<table', downResult.Text ) - 1;
337 downResult.Text := Copy( downResult.Text, 1, foundPos );
339 //
\82Ü
\82¿BBS
\82Í dat
\92¼
\93Ç
\82Ý
\82ª
\8fo
\97\88\82È
\82¢
\82µ
\81Acgi
\88È
\8aO
\82É
\8d·
\95ª
\93Ç
\82Ý
\8d\9e\82Ý
\82Ì
\95û
\96@
\82ª
\82 \82é
\82í
\82¯
\82Å
\82à
\96³
\82¢
\82Ì
\82Å
340 //
\91f
\82Ì
\82Ü
\82Ü
\82ð
\96³
\97\9d\82É
\95Û
\82Æ
\82¤
\82Æ
\82Í
\82¹
\82¸
\82É 2ch
\82Ì dat
\8c`
\8e®
\82É
\95Ï
\8a·
\82µ
\82½
\82à
\82Ì
\82ð
\95Û
\91¶
\82µ
\82Ä
\82µ
\82Ü
\82¤
341 To2chDat( downResult );
343 if Count = 0 then begin
346 if downResult.Count > 0 then
347 //
\8dÅ
\8f\89\82Í
\95K
\82¸ 1
\82Ì
\83\8c\83X
348 downResult.Delete( 0 );
349 Result := dsDiffComplete;
351 if downResult.Count > 0 then begin
352 logStream.Position := logStream.Size;
353 logStream.Write( PChar( downResult.Text )^, Length( downResult.Text ) );
355 LastModified := modified;
357 NewReceive := Count + 1;
358 Count := Count + downResult.Count;
359 NewResCount := downResult.Count;
361 Result := dsNotModify;
369 DisposeResultString( tmp );
381 // *************************************************************************
382 //
\83\8c\83X
\94Ô
\8d\86 inNo
\82É
\91Î
\82·
\82é html
\82ð
\97v
\8b\81\82³
\82ê
\82½
383 // *************************************************************************
384 function TMachiBBSThreadItem.GetRes(
385 inNo : Integer //
\97v
\8b\81\82³
\82ê
\82½
\83\8c\83X
\94Ô
\8d\86
386 ) : string; //
\91Î
\89\9e\82·
\82é HTML
392 //
\93Æ
\8e©
\82É
\83t
\83B
\83\8b\83^
\83\8a\83\93\83O
\82ð
\8ds
\82í
\82È
\82¢
\8fê
\8d\87\82Í
393 // InternalAbon
\82¨
\82æ
\82Ñ Dat2HTML
\82É
\94C
\82¹
\82é
\82±
\82Æ
\82ª
\8fo
\97\88\82é
394 if FDat = nil then begin
395 if IsLogFile then begin
396 // dat
\82Ì
\93Ç
\82Ý
\8d\9e\82Ý
397 FDat := TStringList.Create;
398 FDat.LoadFromFile( FilePath );
400 //
\83\8d\83O
\82É
\91¶
\8dÝ
\82µ
\82È
\82¢
\82Ì
\82Å
\82±
\82Ì
\82Ü
\82Ü
\8fI
\97¹
405 res := FDat[ inNo - 1 ];
406 tmp := InternalAbon( PChar( res ) );
408 Result := Dat2HTML( string( tmp ), inNo );
410 DisposeResultString( tmp );
415 // *************************************************************************
416 //
\83X
\83\8c\83b
\83h
\82Ì
\83w
\83b
\83_ html
\82ð
\97v
\8b\81\82³
\82ê
\82½
417 // *************************************************************************
418 function TMachiBBSThreadItem.GetHeader(
419 inOptionalHeader : string
423 //
\93Æ
\8e©
\82É
\83t
\83B
\83\8b\83^
\83\8a\83\93\83O
\82ð
\8ds
\82í
\82È
\82¢
\8fê
\8d\87\82Í
424 // InternalHeader
\82É
\94C
\82¹
\82é
\82±
\82Æ
\82ª
\8fo
\97\88\82é
425 Result := InternalHeader(
426 '<meta http-equiv="Content-type" content="text/html; charset=Shift_JIS">' +
430 // GetRes
\82ð
\8cÄ
\82Î
\82ê
\82é
\82±
\82Æ
\82ª
\97\
\91z
\82³
\82ê
\82é
\82Ì
\82Å FDat
\82ð
\90¶
\90¬
\82µ
\82Ä
\82¨
\82
431 if FDat <> nil then begin
438 if IsLogFile then begin
439 // dat
\82Ì
\93Ç
\82Ý
\8d\9e\82Ý
440 FDat := TStringList.Create;
441 FDat.LoadFromFile( FilePath );
446 // *************************************************************************
447 //
\83X
\83\8c\83b
\83h
\82Ì
\83t
\83b
\83^ html
\82ð
\97v
\8b\81\82³
\82ê
\82½
448 // *************************************************************************
449 function TMachiBBSThreadItem.GetFooter(
450 inOptionalFooter : string
454 //
\93Æ
\8e©
\82É
\83t
\83B
\83\8b\83^
\83\8a\83\93\83O
\82ð
\8ds
\82í
\82È
\82¢
\8fê
\8d\87\82Í
455 // InternalFooter
\82É
\94C
\82¹
\82é
\82±
\82Æ
\82ª
\8fo
\97\88\82é
456 Result := InternalFooter( inOptionalFooter );
458 //
\82à
\82¤ GetRes
\82Í
\8cÄ
\82Î
\82ê
\82È
\82¢
\82Æ
\8ev
\82¤
\82Ì
\82Å FDat
\82ð
\8aJ
\95ú
\82µ
\82Ä
\82¨
\82
460 if FDat <> nil then begin
469 // *************************************************************************
470 //
\82Ü
\82¿BBS
\82Ì HTML
\82ð 2ch
\82Ì dat
\8c`
\8e®
\82É
471 // *************************************************************************
472 procedure TMachiBBSThreadItem.To2chDat(
481 MAIL_TAG = '<a href="mailto:';
484 //===== 2ch
\82Ì dat
\8c`
\8e®
\82É
\95Ï
\8a·
485 //
\83z
\83X
\83g
\96¼
\82Ì
\8cã
\82Å
\89ü
\8ds
\82³
\82ê
\82Ä
\82¢
\82½
\82è
\82·
\82é
\82Ì
\82Å
\89ü
\8ds
\82ð
\82·
\82×
\82Ä
\8eæ
\82è
\8f\9c\82
486 ioHTML.Text := StringReplace( ioHTML.Text, #13#10, '', [rfReplaceAll] );
487 //
\91ã
\82í
\82è
\82É <dt>
\82ð
\8ds
\82Ì
\8bæ
\90Ø
\82è
\82É
\82·
\82é
488 ioHTML.Text := StringReplace( ioHTML.Text, '<dt>', #10, [rfReplaceAll] );
489 // <dt>
\82©
\82ç
\8en
\82Ü
\82Á
\82Ä
\82¢
\82é
\82Ì
\82Å
\8dÅ
\8f\89\82Í
\8bó
\82Ì
\82Í
\82¸
490 if Length( ioHTML[ 0 ] ) = 0 then
492 //
\83g
\83\8a\83b
\83v
\82Ì
\8cã
\82Ì '<b> </b>'
\82ð
\8bó
\82É
493 ioHTML.Text := StringReplace( ioHTML.Text, '<b> </b>', '', [rfReplaceAll, rfIgnoreCase] );
494 // '<b>'
\82Í
\83\81\81[
\83\8b\82Æ
\96¼
\91O
\82Ì
\8bæ
\90Ø
\82è
495 ioHTML.Text := StringReplace( ioHTML.Text, '<b>', '<>', [rfReplaceAll, rfIgnoreCase] );
496 //
\83\81\81[
\83\8b\82Æ
\96¼
\91O
\82É
\82Â
\82¢
\82Ä
\82
\82é
\95Â
\82¶
\83^
\83O
\82ð
\93\8a\8de
\93ú
\82Æ
\82Ì
\8bæ
\90Ø
\82è
\82É
497 ioHTML.Text := StringReplace( ioHTML.Text, '</b></a>', '<>', [rfReplaceAll, rfIgnoreCase] );
498 ioHTML.Text := StringReplace( ioHTML.Text, '</b>', '<>', [rfReplaceAll, rfIgnoreCase] );
499 // '<dd>'
\82ð
\96{
\95¶
\82Æ
\82Ì
\8bæ
\90Ø
\82è
\82É
500 ioHTML.Text := StringReplace( ioHTML.Text, '<dd>', '<>', [rfReplaceAll, rfIgnoreCase] );
502 res := TStringList.Create;
504 bound := ioHTML.Count - 1;
505 for i := 0 to bound do begin
506 res.Text := StringReplace( ioHTML[ i ], '<>', #10, [rfReplaceAll] );
507 if res.Count >= 3 then begin // 3
\96¢
\96\9e\82Í
\82 \82è
\82¦
\82È
\82¢
\82Æ
\8ev
\82¤
\82¯
\82Ç
\88À
\91S
\82Ì
\82½
\82ß
508 foundPos := Pos( MAIL_TAG, res[ 0 ] );
509 if foundPos > 0 then begin
510 //
\83\81\81[
\83\8b\83A
\83h
\83\8c\83X
\82ð
\94²
\82«
\8fo
\82·
511 foundPos := foundPos + Length( MAIL_TAG );
512 res[ 0 ] := Copy( res[ 0 ], foundPos, Length( res[ 0 ] ) );
513 strTmp := Copy( res[ 0 ], 1, Pos( '">', res[ 0 ] ) - 1 );
514 //
\83\81\81[
\83\8b\82Æ
\96¼
\91O
\82ª
\8bt
\82È
\82Ì
\82Å
\82Ð
\82Á
\82
\82è
\95Ô
\82µ
\82Ä
\96ß
\82·
515 res[ 0 ] := res[ 1 ];
518 //
\83\81\81[
\83\8b\82Æ
\96¼
\91O
\82ª
\8bt
\82È
\82Ì
\82Å
\82Ð
\82Á
\82
\82è
\95Ô
\82·
519 res[ 0 ] := res[ 1 ];
522 res[ 2 ] := StringReplace( res[ 2 ], '[', 'ID:', [] );
523 res[ 2 ] := StringReplace( res[ 2 ], ']', '', [] );
525 ioHTML[ i ] := StringReplace( res.Text, #13#10, '<>', [rfReplaceAll] );
533 // *************************************************************************
534 // TThreadItem
\82ª
\90¶
\90¬
\82³
\82ê
\82½
\8fê
\8d\87\82Ì
\8f\88\92u(TMachiBBSThreadItem
\82ð
\90¶
\90¬
\82·
\82é)
535 // *************************************************************************
536 procedure ThreadItemOnCreateOfTMachiBBSThreadItem(
540 threadItem : TMachiBBSThreadItem;
543 threadItem := TMachiBBSThreadItem.Create( inInstance );
544 ThreadItemSetLong( inInstance, tipContext, DWORD( threadItem ) );
548 // *************************************************************************
549 // TThreadItem
\82ª
\94j
\8aü
\82³
\82ê
\82½
\8fê
\8d\87\82Ì
\8f\88\92u(TMachiBBSThreadItem
\82ð
\94j
\8aü
\82·
\82é)
550 // *************************************************************************
551 procedure ThreadItemOnDisposeOfTMachiBBSThreadItem(
555 threadItem : TMachiBBSThreadItem;
558 threadItem := TMachiBBSThreadItem( ThreadItemGetLong( inInstance, tipContext ) );
563 // =========================================================================
564 // TMachiBBSBoardItem
565 // =========================================================================
567 // *************************************************************************
568 //
\83R
\83\93\83X
\83g
\83\89\83N
\83^
569 // *************************************************************************
570 constructor TMachiBBSBoardItem.Create(
575 uriList : TStringList;
580 OnDownload := Download;
581 OnEnumThread := EnumThread;
582 OnFileName2ThreadURL := ToThreadURL;
585 FIsTemporary := False;
588 if Copy( URL, Length( URL ), 1 ) = '/' then
589 uri := TIdURI.Create( URL )
591 uri := TIdURI.Create( URL + '/' );
592 uriList := TStringList.Create;
594 YofUtils.ExtractHttpFields( ['/', '?'], [], uri.Path, uriList );
595 // http://hokkaido.machi.to/hokkaidou/subject.txt
596 FilePath := MyLogFolder + uriList[ 1 ] + '\' + uri.Document;
597 IsLogFile := FileExists( FilePath );
605 // *************************************************************************
606 //
\83f
\83X
\83g
\83\89\83N
\83^
607 // *************************************************************************
608 destructor TMachiBBSBoardItem.Destroy;
611 if FDat <> nil then begin
619 //
\88ê
\8e\9e\83t
\83@
\83C
\83\8b\82Ì
\8fê
\8d\87\82Í
\8dí
\8f\9c\82·
\82é
621 DeleteFile( FilePath );
627 // *************************************************************************
628 //
\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½
629 // *************************************************************************
630 function TMachiBBSBoardItem.Download : TDownloadState;
634 responseCode : Longint;
636 uriList : TStringList;
638 SUBJECT_NAME = 'subject.txt';
643 if Copy( URL, Length( URL ), 1 ) = '/' then
644 uri := TIdURI.Create( URL + SUBJECT_NAME )
646 uri := TIdURI.Create( URL );
647 uriList := TStringList.Create;
648 if FDat <> nil then begin
655 FDat := TStringList.Create;
656 //
\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Í
657 // InternalDownload
\82É
\94C
\82¹
\82é
\82±
\82Æ
\82ª
\8fo
\97\88\82é
658 modified := LastModified;
659 responseCode := InternalDownload( PChar( uri.URI ), modified, downResult );
661 if responseCode = 200 then begin
663 //
\83p
\83X
\82ð
\8eZ
\8fo
664 YofUtils.ExtractHttpFields( ['/', '?'], [], uri.Path, uriList );
665 if MyLogFolder = '' then begin
666 //
\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¶
667 FilePath := TemporaryFile;
668 FIsTemporary := True;
670 FilePath := MyLogFolder + uriList[ 1 ] + '\' + uri.Document;
671 FIsTemporary := False
674 //
\95Û
\91¶
\97p
\82Ì
\83f
\83B
\83\8c\83N
\83g
\83\8a\82ð
\8c@
\82é
675 ForceDirectoriesEx( Copy( FilePath, 1, LastDelimiter( '\', FilePath ) ) );
677 FDat.Text := string( downResult );
679 FDat.SaveToFile( FilePath );
684 Result := dsComplete;
687 DisposeResultString( downResult );
692 // *************************************************************************
693 //
\83X
\83\8c\88ê
\97\97\82Ì URL
\82©
\82ç
\83X
\83\8c\83b
\83h
\82Ì URL
\82ð
\93±
\82«
\8fo
\82·
694 // *************************************************************************
695 function TMachiBBSBoardItem.ToThreadURL(
696 inFileName : string //
\83X
\83\8c\83b
\83h
\83t
\83@
\83C
\83\8b\96¼
697 ) : string; //
\83X
\83\8c\83b
\83h
\82Ì URL
701 uriList : TStringList;
705 found := Pos( '.', inFileName );
707 inFileName := Copy( inFileName, 1, found - 1 );
708 if Copy( URL, Length( URL ), 1 ) = '/' then
709 uri := TIdURI.Create( URL )
711 uri := TIdURI.Create( URL + '/' );
712 uriList := TStringList.Create;
716 // http://hokkaido.machi.to/hokkaidou/
717 // http://hokkaido.machi.to/bbs/read.pl?BBS=hokkaidou&KEY=1061764446&LAST=50
718 YofUtils.ExtractHttpFields( ['/', '?'], [], uri.Path, uriList );
719 threadURL := uri.Protocol + '://' + uri.Host + '/bbs/read.pl?' +
720 'BBS=' + uriList[ 1 ] + '&KEY=' + inFileName + '&LAST=50';
732 // *************************************************************************
733 //
\82±
\82Ì
\94Â
\82É
\82¢
\82
\82Â
\82Ì
\83X
\83\8c\82ª
\82 \82é
\82©
\97v
\8b\81\82³
\82ê
\82½
734 // *************************************************************************
735 procedure TMachiBBSBoardItem.EnumThread(
736 inCallBack : TBoardItemEnumThreadCallBack
740 uriList : TStringList;
742 SUBJECT_NAME = 'subject.txt';
746 if FDat = nil then begin
747 FDat := TStringList.Create;
749 if Copy( URL, Length( URL ), 1 ) = '/' then
750 uri := TIdURI.Create( URL + SUBJECT_NAME )
752 uri := TIdURI.Create( URL );
753 uriList := TStringList.Create;
755 //
\83p
\83X
\82ð
\8eZ
\8fo
756 YofUtils.ExtractHttpFields( ['/', '?'], [], uri.Path, uriList );
757 // http://hokkaido.machi.to/hokkaidou/subject.txt
758 FilePath := MyLogFolder + uriList[ 1 ] + '\' + uri.Document;
759 if FileExists( FilePath ) then
760 //
\93Ç
\82Ý
\8d\9e\82Ý
761 FDat.LoadFromFile( FilePath );
768 //
\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é
769 inherited EnumThread( inCallBack, FDat.Text );
775 // *************************************************************************
776 // TBoardItem
\82ª
\90¶
\90¬
\82³
\82ê
\82½
\8fê
\8d\87\82Ì
\8f\88\92u(TMachiBBSBoardItem
\82ð
\90¶
\90¬
\82·
\82é)
777 // *************************************************************************
778 procedure BoardItemOnCreateOfTMachiBBSBoardItem(
782 boardItem : TMachiBBSBoardItem;
785 boardItem := TMachiBBSBoardItem.Create( inInstance );
786 BoardItemSetLong( inInstance, bipContext, DWORD( boardItem ) );
790 // *************************************************************************
791 // TBoardItem
\82ª
\94j
\8aü
\82³
\82ê
\82½
\8fê
\8d\87\82Ì
\8f\88\92u(TMachiBBSBoardItem
\82ð
\94j
\8aü
\82·
\82é)
792 // *************************************************************************
793 procedure BoardItemOnDisposeOfTMachiBBSBoardItem(
797 boardItem : TMachiBBSBoardItem;
800 boardItem := TMachiBBSBoardItem( BoardItemGetLong( inInstance, bipContext ) );
807 // =========================================================================
808 //
\83G
\83\93\83g
\83\8a\83|
\83C
\83\93\83g
809 // =========================================================================
811 ul_reason_for_call : DWORD
817 case ul_reason_for_call of
822 module := GetModuleHandle( nil );
824 LoadInternalAPI( module );
825 LoadInternalFilePathAPI( module );
826 LoadInternalThreadItemAPI( module );
827 LoadInternalBoardItemAPI( module );
829 // =====
\83C
\83\93\83X
\83^
\83\93\83X
\82Ì
\8eæ
\82è
\88µ
\82¢
\82ð TThreadItem
\82©
\82ç TMachiBBSThreadItem
\82É
\95Ï
\8dX
\82·
\82é
830 ThreadItemOnCreate := ThreadItemOnCreateOfTMachiBBSThreadItem;
831 ThreadItemOnDispose := ThreadItemOnDisposeOfTMachiBBSThreadItem;
832 // =====
\83C
\83\93\83X
\83^
\83\93\83X
\82Ì
\8eæ
\82è
\88µ
\82¢
\82ð TBoardItem
\82©
\82ç TMachiBBSBoardItem
\82É
\95Ï
\8dX
\82·
\82é
833 BoardItemOnCreate := BoardItemOnCreateOfTMachiBBSBoardItem;
834 BoardItemOnDispose := BoardItemOnDisposeOfTMachiBBSBoardItem;
853 DllProc := @DLLEntry;
854 DLLEntry( DLL_PROCESS_ATTACH );