X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=BoardGroup.pas;h=cfe191a64979520df7f1a97fc82f11fe8af700ed;hb=99f2be3a17dfec20c0edcaaa09e20c39a74d3af9;hp=6cb8092412eaeca8be254f79b8efd035c9dd4307;hpb=944277754dac2bb337133cab9f5c0921c4c31aa4;p=gikonavigoeson%2Fgikonavi.git diff --git a/BoardGroup.pas b/BoardGroup.pas index 6cb8092..cfe191a 100644 --- a/BoardGroup.pas +++ b/BoardGroup.pas @@ -3,73 +3,20 @@ unit BoardGroup; interface uses - Windows, SysUtils, Classes, ComCtrls, IniFiles, {HTTPApp,} YofUtils, IdGlobal, - ExternalBoardManager, ExternalBoardPlugInMain, StrUtils, DateUtils; + Windows, SysUtils, Classes, ComCtrls, {HTTPApp,} YofUtils, IdGlobal, + ExternalBoardManager, ExternalBoardPlugInMain, StrUtils; type //ƒŠƒXƒg‚Ì•\Ž¦ƒAƒCƒeƒ€‘I‘ð - TGikoViewType = (gvtAll, gvtLog, gvtNew, gvtUser); - //ƒŠƒXƒg‚̎擾Œ” - //TGikoListCount = (glc50, glc100, glc200, glc500, glc1000, glcAll); - //„‰ñ”ԍ† - //TGikoRoundNo = (grnNone, grn1, grn2, grn3, grn4, grn5, grnOnce); + TGikoViewType = (gvtAll, gvtLog, gvtNew, gvtLive, gvtArch, gvtUser); //ƒŠƒXƒg‚̏グ‰º‚° - TGikoAgeSage = (gasNone, gasAge, gasSage, gasNew); - -{ TFolder = class - private - FItemList: TList; //ŽqƒAƒCƒeƒ€ƒŠƒXƒg - FLeaf: Boolean; //‰º‚ɃtƒHƒ‹ƒ_‚ðŽ‚Â‚±‚Æ‚ªo—ˆ‚é‚© - public - function Add(Item: TFolder): Integer; - procedure Clear; - procedure Delete(Index: Integer); - procedure Exchange(Index1, Index2: Integer); - procedure Insert(Index: Integer; Item: TFolder); - procedure Move(CurIndex, NewIndex: Integer); - function Remove(Item: TFolder): Integer; - procedure Sort(Compare: TListSortCompare); - property Capacity: Integer read FCapacity write SetCapacity; - property Count: Integer read FCount write SetCount; - property Items[Index: Integer]: TFolder read Get write Put; default; - - property Leaf: Boolean read FLeaf; - end; - - TBBS = class(TFolder) - end; - TCategory class(TFolder) - end; - TBoard = class(TFolder) - end; - TThreadItem = class(TFolder) - end; -} - -{ - TBBS = class(TBBS) - end; - TBoard2ch = class(TBoard) - end; - TThreadItem2ch = class(TThreadItem) - end; -} - -// ITest = interface -// end; -// IBBS = interface -// end; -// ICategory = interface -// end; -// IBoard = interface -// end; -// IThreadItem = interface -// end; + TGikoAgeSage = (gasNone, gasAge, gasSage, gasNew, gasArch, gasNull); TCategory = class; TBoard = class; TThreadItem = class; + // BBS ‚̃‹[ƒg TBBS = class(TList) private @@ -92,18 +39,19 @@ type procedure Delete(index: integer); procedure Clear; override; function Find(key: string): TCategory; - function FindBBSID(BBSID: string): TBoard; - function FindBoardFromTitle(Title: string): TBoard; - function FindBoardFromURL(inURL: string): TBoard; - function FindThreadFromURL( inURL : string ) : TThreadItem; - function FindThreadItem(BBSID: string; FileName: string): TThreadItem; - function FindCategoryFromTitle( inTitle : string ) : TCategory; + function FindBBSID(const BBSID: string): TBoard; + function FindBoardFromTitle(const Title: string): TBoard; + function FindBoardFromTitleAndCategory(const CategoryTitle: string; const BoardTitle: string): TBoard; + function FindBoardFromURL(const inURL: string): TBoard; + function FindThreadFromURL(const inURL : string ) : TThreadItem; + function FindThreadItem(const BBSID, FileName: string): TThreadItem; + function FindCategoryFromTitle(const inTitle : string ) : TCategory; property FilePath : string read FFilePath write FFilePath; property Items[index: integer]: TCategory read GetCategory write SetCategory; property Title: string read FTitle write FTitle; property NodeExpand: Boolean read FExpand write FExpand; - + property KubetsuChk: Boolean read FKubetsuChk write FKubetsuChk; property SelectText: string read FSelectText write SetSelectText; property ShortSelectText: string read FShortSelectText write FShortSelectText; @@ -112,7 +60,7 @@ type end; // ƒJƒeƒSƒŠ(” URL ‚̃ŠƒXƒg) - TCategory = class(THashedStringList) + TCategory = class(TStringList) private FNo: Integer; FTitle: string; @@ -133,18 +81,21 @@ type function Add(item: TBoard): integer; procedure Delete(index: integer); procedure Clear; override; - function FindName(key: string): TBoard; - function FindBBSID(BBSID: string): TBoard; - function FindBoardFromTitle(Title: string): TBoard; - function FindBoardFromURL(inURL: string): TBoard; - function FindThreadFromURL( inURL : string ) : TThreadItem; + function FindName(const key: string): TBoard; + function FindBBSID(const BBSID: string): TBoard; + function FindBoardFromTitle(const Title: string): TBoard; + function FindBoardFromURL(const inURL: string): TBoard; + function FindThreadFromURL(const inURL : string ) : TThreadItem; function IsMidoku: Boolean; property NodeExpand: Boolean read FExpand write FExpand; end; + //! ƒXƒŒƒbƒh”ƒJƒEƒ“ƒgðŒ•¶ + TThreadCount = function(Item : TThreadItem): Boolean; + // ”Â(ƒXƒŒƒbƒh URL ‚̃ŠƒXƒg) - TBoard = class(THashedStringList) + TBoard = class(TStringList) private FContext: DWORD; // ƒvƒ‰ƒOƒCƒ“‚ªŽ©—R‚ɐݒ肵‚Ä‚¢‚¢’l(Žå‚ɃCƒ“ƒXƒ^ƒ“ƒX‚ª“ü‚é) @@ -164,6 +115,8 @@ type FBoolData: Boolean; //‚¢‚ë‚ñ‚È—p“r‚ÉŽg‚¤yo FSPID: string; //‘‚«ž‚Ý—pSPID FPON: string; //‘‚«ž‚Ý—pPON + FCookie: string; //‘‚«ž‚Ý—pCookie•¶Žš—ñ + FExpires: TDateTime; //Cookie‚Ì—LŒøŠúŒÀ FKotehanName: string; //ƒRƒeƒnƒ“–¼‘O FKotehanMail: string; //ƒRƒeƒnƒ“ƒ[ƒ‹ @@ -176,10 +129,23 @@ type FIntData : Integer; // D‚«‚É‚¢‚¶‚Á‚Ă悵B‚¢‚ë‚ñ‚È—p“r‚ÉŽg‚¤yo FListData : TList; // D‚«‚É‚¢‚¶‚Á‚Ă悵B‚¢‚ë‚ñ‚È—p“r‚ÉŽg‚¤yo + FSETTINGTXTTime : TDateTime; //SETTING.TXT‚ðŽæ“¾‚µ‚½“úŽž + FIsSETTINGTXT : boolean; //SETTING.TXT‚ðŽæ“¾‚µ‚Ä‚¢‚é‚© + FHEADTXTTime : TDateTime; //HEAD.TXT‚ðŽæ“¾‚µ‚½“úŽž + FIsHEADTXT : boolean; //HEAD.TXT‚ðŽæ“¾‚µ‚Ä‚¢‚é‚© + FTitlePictureURL: string; //topŠG‚ÌURL + FMultiplicity : Integer; //d•¡‚µ‚Ä‚¢‚é‚©‚Ç‚¤‚©H + FIs2ch : Boolean; //host‚ª2ch‚©‚Ç‚¤‚© + FNewThreadCount: Integer; //V’…ƒXƒŒƒbƒh‚̐” + FLogThreadCount: Integer; //ƒƒO—L‚èƒXƒŒƒbƒh‚̐” + FUserThreadCount: Integer; //H + FLiveThreadCount: Integer; //¶‘¶ƒXƒŒƒbƒh” + FArchiveThreadCount: Integer; //DAT—Ž‚¿ƒXƒŒƒbƒh” function GetThreadItem(index: integer): TThreadItem; procedure SetThreadItem(index: integer; value: TThreadItem); procedure SetRound(b: Boolean); procedure SetRoundName(s: string); + //procedure SetRoundName(s: PChar); procedure SetLastModified(d: TDateTime); procedure SetLastGetTime(d: TDateTime); procedure SetUnRead(i: Integer); @@ -198,6 +164,7 @@ type property BBSID: string read FBBSID write FBBSID; property URL: string read FURL write FURL; property Round: Boolean read FRound write SetRound; + //property RoundName: PChar read FRoundName write SetRoundName; property RoundName: string read FRoundName write SetRoundName; property RoundDate: TDateTime read FRoundDate write FRoundDate; property LastModified: TDateTime read FLastModified write SetLastModified; @@ -219,24 +186,32 @@ type procedure Delete(index: integer); procedure DeleteList(index: integer); procedure Clear; override; - function FindThreadFromFileName(ItemFileName: string): TThreadItem; - function FindThreadFromURL( inURL : string ) : TThreadItem; - function GetIndexFromFileName(ItemFileName: string): Integer; - function GetIndexFromURL(URL: string): Integer; + function FindThreadFromFileName(const ItemFileName: string): TThreadItem; + function FindThreadFromURL(const inURL : string ) : TThreadItem; + function GetIndexFromFileName(const ItemFileName: string): Integer; + function GetIndexFromURL(const URL: string; reverse : Boolean = False): Integer; procedure LoadSettings; procedure SaveSettings; function GetReadCgiURL: string; function GetSubjectFileName: string; function GetFolderIndexFileName: string; + function GetSETTINGTXTFileName: string; + function GETHEADTXTFileName: string; + function GetTitlePictureFileName: string; function GetSendURL: string; function GetNewThreadCount: Integer; function GetLogThreadCount: Integer; + function GetArchiveThreadCount: Integer; + function GetLiveThreadCount: Integer; function GetUserThreadCount: Integer; function GetNewThread(Index: Integer): TThreadItem; - function GetLogThread(Index: Integer): TThreadItem; + function GetLogThread(Index: Integer): TThreadItem; overload; + function GetArchiveThread(Index: Integer): TThreadItem; + function GetLiveThread(Index: Integer): TThreadItem; function GetUserThread(Index: Integer): TThreadItem; - + function GetThreadCount(func :TThreadCount ): Integer; + function GetThread(func :TThreadCount;const Index :Integer ): TThreadItem; procedure BeginUpdate; procedure EndUpdate; property NodeExpand: Boolean read FExpand write FExpand; @@ -245,13 +220,28 @@ type property PON: string read FPON write FPON; property KotehanName: string read FKotehanName write SetKotehanName; property KotehanMail: string read FKotehanMail write SetKotehanMail; + + property SETTINGTXTTime: TDateTime read FSETTINGTXTTime write FSETTINGTXTTime; + property IsSETTINGTXT: boolean read FIsSETTINGTXT write FIsSETTINGTXT; + property HEADTXTTime: TDateTime read FHEADTXTTime write FHEADTXTTime; + property IsHEADTXT: boolean read FIsHEADTXT write FIsHEADTXT; + property TitlePictureURL: string read FTitlePictureURL write FTitlePictureURL; + property Multiplicity: Integer read FMultiplicity write FMultiplicity; + property Is2ch : boolean read FIs2ch write FIs2ch; + property NewThreadCount: Integer read FNewThreadCount write FNewThreadCount; //V’…ƒXƒŒƒbƒh‚̐” + property LogThreadCount: Integer read FLogThreadCount write FLogThreadCount; //ƒƒO—L‚èƒXƒŒƒbƒh‚̐” + property UserThreadCount: Integer read FUserThreadCount write FUserThreadCount; //H + property LiveThreadCount: Integer read FLiveThreadCount write FLiveThreadCount; + property ArchiveThreadCount: Integer read FArchiveThreadCount write FArchiveThreadCount; + + property Cookie: string read FCookie write FCookie; + property Expires: TDateTime read FExpires write FExpires; end; //ƒXƒŒ TThreadItem = class(TObject) private FContext: DWORD; // ƒvƒ‰ƒOƒCƒ“‚ªŽ©—R‚ɐݒ肵‚Ä‚¢‚¢’l(Žå‚ɃCƒ“ƒXƒ^ƒ“ƒX‚ª“ü‚é) - FNo: Integer; //”ԍ† FFileName: string; //ƒXƒŒƒbƒhƒtƒ@ƒCƒ‹–¼ FTitle: string; //ƒXƒŒƒbƒhƒ^ƒCƒgƒ‹ @@ -273,31 +263,36 @@ type FScrollTop: Integer; //ƒXƒNƒ[ƒ‹ˆÊ’u FDownloadHost: string; //¡‚̃zƒXƒg‚ƈႤê‡‚̃zƒXƒg FAgeSage: TGikoAgeSage; //ƒAƒCƒeƒ€‚̏グ‰º‚° -// FSPID: string; //‘‚«ž‚Ý—pSPID - FUpdate: Boolean; FExpand: Boolean; FURL : string; // ‚±‚̃XƒŒ‚ðƒuƒ‰ƒEƒU‚Å•\Ž¦‚·‚éÛ‚Ì URL - FBoardPlugIn : TBoardPlugIn; // ‚±‚̃XƒŒ‚ðƒTƒ|[ƒg‚·‚éƒvƒ‰ƒOƒCƒ“ - FFilePath : string; // ‚±‚̃XƒŒ‚ª•Û‘¶‚³‚ê‚Ä‚¢‚éƒpƒX - FSizeByte : Integer; // CreateHTML2 ‚ðŽÀs‚µ‚Ä‚¢‚éÅ’†‚Ɉꎞ“I‚É•Û‘¶‚³‚ê‚é’l - + FJumpAddress : Integer; //ƒŒƒX”ԍ†Žw’èURL‚𓥂ñ‚¾‚Æ‚«‚ÉŽw’肳‚ê‚郌ƒX‚̔ԍ†‚ª“ü‚é procedure SetLastModified(d: TDateTime); procedure SetRound(b: Boolean); - procedure SetRoundName(s: string); + procedure SetRoundName(const s: string); + //procedure SetRoundName(const s: PChar); procedure SetKokomade(i: Integer); procedure SetUnRead(b: Boolean); procedure SetScrollTop(i: Integer); procedure Init; - function GetCreateDate: TDateTime; + function GetCreateDate: TDateTime; + function GetFilePath: String; public - constructor Create( inPlugIn : TBoardPlugIn; inURL : string ); + constructor Create(const inPlugIn : TBoardPlugIn; const inBoard : TBoard; inURL : string ); overload; + constructor Create(const inPlugIn : TBoardPlugIn; const inBoard : TBoard; + const inURL : string; inExist: Boolean; const inFilename: string ); overload; + destructor Destroy; override; function GetDatURL: string; function GetDatgzURL: string; // function GetOldDatgzURL: string; - function GetOfflawCgiURL(SessionID: string): string; + function GetOfflawCgiURL(const SessionID: string): string; +//////////////// 2013/10/13 ShiroKuma‘Ήž zako Start /////////////////////////// + function GetOfflaw2SoURL: string; +//////////////// 2013/10/13 ShiroKuma‘Ήž zako End ///////////////////////////// + function GetRokkaURL(const SessionID: string): string; // Rokka‘Ήž + function GetExternalBoardKakoDatURL: string; // ŠO•””‰ߋŽƒƒOURLŽæ“¾ function GetSendURL: string; procedure DeleteLogFile; function GetThreadFileName: string; @@ -318,6 +313,7 @@ type property Size: Integer read FSize write FSize; property Round: Boolean read FRound write SetRound; property RoundName: string read FRoundName write SetRoundName; + //property RoundName: PChar read FRoundName write SetRoundName; property IsLogFile: Boolean read FIsLogFile write FIsLogFile; property ParentBoard: TBoard read FParentBoard write FParentBoard; @@ -329,46 +325,58 @@ type property Expand: Boolean read FExpand write FExpand; property DownloadHost: string read FDownloadHost write FDownloadHost; property AgeSage: TGikoAgeSage read FAgeSage write FAgeSage; -// property SPID: string read FSPID write FSPID; - property CreateDate: TDateTime read GetCreateDate; + property CreateDate: TDateTime read GetCreateDate; property URL : string read FURL write FURL; - property BoardPlugIn : TBoardPlugIn read FBoardPlugIn; - property FilePath : string read FFilePath write FFilePath; - property SizeByte : Integer read FSizeByte write FSizeByte; - function IsBoardPlugInAvailable : Boolean; + property FilePath : string read GetFilePath; + property JumpAddress : Integer read FJumpAddress write FJumpAddress; end; - - - //ŒŸõŒ‹‰ÊƒŠƒXƒg -{ TSearchList = class(TList) - private - function GetThreadItem(index: integer): TThreadItem; - procedure SetThreadItem(index: integer; value: TThreadItem); - public - constructor Create; + TBoardGroup = class(TStringList) + private + FBoardPlugIn : TBoardPlugIn; // ‚±‚̔‚ðƒTƒ|[ƒg‚·‚éƒvƒ‰ƒOƒCƒ“ + public destructor Destroy; override; + procedure Clear ; override; + property BoardPlugIn : TBoardPlugIn read FBoardPlugIn write FBoardPlugIn; + end; - property Items[index: integer]: TThreadItem read GetThreadItem write SetThreadItem; + // “ÁŽê—p“r—pTBoard + TSpecialBoard = class(TBoard) + public + function Add(item: TThreadItem): integer; overload; + procedure Clear; overload; + end; - function Add(item: TThreadItem): integer; - procedure Delete(index: integer); - procedure Clear; override; - end;} + // ƒXƒŒƒbƒh–¼NGƒ[ƒhƒŠƒXƒg + TThreadNgList = class(TStringList) + private + FFilePath: String; + public + constructor Create; + procedure Load; + procedure Save; + function IsNG(const Title: String): Boolean; + end; function BBSsFindBoardFromBBSID( inBBSID : string ) : TBoard; function BBSsFindBoardFromURL( inURL : string ) : TBoard; function BBSsFindBoardFromTitle( inTitle : string ) : TBoard; - function BBSsFindThreadFromURL( inURL : string ) : TThreadItem; - function ConvertDateTimeString( inDateTimeString : string) : TDateTime; - + function BBSsFindThreadFromURL(const inURL : string ) : TThreadItem; + function ConvertDateTimeString( inDateTimeString : string) : TDateTime; + + procedure DestorySpecialBBS( inBBS : TBBS ); + var BBSs : array of TBBS; + BoardGroups : array of TBoardGroup; + SpecialBBS : TBBS; + SpecialBoard: TSpecialBoard; + ThreadNgList: TThreadNgList; implementation uses - GikoSystem, RoundData; + GikoSystem, RoundData, MojuUtils, DateUtils, IniFiles; const BBS2CH_NAME: string = '‚Q‚¿‚á‚ñ‚Ë‚é'; @@ -379,11 +387,40 @@ const FOLDER_INDEX_FILENAME: string = 'Folder.idx'; SUBJECT_FILENAME: string = 'subject.txt'; PATH_DELIM: string = '\'; + SETTINGTXT_FILENAME: string = 'SETTING.TXT'; + HEADTXT_FILENAME: string = 'head.html'; //DEFAULT_LIST_COUNT: Integer = 100; + THREAD_NG_FILE: String = 'ThreadNg.txt'; + + +//! ƒƒO‚ðŽ‚Á‚Ä‚¢‚é‚È‚ç^‚ð•Ô‚· +function CountLog(Item: TThreadItem): Boolean; +begin + Result := Item.IsLogFile; +end; +//! V’…‚È‚ç^‚ð•Ô‚· +function CountNew(Item: TThreadItem): Boolean; +begin + Result := Item.NewArrival; +end; +//! DAT—Ž‚¿‚È‚ç^‚ð•Ô‚· +function CountDat(Item: TThreadItem): Boolean; +begin + Result := (Item.AgeSage = gasArch); +end; +//! ¶‘¶ƒXƒŒ‚È‚ç^‚ð•Ô‚· +function CountLive(Item: TThreadItem): Boolean; +begin + Result := (Item.AgeSage <> gasArch); +end; + +//! í‚ɐ^ +function CountAll(Item: TThreadItem): Boolean; +begin + Result := True; +end; + -// COLUMN_CATEGORY: array[0..0] of string = ('ƒJƒeƒSƒŠ–¼'); -// COLUMN_BOARD: array[0..3] of string = ('”–¼', 'Žæ“¾”', '„‰ñ—\–ñ', '‘O‰ñ„‰ñ“úŽž'); -// COLUMN_THREADITEM: array[0..3] of string = ('ƒXƒŒƒbƒh–¼', 'ƒJƒEƒ“ƒg', '„‰ñ—\–ñ', '‘O‰ñ„‰ñ“úŽž'); // BBSID ‚ð—p‚¢‚é 2 ‚¿‚á‚ñ‚Ë‚é‚Ì‚Ý’T‚µo‚µ‚Ü‚· // BBSID ‚ÌŽg—p‚Í‹É—Í”ð‚¯‚Ä‚­‚¾‚³‚¢B @@ -391,26 +428,67 @@ const function BBSsFindBoardFromBBSID( inBBSID : string ) : TBoard; +var + i : Integer; + tmpBoard : TBoard; begin - Result := BBSs[ 0 ].FindBBSID( inBBSID ); +// Result := BBSs[ 0 ].FindBBSID( inBBSID ); + Result := nil; + if Length(BoardGroups) > 0 then begin + for i := BoardGroups[0].Count - 1 downto 0 do begin + tmpBoard := TBoard(BoardGroups[0].Objects[i]); + if tmpBoard.Is2ch then begin + if AnsiCompareStr(tmpBoard.BBSID, inBBSID) = 0 then begin + Result := tmpBoard; + EXIT; + end; + end; + end; + end; end; - +{********************************************** +‚±‚̊֐”‚Í•K‚¸”‚ÌURL‚ÌŒ`Ž®‚Å“n‚µ‚Ä‚­‚¾‚³‚¢B +plugin‚ðŽg—p‚·‚é‚È‚ç‚΁AExtractBoardURL( inURL ) +2ch‚È‚ç‚΁AGikoSys.Get2chThreadURL2BoardURL( inURL ); +‚Å•ÏŠ·‚µ‚Ä‚©‚çŒÄ‚яo‚µ‚Ä‚­‚¾‚³‚¢B +**********************************************} function BBSsFindBoardFromURL( inURL : string ) : TBoard; var - i : Integer; + i,p : Integer; + accept : TAcceptType; + protocol, host, path, document, port, bookmark : string; begin - - for i := Length( BBSs ) - 1 downto 0 do begin - Result := BBSs[ i ].FindBoardFromURL( inURL ); - if Result <> nil then - Exit; - end; - Result := nil; + for i := Length(BoardGroups) - 1 downto 1 do begin + accept := BoardGroups[i].BoardPlugIn.AcceptURL(inURL); + if (accept = atBoard) or (accept = atThread) then begin + if BoardGroups[i].Find(inURL, p) then begin + Result := TBoard(BoardGroups[i].Objects[p]); + Exit; + end else begin + inURL := BoardGroups[i].BoardPlugIn.ExtractBoardURL(inURL); + if BoardGroups[i].Find(inURL, p) then begin + Result := TBoard(BoardGroups[i].Objects[p]); + Exit; + end; + end; + end; + end; + //‚±‚±‚É‚«‚½‚çAplugin‚ðŽg‚í‚È‚¢‚â‚‚ç‚𒲂ׂé + if BoardGroups[0].Find(inURL, p) then + Result := TBoard(BoardGroups[0].Objects[p]); + + if (Result = nil) then begin + GikoSys.ParseURI( inURL, protocol, host, path, document, port, bookmark ); + //ƒzƒXƒg‚ª2ch‚È‚çBBSID‚Å’²‚ׂé + if GikoSys.Is2chHost(host) then begin + Result := BBSsFindBoardFromBBSID(GikoSys.URLToID( inURL )); + end; + end; end; @@ -418,35 +496,91 @@ function BBSsFindBoardFromTitle( inTitle : string ) : TBoard; var - i : Integer; + i,j : Integer; + tmpBoard : TBoard; begin - + Result := nil; for i := Length( BBSs ) - 1 downto 0 do begin - Result := BBSs[ i ].FindBoardFromTitle( inTitle ); - if Result <> nil then - Exit; + for j := BoardGroups[i].Count - 1 downto 0 do begin + tmpBoard := TBoard(BoardGroups[i].Objects[j]); + if ( AnsiCompareStr(tmpBoard.Title, inTitle) = 0) then begin + Result := tmpBoard; + Exit; + end; + end; end; - Result := nil; - end; function BBSsFindThreadFromURL( - inURL : string + const inURL : string ) : TThreadItem; var board : TBoard; + tmpThread : TThreadItem; boardURL : string; + protocol, host, path, document, port, bookmark : string; + BBSID, BBSKey : string; + i, bi : Integer; begin boardURL := GikoSys.GetThreadURL2BoardURL( inURL ); board := BBSsFindBoardFromURL( boardURL ); if board = nil then Result := nil - else + else begin Result := board.FindThreadFromURL( inURL ); + //‚à‚µ‚à2ch‚̔‚Ȃç + if (Result = nil) and (board.Is2ch) then begin + GikoSys.ParseURI( inURL, protocol, host, path, document, port, bookmark ); + GikoSys.Parse2chURL( inURL, path, document, BBSID, BBSKey ); + Result := board.FindThreadFromFileName(BBSKey + '.dat'); + end else if (Result = nil) and not (board.Is2ch) then begin + //ƒvƒ‰ƒOƒCƒ“Œn‚Ì’TõiŽå‚ÉURL‚ª“r’†‚ŕύX‚É‚È‚Á‚½—Þ) + try + bi := Length(BoardGroups) - 1; + for i := 1 to bi do begin + if (BoardGroups[i].BoardPlugIn <> nil) and (Assigned(Pointer(BoardGroups[i].BoardPlugIn.Module))) then begin + if BoardGroups[i].BoardPlugIn.AcceptURL( inURL ) = atThread then begin + tmpThread := TThreadItem.Create( BoardGroups[i].BoardPlugIn, Board, inURL ); + if not board.IsThreadDatRead then begin + GikoSys.ReadSubjectFile( board ); + end; + Result := Board.FindThreadFromFileName( tmpThread.FileName ); + tmpThread.Free; + Break; + end; + end; + end; + except + Result := nil; + end; + end; + end; end; +{! +\brief “ÁŽê—p“rBBSíœ +\param bbs íœ‚·‚é“ÁŽê—p“rBBS +} +procedure DestorySpecialBBS( inBBS : TBBS ); +var + sCategory : TCategory; + sBoard : TSpecialBoard; +begin + if inBBS <> nil then begin + sCategory := inBBS.Items[0]; + if sCategory <> nil then begin + sBoard := TSpecialBoard(sCategory.Items[0]); + if sBoard <> nil then begin + sBoard.Modified := False; + sBoard.Clear; + FreeAndNil(sBoard); + end; + end; + FreeAndNil(inBBS); + end; +end; (************************************************************************* *‹@”\–¼FTBBSƒRƒ“ƒXƒgƒ‰ƒNƒ^ @@ -511,7 +645,7 @@ begin Result := nil; end; -function TBBS.FindBBSID(BBSID: string): TBoard; +function TBBS.FindBBSID(const BBSID: string): TBoard; var i : Integer; begin @@ -528,12 +662,12 @@ end; //************************************************************************* // ƒ^ƒCƒgƒ‹‚̈ê’v‚·‚锂ð’T‚· //*************************************************************************) -function TBBS.FindBoardFromTitle(Title: string): TBoard; +function TBBS.FindBoardFromTitle(const Title: string): TBoard; var i: Integer; begin if not IsBoardFileRead then - GikoSys.ReadBoardFile( Self ); + GikoSys.ReadBoardFile( Self ); for i := Count - 1 downto 0 do begin Result := Items[ i ].FindBoardFromTitle(Title); if Result <> nil then @@ -543,14 +677,33 @@ begin end; //************************************************************************* +// ƒJƒeƒSƒŠ–¼‚Ɣ–¼‚̈ê’v‚·‚锂ð’T‚· +//*************************************************************************) +function TBBS.FindBoardFromTitleAndCategory(const CategoryTitle: string; const BoardTitle: string): TBoard; +var + i: Integer; +begin + if not IsBoardFileRead then + GikoSys.ReadBoardFile( Self ); + for i := Count - 1 downto 0 do begin + if AnsiCompareStr(Items[ i ].Title, CategoryTitle) = 0 then begin + Result := Items[ i ].FindBoardFromTitle(BoardTitle); + if Result <> nil then + Exit; + end; + end; + Result := nil; +end; + +//************************************************************************* // URL ‚ðŽó‚¯•t‚¯‚锂ð’T‚· //*************************************************************************) -function TBBS.FindBoardFromURL(inURL: string): TBoard; +function TBBS.FindBoardFromURL(const inURL: string): TBoard; var i : Integer; begin if not IsBoardFileRead then - GikoSys.ReadBoardFile( Self ); + GikoSys.ReadBoardFile( Self ); for i := Count - 1 downto 0 do begin Result := Items[ i ].FindBoardFromURL( inURL ); if Result <> nil then @@ -562,7 +715,7 @@ end; //************************************************************************* // URL ‚ðŽó‚¯•t‚¯‚éƒXƒŒƒbƒh‚ð’T‚· //*************************************************************************) -function TBBS.FindThreadFromURL(inURL: string): TThreadItem; +function TBBS.FindThreadFromURL(const inURL: string): TThreadItem; var board : TBoard; boardURL : string; @@ -577,7 +730,7 @@ begin end; -function TBBS.FindThreadItem(BBSID: string; FileName: string): TThreadItem; +function TBBS.FindThreadItem(const BBSID, FileName: string): TThreadItem; var Board: TBoard; begin @@ -588,7 +741,7 @@ begin Result := Board.FindThreadFromFileName(FileName); end; -function TBBS.FindCategoryFromTitle( inTitle : string ) : TCategory; +function TBBS.FindCategoryFromTitle(const inTitle : string ) : TCategory; var i : Integer; begin @@ -607,7 +760,7 @@ end; procedure TBBS.SetSelectText(s: string); begin FSelectText := s; - ShortSelectText := GikoSys.ZenToHan(s); + ShortSelectText := CustomStringReplace(ZenToHan(s), ' ', ''); end; {class function TBBS.GetColumnName(Index: Integer): string; @@ -626,6 +779,10 @@ end;} constructor TCategory.Create; begin inherited; + + Duplicates := dupIgnore; + CaseSensitive := False; + //Sorted := True; end; destructor TCategory.Destroy; @@ -653,9 +810,7 @@ end; procedure TCategory.Delete(index: integer); begin - if Items[index] <> nil then - TBoard(Items[index]).Free; - inherited Delete(index); + inherited Delete(index); end; procedure TCategory.Clear; @@ -664,15 +819,15 @@ var begin for i := Count - 1 downto 0 do Delete(i); - Capacity := Count; + Capacity := Count; end; -function TCategory.FindName(key: string): TBoard; +function TCategory.FindName(const key: string): TBoard; begin Result := nil; end; -function TCategory.FindBBSID(BBSID: string): TBoard; +function TCategory.FindBBSID(const BBSID: string): TBoard; var i : integer; begin @@ -688,7 +843,7 @@ end; //************************************************************************* // ƒ^ƒCƒgƒ‹‚̈ê’v‚·‚锂ð’T‚· //*************************************************************************) -function TCategory.FindBoardFromTitle(Title: string): TBoard; +function TCategory.FindBoardFromTitle(const Title: string): TBoard; var i : integer; begin @@ -704,7 +859,7 @@ end; //************************************************************************* // URL ‚ðŽó‚¯•t‚¯‚锂ð’T‚· //*************************************************************************) -function TCategory.FindBoardFromURL(inURL: string): TBoard; +function TCategory.FindBoardFromURL(const inURL: string): TBoard; var i : Integer; begin @@ -718,7 +873,7 @@ end; //************************************************************************* // URL ‚ðŽó‚¯•t‚¯‚éƒXƒŒƒbƒh‚ð’T‚· //*************************************************************************) -function TCategory.FindThreadFromURL(inURL: string): TThreadItem; +function TCategory.FindThreadFromURL(const inURL: string): TThreadItem; var board : TBoard; boardURL : string; @@ -769,6 +924,10 @@ end;} //=================== procedure TBoard.Init; begin + Duplicates := dupIgnore; + CaseSensitive := False; + //Sorted := True; + FNo := 0; FTitle := ''; FBBSID := ''; @@ -779,6 +938,7 @@ begin FLastGetTime := ZERO_DATE; FIsThreadDatRead := False; FUnRead := 0; + FMultiplicity := 0; // FListStyle := vsReport; // FItemNoVisible := True; @@ -806,17 +966,21 @@ begin if inPlugIn = nil then begin // subject.txt ‚Ì•Û‘¶ƒpƒX‚ðÝ’è GikoSys.ParseURI( inURL, protocol, host, path, document, port, bookmark ); - if GikoSys.Is2chHost( host ) then + if GikoSys.Is2chHost( host ) then begin + Self.Is2ch := True; FilePath := - IncludeTrailingPathDelimiter( GikoSys.Setting.LogFolder ) + + GikoSys.Setting.LogFolderP + BBS2CH_LOG_FOLDER + PATH_DELIM + BBSID + PATH_DELIM + SUBJECT_FILENAME - else + end else begin + Self.Is2ch := False; FilePath := - IncludeTrailingPathDelimiter( GikoSys.Setting.LogFolder ) + + GikoSys.Setting.LogFolderP + EXTERNAL_LOG_FOLDER + PATH_DELIM + host + PATH_DELIM + BBSID + PATH_DELIM + SUBJECT_FILENAME + end; end else begin // ƒvƒ‰ƒOƒCƒ“‚É TBoardItem ‚ªì¬‚³‚ꂽ‚±‚Æ‚ð“`‚¦‚é inPlugIn.CreateBoardItem( DWORD( Self ) ); + //Self.Is2ch := False; //plugin‘¤‚Őݒ肷‚é end; end; @@ -908,7 +1072,7 @@ begin Capacity := Count; end; -function TBoard.FindThreadFromFileName(ItemFileName: string): TThreadItem; +function TBoard.FindThreadFromFileName(const ItemFileName: string): TThreadItem; var i: integer; begin @@ -921,7 +1085,7 @@ begin end; end; -function TBoard.GetIndexFromFileName(ItemFileName: string): Integer; +function TBoard.GetIndexFromFileName(const ItemFileName: string): Integer; var i: integer; begin @@ -934,12 +1098,24 @@ begin end; end; -function TBoard.GetIndexFromURL(URL: string): Integer; +function TBoard.GetIndexFromURL(const URL: string; reverse : Boolean = False): Integer; +var + i : Integer; begin - Result := IndexOf( URL ); + if not reverse then + Result := IndexOf( URL ) + else begin + Result := -1; + for i := Self.Count - 1 downto 0 do begin + if Strings[i] = URL then begin + Result := i; + break; + end; + end; + end; end; -function TBoard.FindThreadFromURL( inURL : string ) : TThreadItem; +function TBoard.FindThreadFromURL(const inURL : string ) : TThreadItem; var i : Integer; begin @@ -973,12 +1149,12 @@ procedure TBoard.LoadSettings; var ini: TMemIniFile; FileName: string; - tmp: string; + tmp: string; begin if Length( FilePath ) > 0 then FileName := ExtractFilePath( FilePath ) + FOLDER_INI_FILENAME else - FileName := IncludeTrailingPathDelimiter( GikoSys.Setting.LogFolder ) + FileName := GikoSys.Setting.LogFolderP + BBS2CH_LOG_FOLDER + PATH_DELIM + BBSID + PATH_DELIM + FOLDER_INI_FILENAME; if not FileExists(FileName) then @@ -987,40 +1163,30 @@ begin try // Round := ini.ReadBool('Status', 'Round', False); tmp := ini.ReadString('Status', 'RoundDate', DateTimeToStr(ZERO_DATE)); - FRoundDate := ConvertDateTimeString(tmp); - tmp := ini.ReadString('Status', 'LastModified', DateTimeToStr(ZERO_DATE)); - FLastModified := ConvertDateTimeString(tmp); - tmp := ini.ReadString('Status', 'LastGetTime', DateTimeToStr(ZERO_DATE)); - FLastGetTime := ConvertDateTimeString(tmp); + FRoundDate := ConvertDateTimeString(tmp); + tmp := ini.ReadString('Status', 'LastModified', DateTimeToStr(ZERO_DATE)); + FLastModified := ConvertDateTimeString(tmp); + tmp := ini.ReadString('Status', 'LastGetTime', DateTimeToStr(ZERO_DATE)); + FLastGetTime := ConvertDateTimeString(tmp); + + tmp := ini.ReadString('BoardInformation', 'SETTINGTXTTime', DateTimeToStr(ZERO_DATE)); + FSETTINGTXTTime := ConvertDateTimeString(tmp); + tmp := ini.ReadString('BoardInformation', 'HEADTXTTime', DateTimeToStr(ZERO_DATE)); + FHEADTXTTime := ConvertDateTimeString(tmp); + + FIsSETTINGTXT := ini.ReadBool('BoardInformation', 'IsSETTINGTXT', false); + FIsHEADTXT := ini.ReadBool('BoardInformation', 'IsHEADTXT', false); + FTitlePictureURL := ini.ReadString('BoardInformation', 'TitlePictureURL', ''); - { - try - FRoundDate := ini.ReadDateTime('Status', 'RoundDate', ZERO_DATE); - except - tmp := ini.ReadString('Status', 'RoundDate', DateTimeToStr(ZERO_DATE)); - FRoundDate := StrToDateTime(ConvertDateTimeString(tmp)); - end; - try - FLastModified := ini.ReadDateTime('Status', 'LastModified', ZERO_DATE); - except - tmp := ini.ReadString('Status', 'LastModified', DateTimeToStr(ZERO_DATE)); - FLastModified := StrToDateTime(ConvertDateTimeString(tmp)); - end; - try - FLastGetTime := ini.ReadDateTime('Status', 'LastGetTime', ZERO_DATE); - except - tmp := ini.ReadString('Status', 'LastGetTime', DateTimeToStr(ZERO_DATE)); - FLastGetTime := StrToDateTime(ConvertDateTimeString(tmp)); - end; - } FUnRead := ini.ReadInteger('Status', 'UnRead', 0); FSPID := ini.ReadString('Cookie', 'SPID', ''); FPON := ini.ReadString('Cookie', 'PON', ''); + FCookie := ini.ReadString('Cookie', 'Cookie', ''); + tmp := ini.ReadString('Cookie', 'Expires', DateTimeToStr(ZERO_DATE)); + FExpires := ConvertDateTimeString(tmp); FKotehanName := ini.ReadString('Kotehan', 'Name', ''); FKotehanMail := ini.ReadString('Kotehan', 'Mail', ''); -// ListStyle := TViewStyle(Ord(ini.ReadInteger('Status', 'ListStyle', 3))); -// ItemNoVisible := ini.ReadBool('Status', 'ItemNoVisible', True); -// ViewType := TGikoViewType(Ord(ini.ReadInteger('Status', 'ViewType', 0))); + if UnRead < 0 then UnRead := 0; finally @@ -1036,7 +1202,7 @@ begin if Length( FilePath ) > 0 then FileName := ExtractFilePath( FilePath ) else - FileName := IncludeTrailingPathDelimiter( GikoSys.Setting.LogFolder ) + FileName := GikoSys.Setting.LogFolderP + BBS2CH_LOG_FOLDER + PATH_DELIM + BBSID + PATH_DELIM; if not GikoSys.DirectoryExistsEx(FileName) then GikoSys.ForceDirectoriesEx(FileName); @@ -1052,8 +1218,17 @@ begin ini.WriteInteger('Status', 'UnRead', FUnRead); ini.WriteString('Cookie', 'SPID', FSPID); ini.WriteString('Cookie', 'PON', FPON); + ini.WriteString('Cookie', 'Cookie', FCookie); + ini.WriteDateTime('Cookie', 'Expires', FExpires); ini.WriteString('Kotehan', 'Name', FKotehanName); ini.WriteString('Kotehan', 'Mail', FKotehanMail); + + ini.WriteDateTime('BoardInformation', 'SETTINGTXTTime', FSETTINGTXTTime); + ini.WriteDateTime('BoardInformation', 'HEADTXTTime', FHEADTXTTime); + + ini.WriteBool('BoardInformation', 'IsSETTINGTXT', FIsSETTINGTXT); + ini.WriteBool('BoardInformation', 'IsHEADTXT', FIsHEADTXT); + ini.WriteString('BoardInformation', 'TitlePictureURL', FTitlePictureURL); // ini.WriteInteger('Status', 'ListStyle', Ord(ListStyle)); // ini.WriteBool('Status', 'ItemNoVisible', ItemNoVisible); // ini.WriteInteger('Status', 'ViewType', Ord(ViewType)); @@ -1091,7 +1266,7 @@ begin except if( inDateTimeString[5] = '/' ) and ( inDateTimeString[8] = '/' ) then begin y := StrToIntDef( Copy(inDateTimeString, 1, 4), 1970 ); - m := StrToIntDef( Copy(inDateTimeString, 6, 2), 1 ); + m := StrToIntDef( Copy(inDateTimeString, 6, 2), 1 ); d := StrToIntDef( Copy(inDateTimeString, 9, 2), 1 ); hour := 0; min := 0; sec := 0; @@ -1118,40 +1293,75 @@ begin // Result := inDateTimeString; end; -// ƒTƒuƒWƒFƒNƒgURLŽæ“¾ +//! ƒTƒuƒWƒFƒNƒgURLŽæ“¾ function TBoard.GetReadCgiURL: string; begin - //Result := URL + SUBJECT_FILENAME; - //Result := GikoSys.UrlToServer(URL) - // + 'test/read.cgi/' + BBSID + '/?raw=0.0'; Result := URL + SUBJECT_FILENAME; end; -// ƒTƒuƒWƒFƒNƒgƒtƒ@ƒCƒ‹–¼Žæ“¾iƒpƒX{ƒtƒ@ƒCƒ‹–¼j +//! ƒTƒuƒWƒFƒNƒgƒtƒ@ƒCƒ‹–¼Žæ“¾iƒpƒX{ƒtƒ@ƒCƒ‹–¼j function TBoard.GetSubjectFileName: string; begin if Length( FilePath ) > 0 then Result := FilePath else - Result := IncludeTrailingPathDelimiter( GikoSys.Setting.LogFolder ) + Result := GikoSys.Setting.LogFolderP + BBS2CH_LOG_FOLDER + PATH_DELIM + BBSID + PATH_DELIM + SUBJECT_FILENAME; end; -// ƒCƒ“ƒfƒbƒNƒXƒtƒ@ƒCƒ‹–¼(folder.idx)Žæ“¾iƒpƒX{ƒtƒ@ƒCƒ‹–¼j +//! ƒCƒ“ƒfƒbƒNƒXƒtƒ@ƒCƒ‹–¼(folder.idx)Žæ“¾iƒpƒX{ƒtƒ@ƒCƒ‹–¼j function TBoard.GetFolderIndexFileName: string; begin if Length( FilePath ) > 0 then Result := ExtractFilePath( FilePath ) + FOLDER_INDEX_FILENAME else - Result := IncludeTrailingPathDelimiter( GikoSys.Setting.LogFolder ) + Result := GikoSys.Setting.LogFolderP + BBS2CH_LOG_FOLDER + PATH_DELIM + BBSID + PATH_DELIM + FOLDER_INDEX_FILENAME; end; +//! SETTING.TXT‚̃tƒ@ƒCƒ‹–¼Žæ“¾ +function TBoard.GetSETTINGTXTFileName: string; +begin + if Length( FilePath ) > 0 then + Result := ExtractFilePath( FilePath ) + SETTINGTXT_FILENAME + else + Result := GikoSys.Setting.LogFolderP + + BBS2CH_LOG_FOLDER + PATH_DELIM + BBSID + PATH_DELIM + SETTINGTXT_FILENAME; +end; + +function TBoard.GETHEADTXTFileName: string; +begin + if Length( FilePath ) > 0 then + Result := ExtractFilePath( FilePath ) + HEADTXT_FILENAME + else + Result := GikoSys.Setting.LogFolderP + + BBS2CH_LOG_FOLDER + PATH_DELIM + BBSID + PATH_DELIM + HEADTXT_FILENAME; +end; +function TBoard.GetTitlePictureFileName: string; +var + tmpName: string; +begin + if FTitlePictureURL = '' then + Result := '' + else begin + tmpName := Copy(FTitlePictureURL, LastDelimiter('/', FTitlePictureURL) + 1, Length(FTitlePictureURL)); + if Length( FilePath ) > 0 then + Result := ExtractFilePath( FilePath ) + tmpName + else + Result := GikoSys.Setting.LogFolderP + + BBS2CH_LOG_FOLDER + PATH_DELIM + BBSID + PATH_DELIM + tmpName; + end; +end; // ƒXƒŒ—§‚Ä‘—MURL function TBoard.GetSendURL: string; begin - Result := GikoSys.UrlToServer(URL) + 'test/subbbs.cgi'; + Result := GikoSys.UrlToServer(URL); + if Self.Is2ch then + Result := Result + 'test/bbs.cgi' + else + Result := Result + 'test/subbbs.cgi'; + end; procedure TBoard.SetRound(b: Boolean); @@ -1214,8 +1424,8 @@ begin if FUpdate then FModified := True; end; - -function TBoard.GetNewThreadCount: Integer; +//! func‚ÌðŒ‚Éˆê’v‚·‚éƒXƒŒƒbƒh‚̐”‚ð•Ô‚· +function TBoard.GetThreadCount(func :TThreadCount ): Integer; var i: Integer; begin @@ -1223,63 +1433,48 @@ begin if Length( ParentCategory.ParenTBBS.ShortSelectText ) = 0 then begin for i := 0 to Count - 1 do begin - if Items[i].NewArrival then + if func(Items[i]) then inc(Result); end; end else begin for i := 0 to Count - 1 do begin - if Items[i].NewArrival then + if func(Items[i]) then begin if Items[i].ShortTitle = '' then - Items[i].ShortTitle := GikoSys.ZenToHan(Items[i].Title); + Items[i].ShortTitle := CustomStringReplace(ZenToHan(Items[i].Title), ' ', ''); if AnsiPos(ParentCategory.ParenTBBS.ShortSelectText, Items[i].ShortTitle) <> 0 then inc(Result); end; end; end; end; - +//! V’…ƒXƒŒƒbƒh‚̐”‚ðŽæ“¾‚·‚é +function TBoard.GetNewThreadCount: Integer; +begin + Result := GetThreadCount(CountNew); +end; +//! ƒƒO—L‚èƒXƒŒƒbƒh‚̐”‚ðŽæ“¾‚·‚é function TBoard.GetLogThreadCount: Integer; -var - i: Integer; begin - Result := 0; - if Length( ParentCategory.ParenTBBS.ShortSelectText ) = 0 then - begin - for i := 0 to Count - 1 do begin - if Items[i].IsLogFile then - inc(Result); - end; - end else begin - for i := 0 to Count - 1 do begin - if Items[i].IsLogFile then - begin - if Items[i].ShortTitle = '' then - Items[i].ShortTitle := GikoSys.ZenToHan(Items[i].Title); - if AnsiPos(ParentCategory.ParenTBBS.ShortSelectText, Items[i].ShortTitle) <> 0 then - inc(Result); - end; - end; - end; + Result := GetThreadCount(CountLog); end; - +//! iž‚ÝðŒ‚Éˆê’v‚·‚éƒXƒŒƒbƒh‚̐”‚ðŽæ“¾‚·‚é function TBoard.GetUserThreadCount: Integer; -var - i: Integer; begin - Result := 0; - if Length( ParentCategory.ParenTBBS.ShortSelectText ) = 0 then - Result := Count - else - for i := 0 to Count - 1 do begin - if Items[i].ShortTitle = '' then - Items[i].ShortTitle := GikoSys.ZenToHan(Items[i].Title); - if AnsiPos(ParentCategory.ParenTBBS.ShortSelectText, Items[i].ShortTitle) <> 0 then - inc(Result); - end; + Result := GetThreadCount(CountAll); end; - -function TBoard.GetNewThread(Index: Integer): TThreadItem; +//! DAT—Ž‚¿ƒXƒŒƒbƒh‚̐”‚ðŽæ“¾‚·‚é +function TBoard.GetArchiveThreadCount: Integer; +begin + Result := GetThreadCount(CountDat); +end; +//! ¶‘¶ƒXƒŒƒbƒh‚̐”‚ðŽæ“¾‚·‚é +function TBoard.GetLiveThreadCount: Integer; +begin + Result := GetThreadCount(CountLive); +end; +//! func‚ÌðŒ‚É“K‡‚·‚éIndex”Ԗڂ̃XƒŒƒbƒh‚ðŽæ“¾‚·‚é +function TBoard.GetThread(func :TThreadCount;const Index :Integer ): TThreadItem; var i: Integer; Cnt: Integer; @@ -1289,8 +1484,7 @@ begin if Length( ParentCategory.ParenTBBS.ShortSelectText ) = 0 then begin for i := 0 to Count - 1 do begin - if Items[i].NewArrival then - begin + if func(Items[i]) then begin if Index = Cnt then begin Result := Items[i]; Exit; @@ -1300,10 +1494,9 @@ begin end; end else begin for i := 0 to Count - 1 do begin - if Items[i].NewArrival then - begin - if Items[i].ShortTitle = '' then - Items[i].ShortTitle := GikoSys.ZenToHan(Items[i].Title); + if func(Items[i]) then begin + if Length(Items[i].ShortTitle) = 0 then + Items[i].ShortTitle := CustomStringReplace(ZenToHan(Items[i].Title), ' ', ''); if AnsiPos(ParentCategory.ParenTBBS.ShortSelectText, Items[i].ShortTitle) <> 0 then begin if Index = Cnt then begin Result := Items[i]; @@ -1315,74 +1508,30 @@ begin end; end; end; - +//! DAT—Ž‚¿ƒXƒŒƒbƒh‚ÅIndex”Ԗڂ̃XƒŒƒbƒh‚ðŽæ“¾‚·‚é +function TBoard.GetArchiveThread(Index: Integer): TThreadItem; +begin + Result := GetThread(CountDat, Index); +end; +//! ¶‘¶ƒXƒŒƒbƒh‚ÅIndex”Ԗڂ̃XƒŒƒbƒh‚ðŽæ“¾‚·‚é +function TBoard.GetLiveThread(Index: Integer): TThreadItem; +begin + Result := GetThread(CountLive, Index); +end; +//! V’…ƒXƒŒƒbƒh‚ÅIndex”Ԗڂ̃XƒŒƒbƒh‚ðŽæ“¾‚·‚é +function TBoard.GetNewThread(Index: Integer): TThreadItem; +begin + Result := GetThread(CountNew, Index); +end; +//! Log‚ ‚èƒXƒŒƒbƒh‚ÌIndex”Ԗڂ̃XƒŒƒbƒh‚ðŽæ“¾‚·‚é function TBoard.GetLogThread(Index: Integer): TThreadItem; -var - i: Integer; - Cnt: Integer; begin - Cnt := 0; - if Length( ParentCategory.ParenTBBS.ShortSelectText ) = 0 then - begin - for i := 0 to Count - 1 do begin - if Items[i].IsLogFile then - begin - if Index = Cnt then begin - Result := Items[i]; - Exit; - end; - inc(Cnt); - end; - end; - end else begin - for i := 0 to Count - 1 do begin - if Items[i].IsLogFile then - begin - if Items[i].ShortTitle = '' then - Items[i].ShortTitle := GikoSys.ZenToHan(Items[i].Title); - if AnsiPos(ParentCategory.ParenTBBS.ShortSelectText, Items[i].ShortTitle) <> 0 then begin - if Index = Cnt then begin - Result := Items[i]; - Exit; - end; - inc(Cnt); - end; - end; - end; - end; - Result := nil; + Result := GetThread(CountLog, Index); end; - +//! iž‚Ý‚ÅIndex”Ԗڂ̃XƒŒƒbƒh‚ðŽæ“¾‚·‚é function TBoard.GetUserThread(Index: Integer): TThreadItem; -var - i: Integer; - Cnt: Integer; begin - Result := nil; - Cnt := 0; - if Length( ParentCategory.ParenTBBS.ShortSelectText ) = 0 then - begin - for i := 0 to Count - 1 do begin - if Index = Cnt then - begin - Result := Items[ i ]; - Exit; - end; - inc( Cnt ); - end; - end else begin - for i := 0 to Count - 1 do begin - if Items[i].ShortTitle = '' then - Items[i].ShortTitle := GikoSys.ZenToHan(Items[i].Title); - if AnsiPos(ParentCategory.ParenTBBS.ShortSelectText, Items[i].ShortTitle) <> 0 then begin - if Index = Cnt then begin - Result := Items[i]; - Exit; - end; - inc(Cnt); - end; - end; - end; + Result := GetThread(CountAll, Index); end; procedure TBoard.BeginUpdate; @@ -1395,16 +1544,6 @@ begin FUpdate := True; end; -{class function TBoard.GetColumnName(Index: Integer): string; -begin - Result := COLUMN_THREADITEM[Index]; -end; - -class function TBoard.GetColumnCount: Integer; -begin - Result := Length(COLUMN_THREADITEM); -end;} - //constructor TThreadItem.Create(AOwner: TComponent); procedure TThreadItem.Init; begin @@ -1426,15 +1565,16 @@ begin FUpdate := True; FURL := ''; - FBoardPlugIn := nil; + FJumpAddress := 0; end; // ************************************************************************* // ŠO•””ƒvƒ‰ƒOƒCƒ“‚ðŽw’肵‚½ƒRƒ“ƒXƒgƒ‰ƒNƒ^ // ************************************************************************* constructor TThreadItem.Create( - inPlugIn : TBoardPlugIn; - inURL : string + const inPlugIn : TBoardPlugIn; + const inBoard : TBoard; + inURL : string ); var foundPos : Integer; @@ -1446,9 +1586,9 @@ begin inherited Create; Init; - - FBoardPlugIn := inPlugIn; - URL := inURL; + FParentBoard := inBoard; + //FBoardPlugIn := inPlugIn; + URL := inURL; if inPlugIn = nil then begin foundPos := Pos( READ_PATH, inURL ); @@ -1456,14 +1596,6 @@ begin // dat ‚Ì•Û‘¶ƒpƒX‚ðÝ’è GikoSys.ParseURI( inURL, protocol, host, path, document, port, bookmark ); GikoSys.Parse2chURL( inURL, path, document, BBSID, BBSKey ); - if GikoSys.Is2chHost( host ) then - FilePath := - IncludeTrailingPathDelimiter( GikoSys.Setting.LogFolder ) + - BBS2CH_LOG_FOLDER + PATH_DELIM + BBSID + PATH_DELIM + BBSKey + '.dat' - else - FilePath := - IncludeTrailingPathDelimiter( GikoSys.Setting.LogFolder ) + - EXTERNAL_LOG_FOLDER + PATH_DELIM + host + PATH_DELIM + BBSID + PATH_DELIM + BBSKey + '.dat'; FileName := BBSKey + '.dat'; IsLogFile := FileExists( FilePath ); URL := GikoSys.Get2chBrowsableThreadURL( inURL ); @@ -1474,39 +1606,46 @@ begin end; end; - // ************************************************************************* -// ƒfƒXƒgƒ‰ƒNƒ^ +// ŠO•””ƒvƒ‰ƒOƒCƒ“‚ðŽw’肵‚½ƒRƒ“ƒXƒgƒ‰ƒNƒ^ Log—L‚è‚©‚Ç‚¤‚©”»’fÏ‚Ý +// FileName‚àŽæ“¾Ï‚݁@¨@ReadSubject—p // ************************************************************************* -destructor TThreadItem.Destroy; +constructor TThreadItem.Create( + const inPlugIn : TBoardPlugIn; + const inBoard : TBoard; + const inURL : string; + inExist: Boolean; + const inFilename: string +); begin - // ƒvƒ‰ƒOƒCƒ“‚É TThreadItem ‚ª”jŠü‚³‚ꂽ‚±‚Æ‚ð“`‚¦‚é - if IsBoardPlugInAvailable then - FBoardPlugIn.DisposeThreadItem( DWORD( Self ) ); + inherited Create; + Init; + FParentBoard := inBoard; + URL := inURL; - inherited; + if inPlugIn = nil then begin + // dat ‚Ì•Û‘¶ƒpƒX‚ðÝ’è + FileName := inFilename; + IsLogFile := inExist; + URL := inURL; + end else begin + // ƒvƒ‰ƒOƒCƒ“‚É TThreadItem ‚ªì¬‚³‚ꂽ‚±‚Æ‚ð“`‚¦‚é + inPlugIn.CreateThreadItem( DWORD( Self ) ); + end; end; - // ************************************************************************* -// ŠO•””ƒvƒ‰ƒOƒCƒ“‚ªŽg—p‰Â”\‚© +// ƒfƒXƒgƒ‰ƒNƒ^ // ************************************************************************* -function TThreadItem.IsBoardPlugInAvailable : Boolean; +destructor TThreadItem.Destroy; begin - repeat - if BoardPlugIn = nil then - Break; - - if not Assigned( Pointer( BoardPlugIn.Module ) ) then - Break; - - Result := True; - Exit; - until True; + // ƒvƒ‰ƒOƒCƒ“‚É TThreadItem ‚ª”jŠü‚³‚ꂽ‚±‚Æ‚ð“`‚¦‚é + if Self.ParentBoard.IsBoardPlugInAvailable then + Self.ParentBoard.BoardPlugIn.DisposeThreadItem( DWORD( Self ) ); - Result := False; + inherited; end; @@ -1573,31 +1712,8 @@ begin end; end; -{function TThreadItem.GetOldDatgzURL: string; -var - Protocol, Host, Path, Document, Port, Bookmark: string; +function TThreadItem.GetOfflawCgiURL(const SessionID: string): string; begin - Result := Format('%s%s/%.3s/%s.gz', [ParentBoard.URL, - 'kako', - FileName, - FileName]); - if FDownloadHost <> '' then begin - ParseURI(Result, Protocol, Host, Path, Document, Port, Bookmark); - Result := Format('%s://%s%s%s', [Protocol, - DownloadHost, - Path, - Document]); - - end; -end;} - -function TThreadItem.GetOfflawCgiURL(SessionID: string): string; -//var -// Protocol, Host, Path, Document, Port, Bookmark: string; -begin -// Result := GikoSys.UrlToServer(ParentBoard.URL) -// + 'test/offlaw.cgi/' + ParentBoard.BBSID + '/' -// + ChangeFileExt(FileName, '') + '/?raw=.0&sid=' + HttpEncode(SessionID); if FDownloadHost = '' then begin Result := GikoSys.UrlToServer(ParentBoard.URL) + 'test/offlaw.cgi/' + ParentBoard.BBSID + '/' @@ -1608,13 +1724,69 @@ begin Result := 'http://' + FDownloadHost + '/test/offlaw.cgi/' + ParentBoard.BBSID + '/' + ChangeFileExt(FileName, '') + '/?raw=.0&sid=' + HttpEncode(SessionID); -// Result := Format('%s://%s%s%s', [Protocol, -// DownloadHost, -// Path, -// Document]); end; end; +function TThreadItem.GetOfflaw2SoURL: string; +begin + Result := GikoSys.UrlToServer(ParentBoard.URL) + + 'test/offlaw2.so?shiro=kuma&bbs=' + ParentBoard.BBSID + + '&key=' + ChangeFileExt(FileName, ''); +end; + +function TThreadItem.GetRokkaURL(const SessionID: string): string; +var + Domain: string; + Host: string; + Idx: Integer; + HostPos: Integer; +begin + if FDownloadHost = '' then begin + Idx := AnsiPos('.2ch.net/', ParentBoard.URL); + if (Idx > 0) then begin + Domain := '2ch.net'; + end else begin + Idx := AnsiPos('.bbspink.com/', ParentBoard.URL); + if (Idx > 0) then + Domain := 'bbspink.com'; + end; + if (Idx > 0) then begin + HostPos := AnsiPos('://', ParentBoard.URL) + 3; + Host := Copy(ParentBoard.URL, HostPos, Idx - HostPos); + end; + end else begin + Idx := AnsiPos('.2ch.net', FDownloadHost); + if (Idx > 0) then begin + Domain := '2ch.net'; + end else begin + Idx := AnsiPos('.bbspink.com', FDownloadHost); + if (Idx > 0) then + Domain := 'bbspink.com'; + end; + if (Idx > 0) then begin + Host := Copy(FDownloadHost, 1, Idx - 1); + end; + end; + + if ((Domain = '') or (Host = '')) then + Result := '' + else + Result := 'http://rokka.' + Domain + '/' + Host + '/' + + ParentBoard.BBSID + '/' + ChangeFileExt(FileName, '') + + '/?sid=' + SessionID; +end; + +// ŠO•””‰ߋŽƒƒOURLŽæ“¾ +function TThreadItem.GetExternalBoardKakoDatURL: string; +var + DatNo: string; +begin + DatNo := ChangeFileExt(FileName, ''); + //http://xxx.vip2ch.com/xxx/kako/1234/12345/1234567890.dat + Result := Format('%s%s/%.4s/%.5s/%s.dat', [ParentBoard.URL, 'kako', DatNo, DatNo, DatNo]); +end; +// ŠO•””‰ߋŽƒƒOURLŽæ“¾ + function TThreadItem.GetSendURL: string; begin Result := GikoSys.UrlToServer(ParentBoard.URL) @@ -1622,12 +1794,20 @@ begin end; procedure TThreadItem.DeleteLogFile; +var + tmpFileName: String; begin ParentBoard.BeginUpdate; + if FUnRead then + ParentBoard.UnRead := ParentBoard.UnRead - 1; DeleteFile(GetThreadFileName); - if FileExists(ChangeFileExt(GetThreadFileName,'.NG')) = true then - DeleteFile(ChangeFileExt(GetThreadFileName,'.NG')); + //ŽŽŒ±“I‚Étmp‚àíœ‚µ‚Ä‚Ý‚é + tmpFileName := StringReplace(GetThreadFileName, 'dat', 'tmp', [rfReplaceAll]); + DeleteFile(tmpFileName); + + if FileExists(ChangeFileExt(GetThreadFileName,'.NG')) = true then + DeleteFile(ChangeFileExt(GetThreadFileName,'.NG')); FRoundDate := ZERO_DATE; FLastModified := ZERO_DATE; FSize := 0; @@ -1654,7 +1834,7 @@ begin if Length( FilePath ) > 0 then Result := FilePath else - Result := IncludeTrailingPathDelimiter( GikoSys.Setting.LogFolder ) + Result := GikoSys.Setting.LogFolderP + BBS2CH_LOG_FOLDER + PATH_DELIM + ParentBoard.BBSID + PATH_DELIM + FileName; end; @@ -1666,14 +1846,6 @@ begin ParentBoard.FModified := True; end; -{procedure TThreadItem.SetRoundNo(i: Integer); -begin - if FRoundNo = i then Exit; - FRoundNo := i; - if FUpdate and (ParentBoard <> nil) then - ParentBoard.FModified := True; -end;} - procedure TThreadItem.SetRound(b: Boolean); begin if b then @@ -1686,7 +1858,7 @@ begin ParentBoard.FModified := True; end; -procedure TThreadItem.SetRoundName(s: string); +procedure TThreadItem.SetRoundName(const s: string); begin if FRoundName = s then Exit; FRoundName := s; @@ -1694,6 +1866,7 @@ begin ParentBoard.FModified := True; end; + procedure TThreadItem.SetKokomade(i: Integer); begin if FKokomade = i then Exit; @@ -1706,8 +1879,14 @@ procedure TThreadItem.SetUnRead(b: Boolean); begin if FUnRead = b then Exit; FUnRead := b; - if FUpdate and (ParentBoard <> nil) then + if FUpdate and (ParentBoard <> nil) then begin ParentBoard.FModified := True; + if FUnRead then begin + ParentBoard.UnRead := ParentBoard.UnRead + 1; + end else begin + ParentBoard.UnRead := ParentBoard.UnRead - 1; + end; + end; end; procedure TThreadItem.SetScrollTop(i: Integer); @@ -1728,28 +1907,15 @@ begin FUpdate := True; end; -{initialization - BBS2ch := TBBS.Create; - -finalization - if BBS2ch <> nil then - BBS2ch.Free;} function TThreadItem.GetCreateDate: TDateTime; -var - unixtime: Int64; - tmp: string; begin // ƒtƒ@ƒCƒ‹–¼‚©‚çƒXƒŒì¬“úŽž‚ð‹‚ß‚é - try - if ( GikoSys.Setting.CreationTimeLogs ) and not IsLogFile then + try + if ( GikoSys.Setting.CreationTimeLogs ) and not IsLogFile then Result := ZERO_DATE else begin // ƒƒOƒtƒ@ƒCƒ‹‚ÌŠg’£Žq‚ð‚Í‚¸‚µ‚½‚à‚Ì‚ªƒXƒŒì¬“úŽž - tmp := ChangeFileExt(FFileName, ''); - if ( Length(tmp) = 9) and ( tmp[1] = '0' ) then - Insert('1', tmp, 1); - unixtime := StrToInt64(tmp); - Result := UnixToDateTime(unixtime) + OffsetFromUTC; + Result := GikoSys.GetCreateDateFromName(FFileName); if GikoSys.Setting.FutureThread then begin if CompareDateTime(Result, Now) = 1 then Result := ZERO_DATE; @@ -1761,6 +1927,100 @@ begin Result := ZERO_DATE; end; end; +function TThreadItem.GetFilePath: String; +var + path : String; +begin + path := ExtractFilePath(Self.ParentBoard.FilePath) + Self.FileName; + Result := path; +end; + +destructor TBoardGroup.Destroy; +begin + Clear; + inherited; +end; +procedure TBoardGroup.Clear; +var + i : Integer; +begin + for i := Self.Count - 1 downto 0 do begin + try + TBoard(Self.Objects[i]).Free; + except + end; + end; + inherited Clear; + Self.Capacity := 0; + try + if FBoardPlugIn <> nil then + FBoardPlugIn.Free; + FBoardPlugIn := nil; + except + end; + +end; + +function TSpecialBoard.Add(item: TThreadItem): integer; +begin + Result := inherited AddObject(Item.URL, Item); +end; + +procedure TSpecialBoard.Clear; +var + i: integer; +begin + for i := Count - 1 downto 0 do + DeleteList(i); + Capacity := 0; +end; + +/////////////// +constructor TThreadNgList.Create; +begin + inherited Create; + + FFilePath := GikoSys.GetNGWordsDir; + if not DirectoryExists(FFilePath) then + ForceDirectories(FFilePath); + if (FFilePath[Length(FFilePath)] <> '\') then + FFilePath := FFilePath + '\'; + FFilePath := FFilePath + THREAD_NG_FILE; + Load; +end; + +procedure TThreadNgList.Load; +begin + if (FileExists(FFilePath)) then begin + try + LoadFromFile(FFilePath); + finally + end; + end; +end; + +procedure TThreadNgList.Save; +begin + try + SaveToFile(FFilePath); + finally + end; +end; + +function TThreadNgList.IsNG(const Title: String): Boolean; +var + Cnt: Integer; + MaxCnt: Integer; +begin + MaxCnt := Count - 1; + for Cnt := 0 to MaxCnt do begin + if (Pos(Strings[Cnt], Title) > 0) then begin + Result := True; + Exit; + end; + end; + Result := False; +end; end.