Develop and Download Open Source Software

Browse CVS Repository

Contents of /gikonavigoeson/gikonavi/GikoSystem.pas

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.260 - (show annotations) (download) (as text)
Sun Sep 11 09:41:45 2011 UTC (12 years, 6 months ago) by h677
Branch: MAIN
CVS Tags: v1_63_1_819, v1_63_0_818, v1_63_0_817, v1_63_0_816, v1_63_0_815, HEAD
Branch point for: Bb63
Changes since 1.259: +1 -1 lines
File MIME type: text/x-pascal
bata63、ヒケケソキ

1 unit GikoSystem;
2
3 interface
4
5 uses
6 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
7 ComCtrls, {IniFiles,} ShellAPI, ActnList, Math,
8 {$IF Defined(DELPRO) }
9 SHDocVw,
10 MSHTML,
11 {$ELSE}
12 SHDocVw_TLB,
13 MSHTML_TLB,
14 {$IFEND}
15 {HttpApp,} URLMon, IdGlobal, IdURI, {Masks,}
16 Setting, BoardGroup, gzip, Dolib, bmRegExp, AbonUnit,
17 ExternalBoardManager, ExternalBoardPlugInMain,
18 GikoBayesian, GikoMessage, Belib;
19
20 type
21 TVerResourceKey = (
22 vrComments, //!< 繧ウ繝。繝ウ繝?/span>
23 vrCompanyName, //!< 莨夂、セ蜷?/span>
24 vrFileDescription, //!< 隱ャ譏?/span>
25 vrFileVersion, //!< 繝輔ぃ繧、繝ォ繝舌?繧ク繝ァ繝ウ
26 vrInternalName, //!< 蜀?Κ蜷?/span>
27 vrLegalCopyright, //!< 闡嶺ス懈ィゥ
28 vrLegalTrademarks, //!< 蝠?ィ?/span>
29 vrOriginalFilename, //!< 豁」蠑上ヵ繧。繧、繝ォ蜷?/span>
30 vrPrivateBuild, //!< 繝励Λ繧、繝吶?繝医ン繝ォ繝画ュ蝣ア
31 vrProductName, //!< 陬ス蜩∝錐
32 vrProductVersion, //!< 陬ス蜩√ヰ繝シ繧ク繝ァ繝ウ
33 vrSpecialBuild); //!< 繧ケ繝壹す繝」繝ォ繝薙Ν繝画ュ蝣ア
34
35 //! BBS繧ソ繧、繝?/span>
36 TGikoBBSType = (gbt2ch);
37 //! 繝ュ繧ー繧ソ繧、繝?/span>
38 TGikoLogType = (glt2chNew, glt2chOld);
39 //! 繝。繝?そ繝シ繧ク繧「繧、繧ウ繝ウ
40 TGikoMessageIcon = (gmiOK, gmiSAD, gmiNG, gmiWhat, gmiNone);
41 //! URL繧ェ繝シ繝励Φ繝悶Λ繧ヲ繧カ繧ソ繧、繝?/span>
42 TGikoBrowserType = (gbtIE, gbtUserApp, gbtAuto);
43
44
45 TStrTokSeparator = set of Char;
46 TStrTokRec = record
47 Str: string;
48 Pos: Integer;
49 end;
50
51 //! 繧、繝ウ繝?ャ繧ッ繧ケ繝輔ぃ繧、繝ォ繝ャ繧ウ繝シ繝?/span>
52 TIndexRec = record
53 FNo: Integer;
54 FFileName: string;
55 FTitle: string;
56 FCount: Integer;
57 FSize: Integer;
58 // FRoundNo: Integer;
59 FRoundDate: TDateTime;
60 FLastModified: TDateTime;
61 FKokomade: Integer;
62 FNewReceive: Integer;
63 FMishiyou: Boolean; //!< 譛ェ菴ソ逕ィ
64 FUnRead: Boolean;
65 FScrollTop: Integer;
66 //Index Ver 1.01
67 FAllResCount: Integer;
68 FNewResCount: Integer;
69 FAgeSage: TGikoAgeSage;
70 end;
71
72 //! 繧オ繝悶ず繧ァ繧ッ繝医Ξ繧ウ繝シ繝?/span>
73 TSubjectRec = record
74 FFileName: string;
75 FTitle: string;
76 FCount: Integer;
77 end;
78
79 //! 繝ャ繧ケ繝ャ繧ウ繝シ繝峨∈縺ョ繝昴う繝ウ繧ソ
80 PResRec = ^TResRec;
81
82 //! 繝ャ繧ケ繝ャ繧ウ繝シ繝?/span>
83 TResRec = record
84 FTitle: string;
85 FMailTo: string;
86 FName: string;
87 FDateTime: string;
88 FBody: string;
89 FType: TGikoLogType;
90 end;
91
92 //! URLPath繝ャ繧ウ繝シ繝?/span>
93 TPathRec = record
94 FBBS: string; //!< BBSID
95 FKey: string; //!< ThreadID
96 FSt: Int64; //!< 髢句ァ九Ξ繧ケ逡ェ
97 FTo: Int64; //!< 邨ゆコ?Ξ繧ケ逡ェ
98 FFirst: Boolean; //!< >>1縺ョ陦ィ遉コ
99 FStBegin: Boolean; //!< 1縲懆。ィ遉コ
100 FToEnd: Boolean; //!< 縲懈怙蠕後∪縺ァ陦ィ遉コ
101 FDone: Boolean; //!< 謌仙粥
102 FNoParam: Boolean; //!< 繝ャ繧ケ逡ェ繝代Λ繝。繝シ繧ソ縺ェ縺?/span>
103 end;
104
105 TGikoSys = class(TObject)
106 private
107 { Private 螳」險? }
108 FSetting: TSetting;
109 FDolib: TDolib;
110 FAWKStr: TAWKStr;
111 FResRange : Longint;
112 FBayesian : TGikoBayesian; //!< 繝吶う繧ク繧「繝ウ繝輔ぅ繝ォ繧ソ
113 FVersion : String; //!< 繝輔ぃ繧、繝ォ繝舌?繧ク繝ァ繝ウ
114 FGikoMessage: TGikoMessage;
115 FBelib: TBelib;
116 //! 縺ゅk繧サ繝代Ξ繝シ繧ソ縺ァ蛹コ蛻?i繧後◆譁?ュ怜?縺九i?守分逶ョ縺ョ譁?ュ怜?繧貞叙繧雁?縺?/span>
117 function ChooseString(const Text, Separator: string; Index: integer): string;
118 //! 荳?譎ゅヵ繧。繧、繝ォ縺九i縺ョ蠕ゥ譌ァ
119 procedure RestoreThreadData(Board: TBoard);
120 public
121 { Public 螳」險? }
122 FAbon : TAbon;
123 FSelectResFilter : TAbon;
124 //FBoardURLList: TStringList;
125 constructor Create;
126
127 destructor Destroy; override;
128 property ResRange : Longint read FResRange write FResRange;
129 //! 繝舌?繧ク繝ァ繝ウ諠??ア
130 property Version : String read FVersion;
131 function IsNumeric(s: string): boolean;
132 function IsFloat(s: string): boolean;
133 function DirectoryExistsEx(const Name: string): Boolean;
134 function ForceDirectoriesEx(Dir: string): Boolean;
135
136 function GetBoardFileName: string;
137 function GetCustomBoardFileName: string;
138 function GetHtmlTempFileName: string;
139 function GetAppDir: string;
140 function GetTempFolder: string;
141 function GetSentFileName: string;
142 function GetConfigDir: string;
143 function GetSkinDir: string;
144 function GetSkinHeaderFileName: string;
145 function GetSkinFooterFileName: string;
146 function GetSkinResFileName: string;
147 function GetSkinNewResFileName: string;
148 function GetSkinBookmarkFileName: string;
149 function GetSkinNewmarkFileName: string;
150 function GetStyleSheetDir: string;
151 function GetOutBoxFileName: string;
152 function GetUserAgent: string;
153 function GetSambaFileName : string;
154
155 function GetMainKeyFileName : String;
156 function GetEditorKeyFileName: String;
157 function GetInputAssistFileName: String;
158 procedure ReadSubjectFile(Board: TBoard);
159 procedure CreateThreadDat(Board: TBoard);
160 procedure WriteThreadDat(Board: TBoard);
161 function ParseIndexLine(Line: string): TIndexRec;
162 procedure GetFileList(Path: string; Mask: string; var List: TStringList; SubDir: Boolean; IsPathAdd: Boolean); overload;
163 procedure GetFileList(Path: string; Mask: string; var List: TStringList; IsPathAdd: Boolean); overload;//繧オ繝悶ヵ繧ゥ繝ォ繝?縺ッ讀懃エ「縺励↑縺?/span>
164 procedure GetDirectoryList(Path: string; Mask: string; List: TStringList; SubDir: Boolean);
165
166 function DivideSubject(Line: string): TSubjectRec;
167 property Setting: TSetting read FSetting write FSetting;
168 property Dolib: TDolib read FDolib write FDolib;
169 property Belib: TBelib read FBelib write FBelib;
170
171 function UrlToID(url: string): string;
172 function UrlToServer(url: string): string;
173
174 function StrTokFirst(const s:string; const sep:TStrTokSeparator; var Rec:TStrTokRec):string;
175 function StrTokNext(const sep:TStrTokSeparator; var Rec:TStrTokRec): string;
176
177 function GetFileSize(FileName : string) : longint;
178 function GetFileLineCount(FileName : string): longint;
179 function IntToDateTime(val: Int64): TDateTime;
180 function DateTimeToInt(ADate: TDateTime): Int64;
181
182 function ReadThreadFile(FileName: string; Line: Integer): string;
183
184 procedure MenuFont(Font: TFont);
185
186 // function RemoveToken(var s:string; const delimiter:string):string;
187 function GetTokenIndex(s: string; delimiter: string; index: Integer): string;
188
189 function GetShortName(const LongName: string; ALength: integer): string;
190 function BoolToInt(b: Boolean): Integer;
191 function IntToBool(i: Integer): Boolean;
192 function GzipDecompress(ResStream: TStream; ContentEncoding: string): string;
193 procedure LoadKeySetting(ActionList: TActionList; FileName: String);
194 procedure SaveKeySetting(ActionList: TActionList; FileName: String);
195 procedure CreateProcess(const AppPath: string; const Param: string);
196 procedure OpenBrowser(URL: string; BrowserType: TGikoBrowserType);
197 function HTMLDecode(const AStr: String): String;
198 function GetHRefText(s: string): string;
199 function Is2chHost(Host: string): Boolean;
200 function Parse2chURL(const url: string; const path: string; const document: string; var BBSID: string; var BBSKey: string): Boolean;
201 function Parse2chURL2(URL: string): TPathRec;
202 procedure ParseURI(const URL : string; var Protocol, Host, Path, Document, Port, Bookmark: string);
203 function GetVersionBuild: Integer;
204 function GetBrowsableThreadURL( inURL : string ) : string;
205 function GetThreadURL2BoardURL( inURL : string ) : string;
206 function Get2chThreadURL2BoardURL( inURL : string ) : string;
207 function Get2chBrowsableThreadURL( inURL : string ) : string;
208 function Get2chBoard2ThreadURL( inBoard : TBoard; inKey : string ) : string;
209 procedure ListBoardFile;
210 procedure ReadBoardFile( bbs : TBBS );
211
212 function GetUnknownCategory : TCategory;
213 function GetUnknownBoard( inPlugIn : TBoardPlugIn; inURL : string ) : TBoard;
214
215 procedure GetPopupResNumber(URL : string; var stRes, endRes : Int64);
216
217 property Bayesian : TGikoBayesian read FBayesian write FBayesian;
218 function CreateResAnchor(var Numbers: TStringList; ThreadItem: TThreadItem; limited: Integer):string;
219 procedure GetSameIDRes(const AID : string; ThreadItem: TThreadItem;var body: TStringList); overload;
220 procedure GetSameIDRes(AIDNum : Integer; ThreadItem: TThreadItem;var body: TStringList); overload;
221 function GetResID(AIDNum: Integer; ThreadItem: TThreadItem): String;
222 function ExtructResID(ADateStr: String): String;
223 //! 蜊倩ェ櫁ァ」譫?/span>
224 procedure SpamCountWord( const text : string; wordCount : TWordCount );
225 //! 蟄ヲ鄙偵け繝ェ繧「
226 procedure SpamForget( wordCount : TWordCount; isSpam : Boolean );
227 //! 繧ケ繝代Β蟄ヲ鄙?/span>
228 procedure SpamLearn( wordCount : TWordCount; isSpam : Boolean );
229 //! 繧ケ繝代Β蠎ヲ謨ー
230 function SpamParse( const text : string; wordCount : TWordCount ) : Extended;
231
232 //! 蠑墓焚縺ォ騾√i繧後※縺阪◆譌・莉?ID驛ィ縺ォBE縺ョ譁?ュ怜?縺後≠縺」縺溘i縲√?繝ュ繝輔ぃ繧、繝ォ縺ク縺ョ繝ェ繝ウ繧ッ繧定ソス蜉?
233 function AddBeProfileLink(AID : string; ANum: Integer): string;
234 //! 繝舌?繧ク繝ァ繝ウ諠??ア縺ョ蜿門セ?/span>
235 function GetVersionInfo(KeyWord: TVerResourceKey): string;
236 //! Plugin縺ョ諠??ア縺ョ蜿門セ?/span>
237 function GetPluginsInfo(): string;
238 //! IE縺ョ繝舌?繧ク繝ァ繝ウ諠??ア縺ョ蜿門セ?/span>
239 function GetIEVersion: string;
240 function SetUserOptionalStyle(): string;
241 //! 繧ョ繧ウ繝翫ン縺ョ繝。繝?そ繝シ繧ク繧定ィュ螳壹☆繧?/span>
242 procedure SetGikoMessage;
243 //! 繧ョ繧ウ繝翫ン縺ョ繝。繝?そ繝シ繧ク繧貞叙蠕励☆繧?/span>
244 function GetGikoMessage(MesType: TGikoMessageListType): String;
245 //! GMT縺ョ譎ょ綾繧探DateTime縺ォ螟画鋤縺吶k
246 function DateStrToDateTime(const DateStr: string): TDateTime;
247 //! User32.dll縺悟茜逕ィ縺ァ縺阪k縺?/span>
248 function CanUser32DLL: Boolean;
249 //! OE蠑慕畑隨ヲ蜿門セ?/span>
250 function GetOEIndentChar : string;
251 //! 鄂ョ謠幄ィュ螳壹ヵ繧。繧、繝ォ蜿門セ?/span>
252 function GetReplaceFileName: String;
253 //! 繧、繝ウ繝?ャ繧ッ繧ケ縺ォ縺ェ縺?at?医?縺舌ldat?峨?霑ス蜉?
254 procedure AddOutofIndexDat(Board: TBoard; DatList: TStringList; AllCreate: boolean = True);
255 //! 繝輔ぃ繧、繝ォ蜷阪°繧峨?繧ケ繝ャ繝?ラ菴懈?譌・縺ョ蜿門セ?/span>
256 function GetCreateDateFromName(FileName: String): TDateTime;
257 function GetExtpreviewFileName: String;
258
259 procedure ShowRefCount(msg: String; unk: IUnknown);
260 //! 蜀帝匱縺ョ譖クCookie蜿門セ?/span>
261 function GetBoukenCookie(AURL: String): String;
262 //! 蜀帝匱縺ョ譖クCookie險ュ螳?/span>
263 procedure SetBoukenCookie(ACookieValue, ADomain: String);
264 //! 蜀帝匱縺ョ譖クCookie蜑企勁
265 procedure DelBoukenCookie(ADomain: String);
266 //! 蜀帝匱縺ョ譖クDomain荳?隕ァ蜿門セ?/span>
267 procedure GetBoukenDomain(var ADomain: TStringList);
268 //! 蜀帝匱縺ョ譖ク繝峨Γ繧、繝ウ蜷垢ookie蜿門セ?/span>
269 function GetBouken(AURL: String; var Domain: String): String;
270 end;
271
272 var
273 GikoSys: TGikoSys;
274 const
275 //LENGTH_RESTITLE = 40;
276 ZERO_DATE: Integer = 25569;
277 BETA_VERSION_NAME_E = 'beta';
278 BETA_VERSION_NAME_J = '?奇セ橸セ?';
279 BETA_VERSION = 63;
280 BETA_VERSION_BUILD = ''; //!< debug迚医↑縺ゥ
281 APP_NAME = 'gikoNavi';
282 BE_PHP_URL = 'http://be.2ch.net/test/p.php?i=';
283
284
285 implementation
286
287 uses
288 Giko, RoundData, Favorite, Registry, HTMLCreate, MojuUtils, Sort, YofUtils,
289 IniFiles, DateUtils, SkinFiles;
290
291 const
292 FOLDER_INDEX_VERSION = '1.01';
293 USER_AGENT = 'Monazilla';
294 DEFAULT_NGWORD_FILE_NAME : String = 'NGword.txt';
295 NGWORDs_DIR_NAME : String = 'NGwords';
296
297 READ_PATH: string = '/test/read.cgi/';
298 HTML_READ_PATH: string = '/test/read.html/';
299 OLD_READ_PATH: string = '/test/read.cgi?';
300 KAKO_PATH: string = '/kako/';
301
302 KeyWordStr: array [TVerResourceKey] of String = (
303 'Comments',
304 'CompanyName',
305 'FileDescription',
306 'FileVersion',
307 'InternalName',
308 'LegalCopyright',
309 'LegalTrademarks',
310 'OriginalFilename',
311 'PrivateBuild',
312 'ProductName',
313 'ProductVersion',
314 'SpecialBuild');
315
316 // *************************************************************************
317 //! GikoSys繧ウ繝ウ繧ケ繝医Λ繧ッ繧ソ
318 // *************************************************************************
319 constructor TGikoSys.Create;
320 begin
321 Inherited;
322 FSetting := TSetting.Create;
323 FDolib := TDolib.Create;
324 FBelib := TBelib.Create;
325 FAWKStr := TAWKStr.Create(nil);
326 if DirectoryExists(GetConfigDir) = false then begin
327 CreateDir(GetConfigDir);
328 end;
329 FAbon := TAbon.Create;
330 FAbon.IgnoreKana := FSetting.IgnoreKana;
331 FAbon.Setroot(GetConfigDir+NGWORDs_DIR_NAME);
332 FAbon.GoHome;
333 FAbon.ReturnNGwordLineNum := FSetting.ShowNGLinesNum;
334 FAbon.SetNGResAnchor := FSetting.AddResAnchor;
335 FAbon.DeleteSyria := FSetting.DeleteSyria;
336 FAbon.Deleterlo := FSetting.AbonDeleterlo;
337 FAbon.Replaceul := FSetting.AbonReplaceul;
338 FAbon.AbonPopupRes := FSetting.PopUpAbon;
339
340 FSelectResFilter := TAbon.Create;
341 FSelectResFilter.IgnoreKana := True;
342 // 邨槭j霎シ繧?縺ィ縺阪?讌オ蜉帑ク?隕ァ縺瑚ヲ九i繧後k縺サ縺?′縺?>縺ョ縺ァ莉悶?螳悟?縺ォ蜑企勁
343 FSelectResFilter.AbonString := '';
344 //
345 ResRange := FSetting.ResRange;
346 FVersion := Trim(GetVersionInfo(vrFileVersion));
347 FBayesian := TGikoBayesian.Create;
348 //FBoardURLList := TStringList.Create;
349 //繝。繝?そ繝シ繧ク縺ョ菴懈?
350 FGikoMessage := TGikoMessage.Create;
351 end;
352
353 // *************************************************************************
354 //! GikoSys繝?せ繝医Λ繧ッ繧ソ
355 // *************************************************************************
356 destructor TGikoSys.Destroy;
357 var
358 i: Integer;
359 FileList: TStringList;
360 begin
361 //繝?Φ繝昴Λ繝ェHTML繧貞炎髯、
362 FileList := TStringList.Create;
363 try
364 FileList.BeginUpdate;
365 GetFileList(GetTempFolder, '*.html', FileList, False, True);
366 FileList.EndUpdate;
367 for i := 0 to FileList.Count - 1 do begin
368 DeleteFile(FileList[i]);
369 end;
370 finally
371 FileList.Free;
372 end;
373 FreeAndNil(FGikoMessage);
374 FreeAndNil(FBayesian);
375 FreeAndNil(FSelectResFilter);
376 FreeAndNil(FAbon);
377 FreeAndNil(FAWKStr);
378 FreeAndNil(FBelib);
379 FreeAndNil(FDolib);
380 FreeAndNil(FSetting);
381 inherited;
382 end;
383
384 {!
385 \brief 譁?ュ怜?謨ー蟄励メ繧ァ繝?け
386 \param s 繝√ぉ繝?け縺吶k譁?ュ怜?
387 \return s 縺檎ャヲ蜿キ莉倥″謨エ謨ー縺ィ縺励※隱崎ュ伜庄閭ス縺ェ繧 True
388 }
389 {$HINTS OFF}
390 function TGikoSys.IsNumeric(s: string): boolean;
391 var
392 e: integer;
393 v: integer;
394 begin
395 Val(s, v, e);
396 Result := e = 0;
397 end;
398 {$HINTS ON}
399
400 {!
401 \brief 譁?ュ怜?豬ョ蜍募ー乗焚轤ケ謨ー蟄励メ繧ァ繝?け
402 \param s 繝√ぉ繝?け縺吶k譁?ュ怜?
403 \return s 縺檎ャヲ蜿キ莉倥″豬ョ蜍募ー乗焚縺ィ縺励※隱崎ュ伜庄閭ス縺ェ繧 True
404 }
405 function TGikoSys.IsFloat(s: string): boolean;
406 var
407 v: Extended;
408 begin
409 Result := TextToFloat(PChar(s), v, fvExtended);
410 end;
411
412 // *************************************************************************
413 //! 繝懊?繝峨ヵ繧。繧、繝ォ蜷榊叙蠕暦シ医ヱ繧ケ?九ヵ繧。繧、繝ォ蜷搾シ?/span>
414 // *************************************************************************
415 function TGikoSys.GetBoardFileName: string;
416 begin
417 Result := Setting.GetBoardFileName;
418 end;
419
420 // *************************************************************************
421 //! 繝懊?繝峨ヵ繧。繧、繝ォ蜷榊叙蠕暦シ医ヱ繧ケ?九ヵ繧。繧、繝ォ蜷搾シ?/span>
422 // *************************************************************************
423 function TGikoSys.GetCustomBoardFileName: string;
424 begin
425 Result := Setting.GetCustomBoardFileName;
426 end;
427
428 // *************************************************************************
429 //! 繝?Φ繝昴Λ繝ェ繝輔か繝ォ繝?繝シ蜷榊叙蠕?/span>
430 // *************************************************************************
431 function TGikoSys.GetHtmlTempFileName: string;
432 begin
433 Result := Setting.GetHtmlTempFileName;
434 end;
435
436
437 // *************************************************************************
438 //! 螳溯。後ヵ繧。繧、繝ォ繝輔か繝ォ繝?蜿門セ?/span>
439 // *************************************************************************
440 function TGikoSys.GetAppDir: string;
441 begin
442 Result := Setting.GetAppDir;
443 end;
444
445 // *************************************************************************
446 //! TempHtml繝輔ぃ繧、繝ォ蜷榊叙蠕暦シ医ヱ繧ケ?九ヵ繧。繧、繝ォ蜷搾シ?/span>
447 // *************************************************************************
448 function TGikoSys.GetTempFolder: string;
449 begin
450 Result := Setting.GetTempFolder;
451 end;
452
453 // *************************************************************************
454 //! sent.ini繝輔ぃ繧、繝ォ蜷榊叙蠕暦シ医ヱ繧ケ?九ヵ繧。繧、繝ォ蜷搾シ?/span>
455 // *************************************************************************)
456 function TGikoSys.GetSentFileName: string;
457 begin
458 Result := Setting.GetSentFileName;
459 end;
460
461 // *************************************************************************
462 //! outbox.ini繝輔ぃ繧、繝ォ蜷榊叙蠕暦シ医ヱ繧ケ?九ヵ繧。繧、繝ォ蜷搾シ?/span>
463 // *************************************************************************
464 function TGikoSys.GetOutBoxFileName: string;
465 begin
466 Result := Setting.GetOutBoxFileName;
467 end;
468
469 // *************************************************************************
470 //! Config繝輔か繝ォ繝?蜿門セ?/span>
471 // *************************************************************************
472 function TGikoSys.GetConfigDir: string;
473 begin
474 Result := Setting.GetConfigDir;
475 end;
476
477 //! 繧ケ繧ソ繧、繝ォ繧キ繝シ繝医ヵ繧ゥ繝ォ繝?
478 function TGikoSys.GetStyleSheetDir: string;
479 begin
480 Result := Setting.GetStyleSheetDir;
481 end;
482
483 //! 繧ケ繧ュ繝ウ繝輔か繝ォ繝?
484 function TGikoSys.GetSkinDir: string;
485 begin
486 Result := Setting.GetSkinDir;
487 end;
488
489 //! Skin:繝倥ャ繝?縺ョ繝輔ぃ繧、繝ォ蜷?/span>
490 function TGikoSys.GetSkinHeaderFileName: string;
491 begin
492 Result := Setting.SkinFiles.GetSkinHeaderFileName;
493 end;
494
495 //! Skin:繝輔ャ繧ソ縺ョ繝輔ぃ繧、繝ォ蜷?/span>
496 function TGikoSys.GetSkinFooterFileName: string;
497 begin
498 Result := Setting.SkinFiles.GetSkinFooterFileName;
499 end;
500
501 //! Skin:譁ー逹?繝ャ繧ケ縺ョ繝輔ぃ繧、繝ォ蜷?/span>
502 function TGikoSys.GetSkinNewResFileName: string;
503 begin
504 Result := Setting.SkinFiles.GetSkinNewResFileName;
505 end;
506
507 //! Skin:髱樊眠逹?繝ャ繧ケ縺ョ繝輔ぃ繧、繝ォ蜷?/span>
508 function TGikoSys.GetSkinResFileName: string;
509 begin
510 Result := Setting.SkinFiles.GetSkinResFileName;
511 end;
512
513 //! Skin:縺励♀繧?縺薙%縺セ縺ァ隱ュ繧薙□)縺ョ繝輔ぃ繧、繝ォ蜷?/span>
514 function TGikoSys.GetSkinBookmarkFileName: string;
515 begin
516 Result := Setting.SkinFiles.GetSkinBookmarkFileName;
517 end;
518
519 //! Skin:縺励♀繧?譁ー逹?繝ャ繧ケ)縺ョ繝輔ぃ繧、繝ォ蜷?/span>
520 function TGikoSys.GetSkinNewmarkFileName: string;
521 begin
522 Result := Setting.SkinFiles.GetSkinNewmarkFileName;
523 end;
524
525 //! UserAgent蜿門セ?/span>
526 function TGikoSys.GetUserAgent: string;
527 begin
528 if Dolib.Connected then begin
529 Result := Format('%s %s/%s%d/%s', [
530 Dolib.UserAgent,
531 APP_NAME,
532 BETA_VERSION_NAME_E,
533 BETA_VERSION,
534 Version]);
535 end else begin
536 Result := Format('%s/%s %s/%s%d/%s', [
537 USER_AGENT,
538 Dolib.Version,
539 APP_NAME,
540 BETA_VERSION_NAME_E,
541 BETA_VERSION,
542 Version]);
543 end;
544 end;
545
546 {!
547 \brief 邨碁℃遘偵r TDateTime 縺ォ螟画鋤
548 \param val 1970/1/1/ 00:00:00 縺九i縺ョ邨碁℃遘?/span>
549 \return val 繧堤、コ縺 TDateTime
550 }
551 function TGikoSys.IntToDateTime(val: Int64): TDateTime;
552 begin
553 Result := ZERO_DATE + val / 86400.0;
554 end;
555
556 {!
557 \brief TDateTime 繧堤オ碁℃遘偵↓螟画鋤
558 \param ADate 螟画鋤縺吶k譎ょ綾
559 \return 1970/1/1/ 00:00:00 縺九i縺ョ邨碁℃遘?/span>
560 }
561 function TGikoSys.DateTimeToInt(ADate: TDateTime): Int64;
562 begin
563 Result := Trunc((ADate - ZERO_DATE) * 86400);
564 end;
565
566
567 {!
568 \brief Subject繝輔ぃ繧、繝ォRead
569 \param Board 繧ケ繝ャ荳?隕ァ繧貞叙蠕励☆繧区攸
570 }
571 procedure TGikoSys.ReadSubjectFile(Board: TBoard);
572 var
573 ThreadItem: TThreadItem;
574 FileName: string;
575 FileList: TStringList;
576 Index: Integer;
577 sl: TStringList;
578 i: Integer;
579 Rec: TIndexRec;
580 UnRead: Integer;
581 usePlugIn : Boolean;
582 islog : Boolean;
583 urlHead: String;
584 datFileCheck: Boolean;
585 {*
586 FavoThreadItem : TFavoriteThreadItem;
587 Node: TTreeNode;
588 *}
589 {$IFDEF DEBUG}
590 st, rt: Cardinal;
591 {$ENDIF}
592 begin
593 {$IFDEF DEBUG}
594 st := GetTickCount;
595 {$ENDIF}
596 if Board.IsThreadDatRead then
597 Exit;
598 Board.Clear;
599 UnRead := 0;
600 usePlugIn := Board.IsBoardPlugInAvailable;
601 //server := UrlToServer( Board.URL );
602 // 繧ケ繝ャ繝?ラ縺ァ蜈ア騾壹?URL驛ィ
603 if Board.is2ch then begin
604 urlHead := UrlToServer( Board.URL ) + 'test/read.cgi/' + Board.BBSID + '/';
605 end else begin
606 urlHead := UrlToServer( Board.URL ) + 'test/read.cgi?bbs=' + Board.BBSID + '&key=';
607 end;
608
609 FileName := Board.GetFolderIndexFileName;
610
611 //
612 datFileCheck := (Setting.CheckDatFile) or (not FileExists(FileName));
613 if (datFileCheck) then begin
614 FileList := TStringList.Create;
615 FileList.Sorted := True;
616 FileList.BeginUpdate;
617 //IsLogFile逕ィDAT繝輔ぃ繧、繝ォ繝ェ繧ケ繝?/span>
618 GetFileList(ExtractFileDir(Board.GetFolderIndexFileName), '*.dat', FileList, False);
619 FileList.EndUpdate;
620 end;
621
622 // 驥崎、?r髦イ縺?/span>
623 Board.BeginUpdate;
624 Board.Sorted := True;
625 sl := TStringList.Create;
626 try
627 if FileExists(FileName) then begin
628 sl.LoadFromFile(FileName);
629 //?定。檎岼縺九i?茨シ題。檎岼縺ッ繝舌?繧ク繝ァ繝ウ??/span>
630 for i := sl.Count - 1 downto 1 do begin
631 Rec := ParseIndexLine(sl[i]);
632 if (datFileCheck) then begin
633 islog := FileList.Find( Rec.FFileName, Index );
634 end else begin
635 islog := (Rec.FSize <> 0) and (Rec.FCount <> 0);
636 end;
637 if usePlugIn then
638 ThreadItem := TThreadItem.Create(
639 Board.BoardPlugIn,
640 Board,
641 Board.BoardPlugIn.FileName2ThreadURL( DWORD( Board ), Rec.FFileName ) )
642 else begin
643 if Board.is2ch then begin
644 ThreadItem := TThreadItem.Create(
645 nil,
646 Board,
647 urlHead + ChangeFileExt( Rec.FFileName, '' ) + '/l50',
648 islog,
649 Rec.FFileName
650 );
651 end else begin
652 ThreadItem := TThreadItem.Create(
653 nil,
654 Board,
655 urlHead + ChangeFileExt( Rec.FFileName, '' ) + '&ls=50',
656 islog,
657 Rec.FFileName
658 );
659 end;
660 end;
661
662 //ThreadItem.BeginUpdate;
663 if (datFileCheck) and (islog) then
664 FileList.Delete( Index );
665
666 ThreadItem.No := Rec.FNo;
667 ThreadItem.FileName := Rec.FFileName;
668 ThreadItem.Title := MojuUtils.UnSanitize(Rec.FTitle);
669 ThreadItem.Count := Rec.FCount;
670 ThreadItem.Size := Rec.FSize;
671 ThreadItem.RoundDate := Rec.FRoundDate;
672 ThreadItem.LastModified := Rec.FLastModified;
673 ThreadItem.Kokomade := Rec.FKokomade;
674 ThreadItem.NewReceive := Rec.FNewReceive;
675 ThreadItem.UnRead := Rec.FUnRead;
676 ThreadItem.ScrollTop := Rec.FScrollTop;
677 ThreadItem.AllResCount := Rec.FAllResCount;
678 ThreadItem.NewResCount := Rec.FNewResCount;
679 ThreadItem.AgeSage := Rec.FAgeSage;
680 ThreadItem.ParentBoard := Board;
681 {* 縺頑ー励↓蜈・繧雁、ァ驥冗函謌舌さ繝シ繝 *}
682 {*
683 FavoThreadItem := TFavoriteThreadItem.Create( ThreadItem.URL, ThreadItem.Title, ThreadItem );
684 Node := FavoriteDM.TreeView.Items.AddChildObject( FavoriteDM.TreeView.Items.Item[0], ThreadItem.Title, FavoThreadItem);
685 *}
686
687 //ThreadItem.EndUpdate;
688 Board.Add(ThreadItem);
689
690 if (ThreadItem.UnRead) and (ThreadItem.IsLogFile) then
691 Inc(UnRead);
692 end;
693 end;
694
695 if UnRead <> Board.UnRead then
696 Board.UnRead := UnRead;
697
698 if (datFileCheck) then begin
699 //繧、繝ウ繝?ャ繧ッ繧ケ縺ォ辟。縺九▲縺溘Ο繧ー繧定ソス蜉??郁?繧後う繝ウ繝?ャ繧ッ繧ケ蟇セ蠢懶シ?/span>
700 AddOutofIndexDat(Board, FileList);
701 end;
702 Board.EndUpdate;
703
704 //蜑榊屓逡ー蟶ク邨ゆコ?凾繝√ぉ繝?け
705 RestoreThreadData( Board );
706 finally
707 sl.Free;
708 if (datFileCheck) then begin
709 FileList.Free;
710 end;
711 Board.Sorted := False;
712 end;
713 Board.IsThreadDatRead := True;
714 {$IFDEF DEBUG}
715 rt := GetTickCount - st;
716 Writeln('Read Done.' + Board.Title + ':' + IntToStr(rt) + ' ms');
717 {$ENDIF}
718 end;
719 {!
720 \brief 繧、繝ウ繝?ャ繧ッ繧ケ縺ォ縺ェ縺?at?医?縺舌ldat?峨?霑ス蜉?
721 \param Board 霑ス蜉?縺吶k譚ソ
722 \param DatList dat繝輔ぃ繧、繝ォ蜷?/span>
723 }
724 procedure TGikoSys.AddOutofIndexDat(Board: TBoard; DatList: TStringList; AllCreate: Boolean = True);
725 var
726 i : Integer;
727 Boardpath,FileName : String;
728 ResRec: TResRec;
729 ThreadItem: TThreadItem;
730 create: Boolean;
731 begin
732 create := False;
733 Boardpath := ExtractFilePath(Board.GetFolderIndexFileName);
734 //繧、繝ウ繝?ャ繧ッ繧ケ縺ォ辟。縺九▲縺溘Ο繧ー繧定ソス蜉??郁?繧後う繝ウ繝?ャ繧ッ繧ケ蟇セ蠢懶シ?/span>
735 for i := 0 to DatList.Count - 1 do begin
736 FileName := Boardpath + DatList[i];
737 ThreadItem := nil;
738 if (not AllCreate) then begin
739 create := False;
740 ThreadItem := Board.FindThreadFromFileName(DatList[i]);
741 if (ThreadItem = nil) then begin
742 create := True;
743 end else begin
744 if Board.IsBoardPlugInAvailable then begin
745 THTMLCreate.DivideStrLine(Board.BoardPlugIn.GetDat( DWORD( ThreadItem ), 1 ), @ResRec);
746 end else begin
747 THTMLCreate.DivideStrLine(ReadThreadFile(FileName, 1), @ResRec);
748 end;
749 end;
750 end;
751 if (ThreadItem = nil) then begin
752 if Board.IsBoardPlugInAvailable then begin
753 ThreadItem := TThreadItem.Create(
754 Board.BoardPlugIn,
755 Board,
756 Board.BoardPlugIn.FileName2ThreadURL( DWORD( Board ), DatList[i] ) );
757 THTMLCreate.DivideStrLine(Board.BoardPlugIn.GetDat( DWORD( ThreadItem ), 1 ), @ResRec);
758 end else begin
759 ThreadItem := TThreadItem.Create(
760 nil,
761 Board,
762 Get2chBoard2ThreadURL( Board, ChangeFileExt( DatList[i], '' ) ) );
763 THTMLCreate.DivideStrLine(ReadThreadFile(FileName, 1), @ResRec);
764 end;
765 end;
766
767
768 ThreadItem.BeginUpdate;
769 ThreadItem.FileName := DatList[i];
770 //ThreadItem.FilePath := FileName;
771 ThreadItem.No := Board.Count + 1;
772 ThreadItem.Title := ResRec.FTitle;
773 ThreadItem.Count := GetFileLineCount(FileName);
774 ThreadItem.AllResCount := ThreadItem.Count;
775 ThreadItem.NewResCount := ThreadItem.Count;
776 ThreadItem.Size := GetFileSize(FileName) - ThreadItem.Count;//1byte縺壹l繧九→縺阪′縺ゅk縺代←縺昴l縺ッ縺ゅ″繧峨a繧?/span>
777 ThreadItem.RoundDate := FileDateToDateTime( FileAge( FileName ) );
778 ThreadItem.LastModified := ThreadItem.RoundDate;
779 ThreadItem.Kokomade := -1;
780 ThreadItem.NewReceive := 0;
781 ThreadItem.ParentBoard := Board;
782 ThreadItem.IsLogFile := True;
783 ThreadItem.Round := False;
784 ThreadItem.UnRead := False;
785 ThreadItem.ScrollTop := 0;
786 ThreadItem.AgeSage := gasNone;
787 ThreadItem.EndUpdate;
788 if (AllCreate) or (create) then begin
789 Board.Add(ThreadItem);
790 end;
791 end;
792 end;
793 {!
794 \brief 繧ケ繝ャ繝?ラ繧、繝ウ繝?ャ繧ッ繧ケ繝輔ぃ繧、繝ォ(Folder.idx)菴懈?
795 \param Board Folder.idx 繧剃ス懈?縺吶k譚ソ
796 }
797 procedure TGikoSys.CreateThreadDat(Board: TBoard);
798 var
799 i: integer;
800 s: string;
801 SubjectList: TStringList;
802 sl: TStringList;
803 Rec: TSubjectRec;
804 FileName: string;
805 cnt: Integer;
806 begin
807 if not FileExists(Board.GetSubjectFileName) then Exit;
808 FileName := Board.GetFolderIndexFileName;
809
810 SubjectList := TStringList.Create;
811 try
812 SubjectList.LoadFromFile(Board.GetSubjectFileName);
813 sl := TStringList.Create;
814 try
815 cnt := 1;
816 sl.BeginUpdate;
817 sl.Add(FOLDER_INDEX_VERSION);
818 for i := 0 to SubjectList.Count - 1 do begin
819 Rec := DivideSubject(SubjectList[i]);
820
821 if (Trim(Rec.FFileName) = '') or (Trim(Rec.FTitle) = '') then
822 Continue;
823
824 {s := Format('%x', [cnt]) + #1 //逡ェ蜿キ
825 + Rec.FFileName + #1 //繝輔ぃ繧、繝ォ蜷?/span>
826 + Rec.FTitle + #1 //繧ソ繧、繝医Ν
827 + Format('%x', [Rec.FCount]) + #1 //繧ォ繧ヲ繝ウ繝?/span>
828 + Format('%x', [0]) + #1 //size
829 + Format('%x', [0]) + #1 //RoundDate
830 + Format('%x', [0]) + #1 //LastModified
831 + Format('%x', [0]) + #1 //Kokomade
832 + Format('%x', [0]) + #1 //NewReceive
833 + '0' + #1 //譛ェ菴ソ逕ィ
834 + Format('%x', [0]) + #1 //UnRead
835 + Format('%x', [0]) + #1 //ScrollTop
836 + Format('%x', [Rec.FCount]) + #1 //AllResCount
837 + Format('%x', [0]) + #1 //NewResCount
838 + Format('%x', [0]); //AgeSage
839 }
840 s := Format('%x'#1'%s'#1'%s'#1'%x'#1'%x'#1'%x'#1'%x'#1'%x'#1'%x'#1 +
841 '%s'#1'%x'#1'%x'#1'%x'#1'%x'#1'%x',
842 [cnt, //逡ェ蜿キ
843 Rec.FFileName, //繝輔ぃ繧、繝ォ蜷?/span>
844 MojuUtils.Sanitize(Rec.FTitle), //繧ソ繧、繝医Ν
845 Rec.FCount, //繧ォ繧ヲ繝ウ繝?/span>
846 0, //size
847 0, //RoundDate
848 0, //LastModified
849 0, //Kokomade
850 0, //NewReceive
851 '0', //譛ェ菴ソ逕ィ
852 0, //UnRead
853 0, //ScrollTop
854 Rec.FCount, //AllResCount
855 0, //NewResCount
856 0] //AgeSage
857 );
858
859 sl.Add(s);
860 inc(cnt);
861 end;
862 sl.EndUpdate;
863 sl.SaveToFile(FileName);
864 finally
865 sl.Free;
866 end;
867 finally
868 SubjectList.Free;
869 end;
870 end;
871
872 {!
873 \brief 繧ケ繝ャ繝?ラ繧、繝ウ繝?ャ繧ッ繧ケ(Thread.dat)譖ク縺崎セシ縺ソ
874 \param Thread.dat 繧剃ス懈?縺吶k譚ソ
875 }
876 procedure TGikoSys.WriteThreadDat(Board: TBoard);
877 //const
878 // Values: array[Boolean] of string = ('0', '1');
879 var
880 i: integer;
881 FileName: string;
882 sl: TStringList;
883 s: string;
884 TmpFileList: TStringList;
885 begin
886 if not Board.IsThreadDatRead then
887 Exit;
888 FileName := Board.GetFolderIndexFileName;
889 ForceDirectoriesEx( ExtractFilePath( FileName ) );
890
891 sl := TStringList.Create;
892 TmpFileList := TStringList.Create;
893 TmpFileList.Sorted := true;
894 try
895 TmpFileList.BeginUpdate;
896 GetFileList(ExtractFileDir(Board.GetFolderIndexFileName), '*.tmp', TmpFileList, false);
897 TmpFileList.EndUpdate;
898 sl.BeginUpdate;
899 sl.Add(FOLDER_INDEX_VERSION);
900
901 // 繧ケ繝ャ逡ェ蜿キ菫晏ュ倥?縺溘a繧ス繝シ繝?/span>
902 Sort.SetSortNoFlag(true);
903 Sort.SetSortOrder(true);
904 Sort.SetSortIndex(0);
905 //Sort.SortNonAcquiredCountFlag := GikoSys.Setting.NonAcquiredCount;
906 Board.CustomSort(ThreadItemSortProc);
907
908 for i := 0 to Board.Count - 1 do begin
909 Board.Items[i].No := i + 1;
910 s := Format('%x'#1'%s'#1'%s'#1'%x'#1'%x'#1'%x'#1'%x'#1'%x'#1'%x'#1 +
911 '%s'#1'%x'#1'%x'#1'%x'#1'%x'#1'%x',
912 [Board.Items[i].No, //逡ェ蜿キ
913 Board.Items[i].FileName, //繝輔ぃ繧、繝ォ蜷?/span>
914 MojuUtils.Sanitize(Board.Items[i].Title), //繧ソ繧、繝医Ν
915 Board.Items[i].Count, //繧ォ繧ヲ繝ウ繝?/span>
916 Board.Items[i].Size, //size
917 DateTimeToInt(Board.Items[i].RoundDate), //RoundDate
918 DateTimeToInt(Board.Items[i].LastModified), //LastModified
919 Board.Items[i].Kokomade, //Kokomade
920 Board.Items[i].NewReceive, //NewReceive
921 '0', //譛ェ菴ソ逕ィ
922 BoolToInt(Board.Items[i].UnRead), //UnRead
923 Board.Items[i].ScrollTop, //ScrollTop
924 Board.Items[i].AllResCount, //AllResCount
925 Board.Items[i].NewResCount, //NewResCount
926 Ord(Board.Items[i].AgeSage)] //AgeSage
927 );
928
929 sl.Add(s);
930 end;
931 sl.EndUpdate;
932 sl.SaveToFile(FileName);
933
934 for i := 0 to TmpFileList.Count - 1 do begin
935 DeleteFile(ExtractFilePath(Board.GetFolderIndexFileName) + TmpFileList[i]);
936 end;
937
938 finally
939 TmpFileList.Free;
940 sl.Free;
941 end;
942 end;
943
944 {!
945 \brief Folder.idx 繧 1 陦瑚ァ」驥?/span>
946 \param Line Folder.idx 繧呈ァ区?縺吶k 1 陦?/span>
947 \return 繧ケ繝ャ繝?ラ諠??ア
948 }
949 function TGikoSys.ParseIndexLine(Line: string): TIndexRec;
950 begin
951 Result.FNo := StrToIntDef('$' + MojuUtils.RemoveToken(Line, #1), 0);
952 Result.FFileName := MojuUtils.RemoveToken(Line, #1);
953 Result.FTitle := MojuUtils.UnSanitize(MojuUtils.RemoveToken(Line, #1));
954 Result.FCount := StrToIntDef('$' + MojuUtils.RemoveToken(Line, #1), 0);
955 Result.FSize := StrToIntDef('$' + MojuUtils.RemoveToken(Line, #1), 0);
956 Result.FRoundDate := IntToDateTime(StrToIntDef('$' + MojuUtils.RemoveToken(Line, #1), ZERO_DATE));
957 Result.FLastModified := IntToDateTime(StrToIntDef('$' + MojuUtils.RemoveToken(Line, #1), ZERO_DATE));
958 Result.FKokomade := StrToIntDef('$' + MojuUtils.RemoveToken(Line, #1), -1);
959 Result.FNewReceive := StrToIntDef('$' + MojuUtils.RemoveToken(Line, #1), 0);
960 MojuUtils.RemoveToken(Line, #1);//9: ; //譛ェ菴ソ逕ィ
961 Result.FUnRead := IntToBool(StrToIntDef('$' + MojuUtils.RemoveToken(Line, #1), 0));
962 Result.FScrollTop := StrToIntDef('$' + MojuUtils.RemoveToken(Line, #1), 0);
963 Result.FAllResCount := StrToIntDef('$' + MojuUtils.RemoveToken(Line, #1), 0);
964 Result.FNewResCount := StrToIntDef('$' + MojuUtils.RemoveToken(Line, #1), 0);
965 Result.FAgeSage := TGikoAgeSage(StrToIntDef('$' + MojuUtils.RemoveToken(Line, #1), 0));
966
967 end;
968
969 {!
970 \brief 謖?ョ壹ヵ繧ゥ繝ォ繝?蜀??謖?ョ壹ヵ繧。繧、繝ォ荳?隕ァ繧貞叙蠕励☆繧?/span>
971 \param Path 襍キ轤ケ縺ィ縺ェ繧九ヵ繧ゥ繝ォ繝?繝代せ
972 \param Mask 繝輔ぃ繧、繝ォ蜷阪?繝槭せ繧ッ
973 \param List OUT:蜿門セ励&繧後◆繝輔ぃ繧、繝ォ蜷堺ク?隕ァ縺瑚ソ斐k
974 \param SubDir 荳ュ縺ョ繝輔か繝ォ繝?縺セ縺ァ蜀榊クー逧?↓繝ェ繧ケ繝医☆繧句?エ蜷医? True
975 \param IsPathAdd 繝代せ莉倥″縺ァ繝ェ繧ケ繝医い繝??縺吶k蝣エ蜷医? True
976
977 Mask 繧 '*.txt' 縺ョ繧医≧縺ォ謖?ョ壹☆繧九%縺ィ縺ァ縲?/span>
978 迚ケ螳壹?繝輔ぃ繧、繝ォ蜷阪d迚ケ螳壹?諡。蠑オ蟄舌↓邨槭▲縺溘Μ繧ケ繝医い繝??縺悟庄閭ス縺ァ縺吶??/span>
979
980 \par 萓?
981 \code
982 GetFileList('c:\', '*.txt', list, True, True);
983 \endcode
984 }
985 procedure TGikoSys.GetFileList(Path: string; Mask: string; var List: TStringList; SubDir: Boolean; IsPathAdd: Boolean);
986 var
987 rc: Integer;
988 SearchRec : TSearchRec;
989 s: string;
990 begin
991 Path := IncludeTrailingPathDelimiter(Path);
992 rc := FindFirst(Path + '*.*', faAnyfile, SearchRec);
993 try
994 while rc = 0 do begin
995 if (SearchRec.Name <> '..') and (SearchRec.Name <> '.') then begin
996 s := Path + SearchRec.Name;
997
998 if (SearchRec.Attr and faDirectory = 0) and (MatchesMask(s, Mask)) then
999 if IsPathAdd then
1000 List.Add(s)
1001 else
1002 List.Add(SearchRec.Name);
1003 if SubDir and (SearchRec.Attr and faDirectory > 0) then
1004 GetFileList(s, Mask, List, True, IsPathAdd);
1005 end;
1006 rc := FindNext(SearchRec);
1007 end;
1008 finally
1009 SysUtils.FindClose(SearchRec);
1010 end;
1011 List.Sort;
1012 end;
1013
1014 {!
1015 \breif 謖?ョ壹ヵ繧ゥ繝ォ繝?蜀??謖?ョ壹ヵ繧。繧、繝ォ荳?隕ァ繧貞叙蠕励☆繧九??/span>
1016 繧オ繝悶ヵ繧ゥ繝ォ繝?縺ッ讀懃エ「縺励↑縺?/span>
1017 \param Path 襍キ轤ケ縺ィ縺ェ繧九ヵ繧ゥ繝ォ繝?繝代せ
1018 \param Mask 繝輔ぃ繧、繝ォ蜷阪?繝槭せ繧ッ
1019 \param List OUT:蜿門セ励&繧後◆繝輔ぃ繧、繝ォ蜷堺ク?隕ァ縺瑚ソ斐k
1020 \param IsPathAdd 繝代せ莉倥″縺ァ繝ェ繧ケ繝医い繝??縺吶k蝣エ蜷医? True
1021 \note 蜀崎オキ謖?ョ壼庄閭ス縺ェ GetFileList() 縺後≠繧九?縺ァ縺薙?髢「謨ー縺ッ荳崎ヲ?
1022 \par 萓?/span>
1023 \code
1024 GetFileList('c:\', '*.txt', list, True);
1025 \endcode
1026 }
1027 procedure TGikoSys.GetFileList(Path: string; Mask: string; var List: TStringList; IsPathAdd: Boolean);
1028 var
1029 rc: Integer;
1030 SearchRec : TSearchRec;
1031 begin
1032 Path := IncludeTrailingPathDelimiter(Path);
1033 rc := FindFirst(Path + Mask, faAnyfile, SearchRec);
1034 try
1035 while rc = 0 do begin
1036 if (SearchRec.Name <> '..') and (SearchRec.Name <> '.') then begin
1037 if (SearchRec.Attr and faDirectory = 0) then begin
1038 if IsPathAdd then begin
1039 List.Add(Path + SearchRec.Name)
1040 end else begin
1041 List.Add(SearchRec.Name);
1042 end;
1043 end;
1044 end;
1045 rc := FindNext(SearchRec);
1046 end;
1047 finally
1048 SysUtils.FindClose(SearchRec);
1049 end;
1050 List.Sort;
1051 end;
1052
1053 {!
1054 \brief 謖?ョ壹ヵ繧ゥ繝ォ繝?蜀??繝?ぅ繝ャ繧ッ繝医Μ荳?隕ァ繧貞叙蠕励☆繧?/span>
1055 \param Path 襍キ轤ケ縺ィ縺ェ繧九ヵ繧ゥ繝ォ繝?繝代せ
1056 \param Mask 繝輔か繝ォ繝?蜷阪?繝槭せ繧ッ
1057 \param List OUT:蜿門セ励&繧後◆繝輔か繝ォ繝?蜷堺ク?隕ァ縺瑚ソ斐k
1058 \param SubDir 荳ュ縺ョ繝輔か繝ォ繝?縺セ縺ァ蜀榊クー逧?↓繝ェ繧ケ繝医☆繧句?エ蜷医? True
1059
1060 Mask 繧 '*.txt' 縺ョ繧医≧縺ォ謖?ョ壹☆繧九%縺ィ縺ァ縲?/span>
1061 迚ケ螳壹?繝輔ぃ繧、繝ォ蜷阪d迚ケ螳壹?諡。蠑オ蟄舌↓邨槭▲縺溘Μ繧ケ繝医い繝??縺悟庄閭ス縺ァ縺吶??/span>
1062
1063 \par 萓?
1064 \code
1065 GetDirectoryList('c:\', '*.txt', list, True);
1066 \endcode
1067 }
1068 procedure TGikoSys.GetDirectoryList(Path: string; Mask: string; List: TStringList; SubDir: Boolean);
1069 var
1070 rc: Integer;
1071 SearchRec : TSearchRec;
1072 s: string;
1073 begin
1074 Path := IncludeTrailingPathDelimiter(Path);
1075 rc := FindFirst(Path + '*.*', faDirectory, SearchRec);
1076 try
1077 while rc = 0 do begin
1078 if (SearchRec.Name <> '..') and (SearchRec.Name <> '.') then begin
1079 s := Path + SearchRec.Name;
1080 //if (SearchRec.Attr and faDirectory > 0) then
1081 // s := IncludeTrailingPathDelimiter(s)
1082
1083 if (SearchRec.Attr and faDirectory > 0) and (MatchesMask(s, Mask)) then
1084 List.Add( IncludeTrailingPathDelimiter( s ) );
1085 if SubDir and (SearchRec.Attr and faDirectory > 0) then
1086 GetDirectoryList(s, Mask, List, True);
1087 end;
1088 rc := FindNext(SearchRec);
1089 end;
1090 finally
1091 SysUtils.FindClose(SearchRec);
1092 end;
1093 end;
1094
1095
1096 {!
1097 \brief Subject.txt 荳?陦後r隗」驥?/span>
1098 \param Line Subject.txt 繧呈ァ区?縺吶k 1 陦?/span>
1099 \return 繧ケ繝ャ繝?ラ諠??ア
1100 }
1101 function TGikoSys.DivideSubject(Line: string): TSubjectRec;
1102 var
1103 i: integer;
1104 ws: WideString;
1105 Delim: string;
1106 LeftK: string;
1107 RightK: string;
1108 begin
1109 Result.FCount := 0;
1110
1111 if AnsiPos('<>', Line) = 0 then
1112 Delim := ','
1113 else
1114 Delim := '<>';
1115 Result.FFileName := MojuUtils.RemoveToken(Line, Delim);
1116 Result.FTitle := Trim(MojuUtils.RemoveToken(Line, Delim));
1117
1118 ws := Result.FTitle;
1119 if Copy(ws, Length(ws), 1) = ')' then begin
1120 LeftK := '(';
1121 RightK := ')';
1122 end else if Copy(ws, Length(ws)-1, 2) = '??#39; then begin
1123 LeftK := '??#39;;
1124 RightK := '??#39;;
1125 end else if Copy(ws, Length(ws), 1) = '>' then begin
1126 LeftK := '<';
1127 RightK := '>';
1128 end;
1129 for i := Length(ws) - 1 downto 1 do begin
1130 if Copy(ws, i, Length(LeftK)) = LeftK then begin
1131 Result.FTitle := TrimRight(Copy(ws, 1, i - 1));
1132 ws := Copy(ws, i + Length(LeftK), Length(ws) - i - Length(RightK));
1133 if IsNumeric(ws) then
1134 Result.FCount := StrToInt(ws);
1135 //Delete(Result.FTitle, i, Length(LeftK) + Length(ws) + Length(RightK));
1136 break;
1137 end;
1138 end;
1139 end;
1140
1141 {!
1142 \brief URL縺九iBBSID繧貞叙蠕?/span>
1143 \param url BBSID 繧貞叙蠕励☆繧 URL
1144 \return BBSID
1145 }
1146 function TGikoSys.UrlToID(url: string): string;
1147 var
1148 i: integer;
1149 begin
1150 Result := '';
1151 url := Trim(url);
1152
1153 if url = '' then Exit;
1154 try
1155 url := Copy(url, 0, Length(url) - 1);
1156 for i := Length(url) downto 0 do begin
1157 if url[i] = '/' then begin
1158 Result := Copy(url, i + 1, Length(url));
1159 Break;
1160 end;
1161 end;
1162 except
1163 Result := '';
1164 end;
1165 end;
1166
1167 {!
1168 \brief URL縺九i譛?蠕後?隕∫エ?繧貞炎髯、
1169 \param url 隗」驥医☆繧 URL
1170 \return 蛻?j蜿悶i繧後◆蠕後? URL
1171
1172 URL 縺九i BBSID莉・螟悶?驛ィ蛻?r蜿門セ励☆繧九?縺ォ菴ソ逕ィ縺励∪縺吶??/span>
1173 }
1174 function TGikoSys.UrlToServer(url: string): string;
1175 var
1176 i: integer;
1177 wsURL: WideString;
1178 begin
1179 Result := '';
1180 wsURL := url;
1181 wsURL := Trim(wsURL);
1182
1183 if wsURL = '' then exit;
1184
1185 if Copy(wsURL, Length(wsURL), 1) = '/' then
1186 wsURL := Copy(wsURL, 0, Length(wsURL) - 1);
1187
1188 for i := Length(wsURL) downto 0 do begin
1189 if wsURL[i] = '/' then begin
1190 Result := Copy(wsURL, 0, i);
1191 break;
1192 end;
1193 end;
1194 end;
1195
1196 {!
1197 \brief 繝?ぅ繝ャ繧ッ繝医Μ縺悟ュ伜惠縺吶k縺九メ繧ァ繝?け
1198 \param Name 蟄伜惠繧堤「コ隱阪☆繧九ヵ繧ゥ繝ォ繝?繝代せ
1199 \return 繝輔か繝ォ繝?縺悟ュ伜惠縺吶k縺ェ繧 True
1200 }
1201 function TGikoSys.DirectoryExistsEx(const Name: string): Boolean;
1202 var
1203 Code: Cardinal;
1204 begin
1205 Code := GetFileAttributes(PChar(Name));
1206 Result := (Code <> Cardinal(-1)) and (FILE_ATTRIBUTE_DIRECTORY and Code <> 0);
1207 end;
1208
1209 {!
1210 \brief 繝?ぅ繝ャ繧ッ繝医Μ菴懈??郁、?焚髫主ア、蟇セ蠢懶シ?/span>
1211 \param Dir 菴懈?縺吶k繝代せ
1212 \return 菴懈?縺ォ謌仙粥縺励◆蝣エ蜷医? True
1213 }
1214 function TGikoSys.ForceDirectoriesEx(Dir: string): Boolean;
1215 begin
1216 Result := True;
1217 if Length(Dir) = 0 then
1218 raise Exception.Create('繝輔か繝ォ繝?縺御ス懈?蜃コ譚・縺セ縺帙s');
1219 Dir := ExcludeTrailingPathDelimiter(Dir);
1220 if (Length(Dir) < 3) or DirectoryExistsEx(Dir)
1221 or (ExtractFilePath(Dir) = Dir) then Exit; // avoid 'xyz:\' problem.
1222 Result := ForceDirectoriesEx(ExtractFilePath(Dir)) and CreateDir(Dir);
1223 end;
1224
1225 {!
1226 \brief 譁?ュ怜?縺九i繝医?繧ッ繝ウ縺ョ蛻?j蜃コ縺暦シ亥?譛溷?逅?シ?/span>
1227 FDelphi縺九i縺ョ繝代け繝ェ
1228 \param s 蜈?↓縺ェ繧九く繝」繝ゥ繧ッ繧ソ
1229 \param sep 蛹コ蛻?j縺ォ縺ェ繧区枚蟄怜?
1230 \param Rec OUT:譁?ュ怜?襍ー譟サ諠??ア縺瑚ソ斐k
1231 \return 蛻?j蜃コ縺励◆繝医?繧ッ繝ウ
1232 \todo Split, RemoveToken, GetTokenIndex, NthField 陦後″
1233 }
1234 function TGikoSys.StrTokFirst(const s:string; const sep: TStrTokSeparator; var Rec: TStrTokRec): string;
1235 begin
1236 Rec.Str := s;
1237 Rec.Pos := 1;
1238 Result := StrTokNext(sep, Rec);
1239 end;
1240
1241 {!
1242 \brief 譁?ュ怜?縺九i繝医?繧ッ繝ウ縺ョ蛻?j蜃コ縺?/span>
1243 FDelphi縺九i縺ョ繝代け繝ェ
1244 \param sep 蛹コ蛻?j縺ォ縺ェ繧九く繝」繝ゥ繧ッ繧ソ
1245 \param Rec IN/OUT:StrTokFirst縺ァ菴懈?縺輔l縺滓枚蟄怜?襍ー譟サ諠??ア
1246 \return 蛻?j蜃コ縺励◆繝医?繧ッ繝ウ
1247 \todo Split, RemoveToken, GetTokenIndex, NthField 陦後″
1248 }
1249 function TGikoSys.StrTokNext(const sep: TStrTokSeparator; var Rec: TStrTokRec): string;
1250 var
1251 Len, I: Integer;
1252 begin
1253 with Rec do begin
1254 Len := Length(Str);
1255 Result := '';
1256 if Len >= Pos then begin
1257 while (Pos <= Len) and (Str[Pos] in sep) do begin
1258 Inc(Pos);
1259 end;
1260 I := Pos;
1261 while (Pos<= Len) and not (Str[Pos] in sep) do begin
1262 if IsDBCSLeadByte(Byte(Str[Pos])) then begin
1263 Inc(Pos);
1264 end;
1265 Inc(Pos);
1266 end;
1267 Result := Copy(Str, I, Pos - I);
1268 while (Pos <= Len) and (Str[Pos] in sep) do begin// 縺薙l縺ッ縺雁・ス縺ソ
1269 Inc(Pos);
1270 end;
1271 end;
1272 end;
1273 end;
1274
1275 {!
1276 \brief 繝輔ぃ繧、繝ォ繧オ繧、繧コ蜿門セ?/span>
1277 \param FileName 繝輔ぃ繧、繝ォ繧オ繧、繧コ繧貞叙蠕励☆繧九ヵ繧。繧、繝ォ繝代せ
1278 \return 繝輔ぃ繧、繝ォ繧オ繧、繧コ(bytes)
1279 }
1280 function TGikoSys.GetFileSize(FileName : string): longint;
1281 var
1282 F : File;
1283 begin
1284 try
1285 if not FileExists(FileName) then begin
1286 Result := 0;
1287 Exit;
1288 end;
1289 Assign(F, FileName);
1290 Reset(F, 1);
1291 Result := FileSize(F);
1292 CloseFile(F);
1293 except
1294 Result := 0;
1295 end;
1296 end;
1297
1298 {!
1299 \brief 繝?く繧ケ繝医ヵ繧。繧、繝ォ縺ョ陦梧焚繧貞叙蠕?/span>
1300 \param FileName 陦梧焚繧貞叙蠕励☆繧九ヵ繧。繧、繝ォ繝代せ
1301 \return 陦梧焚
1302 \todo 繝。繝「繝ェ繝槭ャ繝励ラ繝輔ぃ繧、繝ォ陦後″
1303 }
1304 function TGikoSys.GetFileLineCount(FileName : string): longint;
1305 var
1306 sl: TStringList;
1307 begin
1308 sl := TStringList.Create;
1309 try
1310 try
1311 sl.LoadFromFile(FileName);
1312 Result := sl.Count;
1313 except
1314 Result := 0;
1315 end;
1316 finally
1317 sl.Free;
1318 end;
1319
1320 end;
1321
1322 {!
1323 \brief 繝輔ぃ繧、繝ォ縺九i謖?ョ夊。後r蜿門セ?/span>
1324 \param FileName 繝輔ぃ繧、繝ォ縺ョ繝代せ
1325 \param Line 謖?ョ夊。?/span>
1326 \return 謖?ョ壹&繧後◆ 1 陦?/span>
1327 \todo 繝。繝「繝ェ繝槭ャ繝励ラ繝輔ぃ繧、繝ォ陦後″
1328 }
1329 function TGikoSys.ReadThreadFile(FileName: string; Line: Integer): string;
1330 var
1331 fileTmp : TStringList;
1332 begin
1333 Result := '';
1334 if FileExists(FileName) then begin
1335 fileTmp := TStringList.Create;
1336 try
1337 try
1338 fileTmp.LoadFromFile( FileName );
1339 if ( Line >= 1 ) and ( Line < fileTmp.Count + 1 ) then begin
1340 Result := fileTmp.Strings[ Line-1 ];
1341 end;
1342 except
1343 //on EFOpenError do Result := '';
1344 end;
1345 finally
1346 fileTmp.Free;
1347 end;
1348 end;
1349 end;
1350
1351 {!
1352 \brief 繧キ繧ケ繝?Β繝。繝九Η繝シ繝輔か繝ウ繝医?螻樊?ァ繧貞叙蠕?/span>
1353 \param Font OUT:蜿門セ励@縺溘ヵ繧ゥ繝ウ繝亥ア樊?ァ縺瑚ソ斐k
1354 }
1355 procedure TGikoSys.MenuFont(Font: TFont);
1356 var
1357 lf: LOGFONT;
1358 nm: NONCLIENTMETRICS;
1359 begin
1360 nm.cbSize := sizeof(NONCLIENTMETRICS);
1361 SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, @nm, 0);
1362 lf := nm.lfMenuFont;
1363 Font.Name := lf.lfFaceName;
1364 Font.Height := lf.lfHeight;
1365 Font.Style := [];
1366 if lf.lfWeight >= 700 then
1367 Font.Style := Font.Style + [fsBold];
1368 if lf.lfItalic = 1 then
1369 Font.Style := Font.Style + [fsItalic];
1370 end;
1371
1372 {!
1373 \brief 蜈磯?ュ縺ョ繝医?繧ッ繝ウ繧貞?繧雁?縺?/span>
1374 \param s IN/OUT:蜈?↓縺ェ繧区枚蟄怜?縲∝?繧雁?縺励◆蠕後?谿九j縺ョ譁?ュ怜?
1375 \param delimiter 蛹コ蛻?j縺ォ縺ェ繧区枚蟄怜?
1376 \return 蛻?j蜃コ縺励◆譁?ュ怜?
1377
1378 縺ゥ縺薙°縺ョ繧オ繧、繝医°繧峨?繝代け繝ェ
1379 }
1380 {function TGikoSys.RemoveToken(var s: string;const delimiter: string): string;
1381 var
1382 p: Integer;
1383 begin
1384 p := AnsiPos(delimiter, s);
1385 if p = 0 then
1386 Result := s
1387 else
1388 Result := Copy(s, 1, p - 1);
1389 Delete(s, 1, Length(Result) + Length(delimiter));
1390 end;
1391 }
1392
1393 {!
1394 \brief n 蛟狗岼縺ョ繝医?繧ッ繝ウ繧貞?繧雁?縺?/span>
1395 \param s 蜈?↓縺ェ繧区枚蟄怜?
1396 \param index 0 縺九i蟋九∪繧九う繝ウ繝?ャ繧ッ繧ケ(n 蛟狗岼縺ョ n)
1397 \return 蛻?j蜃コ縺励◆繝医?繧ッ繝ウ
1398
1399 縺ゥ縺薙°縺ョ繧オ繧、繝医°繧峨?繝代け繝ェ
1400 }
1401 function TGikoSys.GetTokenIndex(s: string; delimiter: string; index: Integer): string;
1402 var
1403 i: Integer;
1404 begin
1405 Result := '';
1406 for i := 0 to index do
1407 Result := MojuUtils.RemoveToken(s, delimiter);
1408 end;
1409
1410
1411 //繧、繝ウ繝?ャ繧ッ繧ケ譛ェ譖エ譁ー繝舌ャ繝輔ぃ繧偵ヵ繝ゥ繝?す繝・??/span>
1412 {procedure TGikoSys.FlashExitWrite;
1413 var
1414 i: Integer;
1415 begin
1416 //繧ケ繝ャ繝?ラ繝??繧ソ繝輔ぃ繧、繝ォ繧呈峩譁ー
1417 for i := 0 to FExitWrite.Count - 1 do
1418 WriteThreadDat(FExitWrite[i]);
1419 FExitWrite.Clear;
1420 end;}
1421
1422 {!
1423 \brief 繧ケ繝ャ蜷阪↑縺ゥ繧堤洒縺?錐蜑阪↓螟画鋤縺吶k
1424 \param LongName 蜈?↓縺ェ繧区枚蟄怜?
1425 \param ALength 蜿弱a繧区枚蟄怜?髟キ(bytes)
1426 \return 螟画鋤縺輔l縺滓枚蟄怜?
1427
1428 from HotZonu
1429 }
1430 function TGikoSys.GetShortName(const LongName: string; ALength: integer): string;
1431 const
1432 ERASECHAR : array [1..39] of string =
1433 ('笘?#39;,'笘?#39;,'笆?','笆。','笳?#39;,'笳?#39;,'?ソ','??#39;,'笆イ','笆シ',
1434 '笆ウ','笆ス','笳?#39;,'笳?#39;,'笳?#39;,'縲?#39;,'縲?#39;,'笙ェ','縲?#39;,'縲?#39;,
1435 '窶?#39;,'窶?#39;,'縲?#39;,'縲?#39;,'窶?#39;,'窶?#39;,'??#39;,'??#39;,'竕ェ','竕ォ',
1436 '??#39;,'??#39;,'縲?#39;,'縲?#39;,'縲?#39;,'縲?#39;,'縲?#39;,'窶ヲ', '縲?');
1437 var
1438 Chr : array [0..255] of char;
1439 S : string;
1440 i : integer;
1441 begin
1442 s := Trim(LongName);
1443 if (Length(s) <= ALength) then begin
1444 Result := s;
1445 end else begin
1446 S := s;
1447 for i := Low(ERASECHAR) to High(ERASECHAR) do begin
1448 S := CustomStringReplace(S, ERASECHAR[i], '');
1449 end;
1450 if (Length(S) <= ALength) then begin
1451 Result := S;
1452 end else begin
1453 Windows.LCMapString(
1454 GetUserDefaultLCID(),
1455 LCMAP_HALFWIDTH,
1456 PChar(S),
1457 Length(S) + 1,
1458 chr,
1459 Sizeof(chr)
1460 );
1461 S := Chr;
1462 S := Copy(S,1,ALength);
1463 while true do begin
1464 if (ByteType(S, Length(S)) = mbLeadByte ) then begin
1465 S := Copy(S, 1, Length(S) - 1);
1466 end else begin
1467 Break;
1468 end;
1469 end;
1470 Result := S;
1471 end;
1472 end;
1473 end;
1474
1475 {!
1476 \brief Boolean 繧 Integer 縺ォ螟画鋤
1477 \return False..0, True..1
1478 }
1479 function TGikoSys.BoolToInt(b: Boolean): Integer;
1480 begin
1481 Result := IfThen(b, 1, 0);
1482 end;
1483
1484 {!
1485 \brief Integer 繧 Boolean 縺ォ螟画鋤
1486 \return 1..True, other..False
1487 \todo 0..False, other..True 縺ョ譁ケ縺後>縺??縺ァ縺ッ?
1488 (縺薙?莉墓ァ倥↓萓晏ュ倥@縺ヲ縺?k縺九b縺励l縺ェ縺??縺ァ譛ェ菫ョ豁」)
1489 }
1490 function TGikoSys.IntToBool(i: Integer): Boolean;
1491 begin
1492 Result := i = 1;
1493 end;
1494
1495 {!
1496 \brief gzip縺ァ蝨ァ邵ョ縺輔l縺溘?繧呈綾縺?/span>
1497 \param ResStream 隱ュ縺ソ霎シ繧?繧ケ繝医Μ繝シ繝?
1498 \param ContentEncoding 繧ィ繝ウ繧ウ繝シ繝?ぅ繝ウ繧ー
1499 \return 螻暮幕縺輔l縺滓枚蟄怜?
1500 }
1501 function TGikoSys.GzipDecompress(ResStream: TStream; ContentEncoding: string): string;
1502 const
1503 BUF_SIZE = 4096;
1504 var
1505 GZipStream: TGzipDecompressStream;
1506 TextStream: TStringStream;
1507 buf: array[0..BUF_SIZE - 1] of Byte;
1508 cnt: Integer;
1509 s: string;
1510 i, ln: Integer;
1511 begin
1512 Result := '';
1513 TextStream := TStringStream.Create('');
1514 try
1515 //繝弱?繝医Φ繧ヲ繝ウ繝√え繧」繝ォ繧ケ2003蟇セ遲?x-gzip縺ィ縺九↓縺ェ繧九∩縺溘>)
1516 // if LowerCase(Trim(ContentEncoding)) = 'gzip' then begin
1517 if AnsiPos('gzip', LowerCase(Trim(ContentEncoding))) > 0 then begin
1518 ResStream.Position := 0;
1519 GZipStream := TGzipDecompressStream.Create(TextStream);
1520 try
1521 repeat
1522 FillChar(buf, BUF_SIZE, 0);
1523 cnt := ResStream.Read(buf, BUF_SIZE);
1524 if cnt > 0 then
1525 GZipStream.Write(buf, BUF_SIZE);
1526 until cnt = 0;
1527 finally
1528 GZipStream.Free;
1529 end;
1530 end else begin
1531 ResStream.Position := 0;
1532 repeat
1533 FillChar(buf, BUF_SIZE, 0);
1534 cnt := ResStream.Read(buf, BUF_SIZE);
1535 if cnt > 0 then
1536 TextStream.Write(buf, BUF_SIZE);
1537 until cnt = 0;
1538 end;
1539
1540 //NULL譁?ュ励r"*"縺ォ縺吶k
1541 s := TextStream.DataString;
1542 i := Length(s);
1543 ln := i;
1544 while (i > 0) and (s[i] = #0) do
1545 Dec(i);
1546 Delete(s, i + 1, ln - i);
1547
1548 i := Pos(#0, s);
1549 while i <> 0 do begin
1550 s[i] := '*';
1551 i := Pos(#0, s);
1552 end;
1553
1554 Result := s;
1555 finally
1556 TextStream.Free;
1557 end;
1558 end;
1559
1560 {!
1561 \brief 繧「繧ッ繧キ繝ァ繝ウ縺ォ繧キ繝ァ繝シ繝医き繝?ヨ繧ュ繝シ繧定ィュ螳?/span>
1562 \param ActionList 險ュ螳壹☆繧九い繧ッ繧キ繝ァ繝ウ荳?隕ァ
1563 \param FileName Ini繝輔ぃ繧、繝ォ縺ョ蜷榊燕
1564 }
1565 procedure TGikoSys.LoadKeySetting(ActionList: TActionList; FileName: String);
1566 const
1567 STD_SEC = 'KeySetting';
1568 var
1569 i: Integer;
1570 ini: TMemIniFile;
1571 ActionName: string;
1572 ActionKey: Integer;
1573 SecList: TStringList;
1574 Component: TComponent;
1575 begin
1576 if not FileExists(fileName) then
1577 Exit;
1578 SecList := TStringList.Create;
1579 ini := TMemIniFile.Create(fileName);
1580 try
1581 ini.ReadSection(STD_SEC, SecList);
1582 for i := 0 to SecList.Count - 1 do begin
1583 ActionName := SecList[i];
1584 ActionKey := ini.ReadInteger(STD_SEC, ActionName, -1);
1585 if ActionKey <> -1 then begin
1586 Component := ActionList.Owner.FindComponent(ActionName);
1587 if TObject(Component) is TAction then begin
1588 TAction(Component).ShortCut := ActionKey;
1589 end;
1590 end;
1591 end;
1592 finally
1593 ini.Free;
1594 SecList.Free;
1595 end;
1596 end;
1597
1598 {!
1599 \brief 繧「繧ッ繧キ繝ァ繝ウ縺ォ險ュ螳壹&繧後※縺?k繧キ繝ァ繝シ繝医き繝?ヨ繧ュ繝シ繧偵ヵ繧。繧、繝ォ縺ォ菫晏ュ?/span>
1600 \param ActionList 菫晏ュ倥☆繧九い繧ッ繧キ繝ァ繝ウ荳?隕ァ
1601 \param FileName Ini繝輔ぃ繧、繝ォ蜷?/span>
1602
1603 ActionList 縺ォ險ュ螳壹&繧後※縺?k繧キ繝ァ繝シ繝医き繝?ヨ繧ュ繝シ繧 FileName 縺ォ菫晏ュ倥@縺セ縺吶??/span>
1604 }
1605 procedure TGikoSys.SaveKeySetting(ActionList: TActionList; FileName: String);
1606 const
1607 STD_SEC = 'KeySetting';
1608 var
1609 i: Integer;
1610 ini: TMemIniFile;
1611 begin
1612 ini := TMemIniFile.Create(GetConfigDir + FileName);
1613 try
1614 for i := 0 to ActionList.ActionCount - 1 do begin
1615 if ActionList.Actions[i].Tag = -1 then
1616 Continue;
1617 ini.WriteInteger(STD_SEC, ActionList.Actions[i].Name, TAction(ActionList.Actions[i]).ShortCut);
1618 end;
1619 ini.UpdateFile;
1620 finally
1621 ini.Free;
1622 end;
1623 end;
1624
1625
1626 {!
1627 \brief 繝励Ο繧サ繧ケ縺ョ逕滓?
1628 \param AppPath 襍キ蜍輔☆繧九?繝ュ繧サ繧ケ縺ョ繝輔ぃ繧、繝ォ繝代せ
1629 \param Param AppPath 縺ォ貂。縺吝シ墓焚
1630 }
1631 procedure TGikoSys.CreateProcess(const AppPath: string; const Param: string);
1632 var
1633 PI: TProcessInformation;
1634 SI: TStartupInfo;
1635 Path: string;
1636 begin
1637 Path := '"' + AppPath + '"';
1638 if Param <> '' then
1639 Path := Path + ' ' + Param;
1640
1641 SI.Cb := SizeOf(Si);
1642 SI.lpReserved := nil;
1643 SI.lpDesktop := nil;
1644 SI.lpTitle := nil;
1645 SI.dwFlags := 0;
1646 SI.cbReserved2 := 0;
1647 SI.lpReserved2 := nil;
1648 SI.dwysize := 0;
1649 if Windows.CreateProcess(nil,
1650 PChar(Path),
1651 nil,
1652 nil,
1653 False,
1654 0,
1655 nil,
1656 nil,
1657 SI,
1658 PI) then
1659 begin
1660 CloseHandle(PI.hProcess);
1661 end;
1662
1663 end;
1664
1665 {!
1666 \brief Web 繝悶Λ繧ヲ繧カ繧定オキ蜍?/span>
1667 \param URL Web 繝悶Λ繧ヲ繧カ縺ァ陦ィ遉コ縺吶k URL
1668 \param BrowserType 繝悶Λ繧ヲ繧カ縺ョ繧ソ繧、繝?IE 縺九←縺?°)
1669 }
1670 procedure TGikoSys.OpenBrowser(URL: string; BrowserType: TGikoBrowserType);
1671 var
1672 i, j : Integer;
1673 path, arg : String;
1674 params : TStringList;
1675 begin
1676 case BrowserType of
1677 gbtIE:
1678 HlinkNavigateString(nil, PWideChar(WideString(URL)));
1679 gbtUserApp, gbtAuto:
1680 if (Setting.URLApp) then begin
1681 if (FileExists(Setting.URLAppFile)) then begin
1682 GikoSys.CreateProcess(Setting.URLAppFile, URL)
1683 end else begin
1684 // 襍キ蜍輔ヱ繝ゥ繝。繝シ繧ソ莉倥″蟇セ遲?/span>
1685 path := '';
1686 params := TStringList.Create;
1687 try
1688 params.Delimiter := ' ';
1689 params.DelimitedText := Setting.URLAppFile;
1690 for i := 0 to params.Count - 1 do begin
1691 path := TrimLeft(path + ' ' + params[i]);
1692 if (FileExists(path)) then begin
1693 arg := '';
1694 for j := i + 1 to params.Count - 1 do begin
1695 arg := arg + ' ' + params[j];
1696 end;
1697 break;
1698 end;
1699 end;
1700 if i < params.Count then begin
1701 GikoSys.CreateProcess(path, arg + ' ' + URL);
1702 end else begin
1703 HlinkNavigateString(nil, PWideChar(WideString(URL)));
1704 end;
1705 finally
1706 params.Free;
1707 end;
1708 end;
1709 end else
1710 HlinkNavigateString(nil, PWideChar(WideString(URL)));
1711 end;
1712 end;
1713
1714 {!
1715 \brief 譁?ュ怜ョ滉ス灘盾辣ァ繧偵ョ繧ウ繝シ繝?/span>
1716 \param AStr 繝?さ繝シ繝峨☆繧区枚蟄怜?
1717 \return 繝?さ繝シ繝峨&繧後◆譁?ュ怜?
1718 }
1719 function TGikoSys.HTMLDecode(const AStr: String): String;
1720 var
1721 Sp, Rp, Cp, Tp: PChar;
1722 S: String;
1723 I, Code: Integer;
1724 Num: Boolean;
1725 begin
1726 SetLength(Result, Length(AStr));
1727 Sp := PChar(AStr);
1728 Rp := PChar(Result);
1729 //Cp := Sp;
1730 try
1731 while Sp^ <> #0 do begin
1732 case Sp^ of
1733 '&': begin
1734 //Cp := Sp;
1735 Inc(Sp);
1736 case Sp^ of
1737 'a': if AnsiStrPos(Sp, 'amp;') = Sp then
1738 begin
1739 Inc(Sp, 3);
1740 Rp^ := '&';
1741 end;
1742 'l',
1743 'g': if (AnsiStrPos(Sp, 'lt;') = Sp) or (AnsiStrPos(Sp, 'gt;') = Sp) then
1744 begin
1745 Cp := Sp;
1746 Inc(Sp, 2);
1747 while (Sp^ <> ';') and (Sp^ <> #0) do
1748 Inc(Sp);
1749 if Cp^ = 'l' then
1750 Rp^ := '<'
1751 else
1752 Rp^ := '>';
1753 end;
1754 'q': if AnsiStrPos(Sp, 'quot;') = Sp then
1755 begin
1756 Inc(Sp,4);
1757 Rp^ := '"';
1758 end;
1759 '#': begin
1760 Tp := Sp;
1761 Inc(Tp);
1762 Num := IsNumeric(Copy(Tp, 1, 1));
1763 while (Sp^ <> ';') and (Sp^ <> #0) do begin
1764 if (Num) and (not IsNumeric(Copy(Sp, 1, 1))) then
1765 Break;
1766 Inc(Sp);
1767 end;
1768 SetString(S, Tp, Sp - Tp);
1769 Val(S, I, Code);
1770 Rp^ := Chr((I));
1771 end;
1772 // else
1773 //raise EConvertError.CreateFmt(sInvalidHTMLEncodedChar,
1774 //[Cp^ + Sp^, Cp - PChar(AStr)])
1775 end;
1776 end
1777 else
1778 Rp^ := Sp^;
1779 end;
1780 Inc(Rp);
1781 Inc(Sp);
1782 end;
1783 except
1784 // on E:EConvertError do
1785 // raise EConvertError.CreateFmt(sInvalidHTMLEncodedChar,
1786 // [Cp^ + Sp^, Cp - PChar(AStr)])
1787 end;
1788 SetLength(Result, Rp - PChar(Result));
1789 end;
1790
1791 {!
1792 \brief HTML 縺ョ繧「繝ウ繧ォ繝シ繧ソ繧ー縺九i URL 繧貞叙蠕?/span>
1793 \param s URL 繧貞叙蠕励☆繧 HTML
1794 \return 蜿門セ励@縺 URL
1795 }
1796 function TGikoSys.GetHRefText(s: string): string;
1797 var
1798 Index: Integer;
1799 Index2: Integer;
1800 begin
1801 Result := '';
1802 s := Trim(s);
1803 if s = '' then
1804 Exit;
1805
1806 Index := AnsiPos('href', LowerCase(s));
1807 if Index = 0 then
1808 Exit;
1809 s := Trim(Copy(s, Index + 4, Length(s)));
1810 s := Trim(Copy(s, 2, Length(s)));
1811
1812 //蟋九a縺ョ譁?ュ励′'"'縺ェ繧牙叙繧企勁縺?/span>
1813 //if Copy(s, 1, 1) = '"' then begin
1814 if s[1] = '"' then begin
1815 s := Trim(Copy(s, 2, Length(s)));
1816 end;
1817
1818 Index := AnsiPos('"', s);
1819 if Index <> 0 then begin
1820 //'"'縺セ縺ァURL縺ィ縺吶k
1821 s := Copy(s, 1, Index - 1);
1822 end else begin
1823 //'"'縺檎┌縺代l縺ー繧ケ繝壹?繧ケ縺?quot;>"縺ョ譌ゥ縺?婿縺セ縺ァ繧旦RL縺ィ縺吶k
1824 Index := AnsiPos(' ', s);
1825 Index2 := AnsiPos('>', s);
1826 if Index = 0 then
1827 Index := Index2;
1828 if Index > Index2 then
1829 Index := Index2;
1830 if Index <> 0 then
1831 s := Copy(s, 1, Index - 1)
1832 else
1833 //縺薙l莉・荳翫b縺?衍繧峨s縺ャ
1834 ;
1835 end;
1836 Result := Trim(s);
1837 end;
1838
1839 {!
1840 \brief 繝帙せ繝亥錐縺鯉シ抵ス?ス医°縺ゥ縺?°繝√ぉ繝?け縺吶k
1841 \param Host 繝√ぉ繝?け縺吶k繝帙せ繝亥錐
1842 \return 2縺。繧?s縺ュ繧九?繝帙せ繝亥錐縺ェ繧 True
1843 }
1844 function TGikoSys.Is2chHost(Host: string): Boolean;
1845 const
1846 HOST_NAME: array[0..1] of string = ('2ch.net', 'bbspink.com');
1847 var
1848 i: Integer;
1849 // Len: Integer;
1850 begin
1851 Result := False;
1852 if RightStr( Host, 1 ) = '/' then
1853 Host := Copy( Host, 1, Length( Host ) - 1 );
1854 OutputDebugString(pchar(HOST_NAME[0]));
1855 for i := 0 to Length(HOST_NAME) - 1 do begin
1856 // Len := Length(HOST_NAME[i]);
1857 if (AnsiPos(HOST_NAME[i], Host) > 0) and
1858 (AnsiPos(HOST_NAME[i], Host) = (Length(Host) - Length(HOST_NAME[i]) + 1)) then begin
1859 Result := True;
1860 Exit;
1861 end;
1862 end;
1863 end;
1864
1865 {!
1866 \brief 2縺。繧?s縺ュ繧句ス「蠑上? URL 繧貞?隗」
1867 \param url 2縺。繧?s縺ュ繧句ス「蠑上? URL
1868 \param path test/read.cgi 縺ェ縺ゥ縺ョ荳ュ髢薙ヱ繧ケ(ParseURI 縺九i蠕励k)
1869 \param document index.html 縺ェ縺ゥ縺ョ繝峨く繝・繝。繝ウ繝亥錐(ParseURI 縺九i蠕励k)
1870 \param BBSID OUT:BBSID 縺瑚ソ斐k(ex. giko)
1871 \param BBSKey OUT:繧ケ繝ャ繝?ラ繧ュ繝シ縺瑚ソ斐k(ex. 10000000000)
1872 \return 2縺。繧?s縺ュ繧九? URL 縺ィ縺励※蛻?ァ」縺ァ縺阪◆縺ェ繧 True
1873 }
1874 function TGikoSys.Parse2chURL(const url: string; const path: string; const document: string; var BBSID: string; var BBSKey: string): Boolean;
1875 var
1876 Index: Integer;
1877 s: string;
1878 SList: TStringList;
1879 begin
1880 BBSID := '';
1881 BBSKey := '';
1882 Result := False;
1883
1884 Index := AnsiPos(READ_PATH, path);
1885 if Index <> 0 then begin
1886 s := Copy(path, Index + Length(READ_PATH), Length(path));
1887 end else begin
1888 Index := AnsiPos(HTML_READ_PATH, path);
1889 if Index <> 0 then begin
1890 s := Copy(path, Index + Length(HTML_READ_PATH), Length(path));
1891 end;
1892 end;
1893 if Index <> 0 then begin
1894 if (Length(s) > 0) and (s[1] = '/') then
1895 Delete(s, 1, 1);
1896 BBSID := GetTokenIndex(s, '/', 0);
1897 BBSKey := GetTokenIndex(s, '/', 1);
1898 if BBSKey = '' then
1899 BBSKey := Document;
1900 Result := (BBSID <> '') or (BBSKey <> '');
1901 Exit;
1902 end;
1903 Index := AnsiPos(KAKO_PATH, path);
1904 if Index <> 0 then begin
1905 s := Copy(path, 2, Length(path));
1906 BBSID := GetTokenIndex(s, '/', 0);
1907 if (BBSID = 'log') and (GetTokenIndex(s, '/', 2) = 'kako') then
1908 BBSID := GetTokenIndex(s, '/', 1);
1909 BBSKey := ChangeFileExt(Document, '');
1910 Result := (BBSID <> '') or (BBSKey <> '');
1911 Exit;
1912 end;
1913 Index := AnsiPos('read.cgi?', URL);
1914 if Index <> 0 then begin
1915 SList := TStringList.Create;
1916 try
1917 try
1918 // s := HTMLDecode(Document);
1919 ExtractHTTPFields(['?', '&'], [], PChar(URL), SList, False);
1920 BBSID := SList.Values['bbs'];
1921 BBSKey := SList.Values['key'];
1922 Result := (BBSID <> '') or (BBSKey <> '');
1923 Exit;
1924 except
1925 Exit;
1926 end;
1927 finally
1928 SList.Free;
1929 end;
1930 end;
1931 end;
1932
1933 {!
1934 \brief 2ch 蠖「蠑上? URL 縺九i繝ャ繧ケ逡ェ繧貞叙蠕?/span>
1935 \param URL 2縺。繧?s縺ュ繧句ス「蠑上? URL
1936 \param stRes OUT:髢句ァ九Ξ繧ケ逡ェ縺瑚ソ斐k
1937 \param endRes OUT:邨ゆコ?Ξ繧ケ逡ェ縺瑚ソ斐k
1938
1939 http://2ch.net/荳ュ逡・/32-50 \n
1940 縺ョ蝣エ蜷 stRef = 32, endRes = 50 縺ォ縺ェ繧?/span>
1941 }
1942 procedure TGikoSys.GetPopupResNumber(URL : string; var stRes, endRes : Int64);
1943 const
1944 START_NAME : array[0..1] of String = ('st=', 'start=');
1945 END_NAME : array[0..1] of String = ('to=', 'end=');
1946 RES_NAME : array[0..0] of String = ('res=');
1947 var
1948 buf : String;
1949 convBuf : String;
1950 ps : Int64;
1951 pch : PChar;
1952 bufList : TStringList;
1953 i, j, idx : Integer;
1954 begin
1955 URL := Trim(LowerCase(URL));
1956 for i := 0 to Length(START_NAME) -1 do begin
1957 idx := AnsiPos(START_NAME[i], URL);
1958 if (idx <> 0) then begin
1959 break;
1960 end;
1961 idx := AnsiPos(END_NAME[i], URL);
1962 if (idx <> 0) then begin
1963 break;
1964 end;
1965
1966 end;
1967
1968 if (idx <> 0) then begin
1969 idx := AnsiPos('?', URL);
1970 if (idx = 0) then begin
1971 idx := LastDelimiter('/', URL);
1972 end;
1973 stRes := 0;
1974 endRes := 0;
1975 bufList := TStringList.Create();
1976 try
1977 bufList.Delimiter := '&';
1978 bufList.DelimitedText := Copy(URL, idx + 1, Length(URL));
1979 for i := 0 to bufList.Count - 1 do begin
1980 convBuf := '';
1981 // 髢句ァ九Ξ繧ケ逡ェ縺ョ讀懃エ「
1982 if (stRes = 0) then begin
1983 for j := 0 to Length(START_NAME) - 1 do begin
1984 idx := AnsiPos(START_NAME[j], bufList[i]);
1985 if (idx = 1) then begin
1986 convBuf := Copy(bufList[i], idx + Length(START_NAME[j]), Length(bufList[i]));
1987 stRes := StrToInt64Def( convBuf, 0 );
1988 break;
1989 end;
1990 end;
1991 end;
1992 // 邨ゆコ?Ξ繧ケ逡ェ縺ョ讀懃エ「
1993 if (convBuf = '') and (endRes = 0) then begin
1994 for j := 0 to Length(END_NAME) - 1 do begin
1995 idx := AnsiPos(END_NAME[j], bufList[i]);
1996 if (idx = 1) then begin
1997 convBuf := Copy(bufList[i], idx + Length(END_NAME[j]), Length(bufList[i]));
1998 endRes := StrToInt64Def( convBuf, 0 );
1999 break;
2000 end;
2001 end;
2002 end;
2003 // 繝ャ繧ケ逡ェ縺ョ讀懃エ「
2004 if ((stRes = 0) and (endRes = 0) and (convBuf = '')) then begin
2005 for j := 0 to Length(RES_NAME) - 1 do begin
2006 idx := AnsiPos(RES_NAME[j], bufList[i]);
2007 if (idx = 1) then begin
2008 convBuf := Copy(bufList[i], idx + Length(RES_NAME[j]), Length(bufList[i]));
2009 stRes := StrToInt64Def( convBuf, 0 );
2010 endRes := stRes;
2011 break;
2012 end;
2013 end;
2014 end;
2015 end;
2016
2017 if (stRes <> 0) and (endRes = 0) then begin
2018 endRes := stRes + MAX_POPUP_RES;
2019 end else if (stRes = 0) and (endRes <> 0) then begin
2020 stRes := endRes - MAX_POPUP_RES;
2021 if stRes < 1 then begin
2022 stRes := 1;
2023 end;
2024 end;
2025 finally
2026 bufList.clear;
2027 bufList.free;
2028 end;
2029 end else if ( AnsiPos('.html',URL) <> Length(URL) -4 ) and ( AnsiPos('.htm',URL) <> Length(URL) -3 ) then begin
2030 buf := Copy(URL, LastDelimiter('/',URL)+1,Length(URL)-LastDelimiter('/',URL)+1);
2031 if Length(buf) > 0 then begin
2032 if AnsiPos('-', buf) = 1 then begin
2033 stRes := 0;
2034 Delete(buf,1,1);
2035 ps := 0;
2036 pch := PChar(buf);
2037 while ( ps < Length(buf) )and ( pch[ps] >= '0' ) and ( pch[ps] <= '9' ) do Inc(ps);
2038 convBuf := Copy( buf, 1, ps );
2039 if convBuf <> '' then begin
2040 endRes := StrToInt64Def(convBuf, 0);
2041 end;
2042 if endRes <> 0 then begin
2043 stRes := endRes - MAX_POPUP_RES;
2044 if stRes < 1 then
2045 stRes := 1;
2046 end;
2047 end else begin
2048 ps := 0;
2049 pch := PChar(buf);
2050 while ( ps < Length(buf) )and ( pch[ps] >= '0' ) and ( pch[ps] <= '9' ) do Inc(ps);
2051 try
2052 convBuf := Copy( buf, 1, ps );
2053 if convBuf <> '' then begin
2054 stRes := StrToInt64(convBuf);
2055 Delete(buf,1,ps+1);
2056 ps := 0;
2057 pch := PChar(buf);
2058 while ( ps < Length(buf) )and ( pch[ps] >= '0' ) and ( pch[ps] <= '9' ) do Inc(ps);
2059 convBuf := Copy( buf, 1, ps );
2060 if convBuf <> '' then begin
2061 endRes := StrToInt64Def(convBuf, 0);
2062 end;
2063 end else begin
2064 stRes := 0;
2065 end;
2066 except
2067 stRes := 0;
2068 endRes := 0;
2069 end;
2070 end;
2071 end;
2072 end;
2073 end;
2074
2075 {!
2076 \brief 2縺。繧?s縺ュ繧句ス「蠑上? URL 繧貞?隗」
2077 \param URL 2縺。繧?s縺ュ繧句ス「蠑上? URL
2078 \return 蛻?ァ」縺輔l縺溯ヲ∫エ?
2079 }
2080 function TGikoSys.Parse2chURL2(URL: string): TPathRec;
2081 var
2082 i: Integer;
2083 s: string;
2084 // buf : String;
2085 // convBuf : String;
2086 wk: string;
2087 wkMin: Integer;
2088 wkMax: Integer;
2089 wkInt: Integer;
2090 RStart: Integer;
2091 RLength: Integer;
2092 // ps : Integer;
2093 // pch : PChar;
2094 SList: TStringList;
2095 begin
2096 URL := Trim(LowerCase(URL));
2097 Result.FBBS := '';
2098 Result.FKey := '';
2099 Result.FSt := 0;
2100 Result.FTo := 0;
2101 Result.FFirst := False;
2102 Result.FStBegin := False;
2103 Result.FToEnd := False;
2104 Result.FDone := False;
2105 Result.FNoParam := False;
2106
2107 wkMin := 0;
2108 wkMax := 1;
2109 if URL[length(URL)] = '\' then
2110 URL := URL + 'n';
2111 FAWKStr.RegExp := 'http://.+\.(2ch\.net|bbspink\.com)/';
2112 if FAWKStr.Match(FAWKStr.ProcessEscSeq(URL), RStart, RLength) <> 0 then begin
2113 s := Copy(URL, RStart + RLength - 1, Length(URL));
2114
2115 //讓呎コ匁嶌蠑?/span>
2116 //譛?蠕後?l50, 10, 10-20, 10n, 10-20n, -10, 10-, 10n- 縺ェ縺ゥ
2117 //http://xxx.2ch.net/test/read.cgi/bbsid/1000000000/
2118 FAWKStr.RegExp := '/test/read.(cgi|html)/.+/[0-9]+/?.*';
2119 if FAWKStr.Match(FAWKStr.ProcessEscSeq(s), RStart, RLength) > 0 then begin
2120 s := Copy(s, 15, Length(s));
2121
2122 SList := TStringList.Create;
2123 try
2124 SList.Clear;
2125 FAWKStr.RegExp := '/';
2126 if FAWKStr.Split(FAWKStr.ProcessEscSeq(s), SList) >= 3 then begin
2127 Result.FBBS := SList[1];
2128 Result.FKey := SList[2];
2129 if SList.Count >= 4 then
2130 s := SList[3]
2131 else begin
2132 s := '';
2133 Result.FNoParam := true;
2134 end;
2135 end else
2136 Exit;
2137
2138 SList.Clear;
2139 FAWKStr.LineSeparator := mcls_CRLF;
2140 FAWKStr.RegExp := '-';
2141 if FAWKStr.Split(FAWKStr.ProcessEscSeq(s), SList) = 0 then begin
2142 Result.FFirst := True;
2143 end else begin
2144 FAWKStr.RegExp := 'l[0-9]+';
2145 if FAWKStr.Match(FAWKStr.ProcessEscSeq(s), RStart, RLength) > 0 then begin
2146 Result.FFirst := True;
2147 end else begin
2148 for i := 0 to SList.Count - 1 do begin
2149 if Trim(SList[i]) = '' then begin
2150 if i = 0 then
2151 Result.FStBegin := True;
2152 if i = (SList.Count - 1) then
2153 Result.FToEnd := True;
2154 end else if IsNumeric(SList[i]) then begin
2155 wkInt := StrToInt(SList[i]);
2156 wkMax := Max(wkMax, wkInt);
2157 if wkMin = 0 then
2158 wkMin := wkInt
2159 else
2160 wkMin := Min(wkMin, wkInt);
2161 end else if Trim(SList[i]) = 'n' then begin
2162 Result.FFirst := True;
2163 end else begin
2164 FAWKStr.RegExp := '^n[0-9]+$|^[0-9]+n$';
2165 if FAWKStr.Match(FAWKStr.ProcessEscSeq(SList[i]), RStart, RLength) > 0 then begin
2166 if Copy(SList[i], 1, 1) = 'n' then
2167 wkInt := StrToInt(Copy(SList[i], 2, Length(SList[i])))
2168 else
2169 wkInt := StrToInt(Copy(SList[i], 1, Length(SList[i]) - 1));
2170 Result.FFirst := True;
2171 wkMax := Max(wkMax, wkInt);
2172 if wkMin = 1 then
2173 wkMin := wkInt
2174 else
2175 wkMin := Min(wkMin, wkInt);
2176 end;
2177 end;
2178 end;
2179 if Result.FStBegin and (not Result.FToEnd) then
2180 Result.FSt := wkMin
2181 else if (not Result.FStBegin) and Result.FToEnd then
2182 Result.FTo := wkMax
2183 else if (not Result.FStBegin) and (not Result.FToEnd) then begin
2184 Result.FSt := wkMin;
2185 Result.FTo := wkMax;
2186 end;
2187 //Result.FSt := wkMin;
2188 //Result.FTo := wkMax;
2189 end;
2190 end;
2191 finally
2192 SList.Free;
2193 end;
2194 Result.FDone := True;
2195 Exit;
2196 end;
2197
2198 //譁ーkako譖ク蠑?/span>
2199 //http://server.2ch.net/ITA_NAME/kako/1000/10000/1000000000.html
2200 FAWKStr.RegExp := '/.+/kako/[0-9]+/[0-9]+/[0-9]+\.html';
2201 if FAWKStr.Match(FAWKStr.ProcessEscSeq(s), RStart, RLength) > 0 then begin
2202 SList := TStringList.Create;
2203 try
2204 SList.Clear;
2205 FAWKStr.RegExp := '/';
2206 if FAWKStr.Split(FAWKStr.ProcessEscSeq(s), SList) >= 6 then begin
2207 Result.FBBS := SList[1];
2208 Result.FKey := ChangeFileExt(SList[5], '');
2209 Result.FFirst := True;
2210 end else
2211 Exit;
2212 finally
2213 SList.Free;
2214 end;
2215 Result.FDone := True;
2216 Exit;
2217 end;
2218
2219 //譌ァkako譖ク蠑?/span>
2220 //http://server.2ch.net/ITA_NAME/kako/999/999999999.html
2221 FAWKStr.RegExp := '/.+/kako/[0-9]+/[0-9]+\.html';
2222 if FAWKStr.Match(FAWKStr.ProcessEscSeq(s), RStart, RLength) > 0 then begin
2223 SList := TStringList.Create;
2224 try
2225 SList.Clear;
2226 FAWKStr.RegExp := '/';
2227 if FAWKStr.Split(FAWKStr.ProcessEscSeq(s), SList) >= 5 then begin
2228 Result.FBBS := SList[1];
2229 Result.FKey := ChangeFileExt(SList[4], '');
2230 Result.FFirst := True;
2231 end else
2232 Exit;
2233 finally
2234 SList.Free;
2235 end;
2236 Result.FDone := True;
2237 Exit;
2238 end;
2239
2240 //log蜿翫?log2譖ク蠑?/span>
2241 //http://server.2ch.net/log/ITA_NAME/kako/999/999999999.html
2242 //http://server.2ch.net/log2/ITA_NAME/kako/999/999999999.html
2243 FAWKStr.RegExp := '/log2?/.+/kako/[0-9]+/[0-9]+\.html';
2244 if FAWKStr.Match(FAWKStr.ProcessEscSeq(s), RStart, RLength) > 0 then begin
2245 SList := TStringList.Create;
2246 try
2247 SList.Clear;
2248 FAWKStr.RegExp := '/';
2249 if FAWKStr.Split(FAWKStr.ProcessEscSeq(s), SList) >= 6 then begin
2250 Result.FBBS := SList[2];
2251 Result.FKey := ChangeFileExt(SList[5], '');
2252 Result.FFirst := True;
2253 end else
2254 Exit;
2255 finally
2256 SList.Free;
2257 end;
2258 Result.FDone := True;
2259 Exit;
2260 end;
2261
2262
2263 //譌ァURL譖ク蠑?/span>
2264 //http://server.2ch.net/test/read.cgi?bbs=ITA_NAME&key=1000000000&st=1&to=5&nofirst=true
2265 FAWKStr.RegExp := '/test/read\.cgi\?';
2266 if FAWKStr.Match(FAWKStr.ProcessEscSeq(s), RStart, RLength) > 0 then begin
2267 s := Copy(s, 16, Length(s));
2268 SList := TStringList.Create;
2269 try
2270 SList.Clear;
2271 FAWKStr.RegExp := '&';
2272 if FAWKStr.Split(FAWKStr.ProcessEscSeq(s), SList) >= 2 then begin
2273 Result.FFirst := True;
2274 for i := 0 to SList.Count - 1 do begin
2275 if Pos('bbs=', SList[i]) = 1 then begin
2276 Result.FBBS := Copy(SList[i], 5, Length(SList[i]));
2277 end else if Pos('key=', SList[i]) = 1 then begin
2278 Result.FKey := Copy(SList[i], 5, Length(SList[i]));
2279 end else if Pos('st=', SList[i]) = 1 then begin
2280 wk := Copy(SList[i], 4, Length(SList[i]));
2281 if IsNumeric(wk) then
2282 Result.FSt := StrToInt(wk)
2283 else if wk = '' then
2284 Result.FStBegin := True;
2285 end else if Pos('to=', SList[i]) = 1 then begin
2286 wk := Copy(SList[i], 4, Length(SList[i]));
2287 if IsNumeric(wk) then
2288 Result.FTo := StrToInt(wk)
2289 else if wk = '' then
2290 Result.FToEnd := True;
2291 end else if Pos('nofirst=', SList[i]) = 1 then begin
2292 Result.FFirst := False;
2293 end;
2294 end;
2295 end else
2296 Exit;
2297 finally
2298 SList.Free;
2299 end;
2300
2301 if (Result.FBBS <> '') and (Result.FKey <> '') then begin
2302 Result.FDone := True;
2303 end;
2304 Exit;
2305 end;
2306 end;
2307 end;
2308
2309 {!
2310 \brief URI 繧貞?隗」
2311 \param URL 蛻?ァ」縺吶k URI
2312 \param Protocol OUT:繝励Ο繝医さ繝ォ縺瑚ソ斐k(ex. http)
2313 \param Host OUT:繝帙せ繝医′霑斐k(ex. hoge.com)
2314 \param Path OUT:荳ュ髢薙ヱ繧ケ縺瑚ソ斐k(ex. test/read.cgi)
2315 \param Document OUT:繝峨く繝・繝。繝ウ繝亥錐縺瑚ソ斐k(ex. index.html)
2316 \param Port OUT:繝昴?繝医′霑斐k(ex. 8080)
2317 \param Bookmark OUT:繝悶ャ繧ッ繝槭?繧ッ(?)縺瑚ソ斐k
2318 }
2319 procedure TGikoSys.ParseURI(const URL : string; var Protocol, Host, Path, Document, Port, Bookmark: string);
2320 var
2321 URI: TIdURI;
2322 begin
2323 Protocol := '';
2324 Host := '';
2325 Path := '';
2326 Document := '';
2327 Port := '';
2328 Bookmark := '';
2329 URI := TIdURI.Create(URL);
2330 try
2331 Protocol := URI.Protocol;
2332 Host := URI.Host;
2333 Path := URI.Path;
2334 Document := URI.Document;
2335 Port := URI.Port;
2336 Bookmark := URI.Bookmark;
2337 finally
2338 URI.Free;
2339 end;
2340 end;
2341
2342 {!
2343 \brief 繧ョ繧ウ繝翫ン縺ョ繝舌?繧ク繝ァ繝ウ繧貞叙蠕?/span>
2344 \return 繝舌?繧ク繝ァ繝ウ縺ョ荳 2 譯?dwFileVersionLS)
2345 }
2346 function TGikoSys.GetVersionBuild: Integer;
2347 var
2348 FixedFileInfo: PVSFixedFileInfo;
2349 VersionHandle, VersionSize: DWORD;
2350 pVersionInfo: Pointer;
2351 ItemLen : UInt;
2352 AppFile: string;
2353 begin
2354 Result := 0;
2355 AppFile := Application.ExeName;
2356 VersionSize := GetFileVersionInfoSize(pChar(AppFile), VersionHandle);
2357 if VersionSize = 0 then
2358 Exit;
2359 GetMem(pVersionInfo, VersionSize);
2360 try
2361 if GetFileVersionInfo(PChar(AppFile),VersionHandle,VersionSize, pVersionInfo) then
2362 if VerQueryValue(pVersionInfo, '\', Pointer(FixedFileInfo), ItemLen) then
2363 Result := LOWORD(FixedFileInfo^.dwFileVersionLS);
2364 finally
2365 FreeMem(pVersionInfo, VersionSize);
2366 end;
2367 end;
2368
2369 {!
2370 \brief 繧ケ繝ャ繝?ラ URL 縺ョ豁」隕丞喧
2371 \param inURL 豁」隕丞喧縺吶k繧ケ繝ャ繝?ラ URL
2372 \return 豁」隕丞喧縺輔l縺溘せ繝ャ繝?ラ URL
2373
2374 繧ケ繝ャ繝?ラ URL 繧偵ぐ繧ウ繝翫ン縺ョ荳ュ縺ァ荳?諢上↑繧ゅ?縺ォ豁」隕丞喧縺励∪縺吶??/span>
2375 荳?諢上↑ URL 縺ォ縺吶k莠九〒縲ゞRL 縺九i繧ケ繝ャ繝?ラ繧貞ー弱″蜃コ縺吩ス懈・ュ繧呈怙驕ゥ蛹悶@縺セ縺吶??n
2376 豁」隕丞喧縺ョ譁ケ驥昴→縺励※縲√し繧、繝医′謗ィ螂ィ縺吶k繝?ヵ繧ゥ繝ォ繝医? URL 縺ォ縺ェ繧九h縺?↓蠢?′縺代∪縺吶??/span>
2377 (1-1000 縺ョ繧医≧縺ェ雋?闕キ繧偵°縺代k繧ゅ?縺ォ縺ッ縺励↑縺?%縺ィ)
2378
2379 萓?豁」隕丞喧蜑?:\n
2380 http://荳ュ逡・/ \n
2381 http://荳ュ逡・/20-100
2382
2383 (豁」隕丞喧蠕?:\n
2384 http://荳ュ逡・/l50
2385 }
2386 function TGikoSys.GetBrowsableThreadURL(
2387 inURL : string
2388 ) : string;
2389 var
2390 threadItem : TThreadItem;
2391 boardPlugIn : TBoardPlugIn;
2392 board : TBoard;
2393 i : Integer;
2394 begin
2395
2396 //===== 繝励Λ繧ー繧、繝ウ
2397 try
2398 for i := Length( BoardGroups ) - 1 downto 1 do begin
2399 if Assigned( Pointer( BoardGroups[i].BoardPlugIn.Module ) ) then begin
2400 if BoardGroups[i].BoardPlugIn.AcceptURL( inURL ) = atThread then begin
2401 board := BBSsFindBoardFromURL( BoardGroups[i].BoardPlugIn.ExtractBoardURL(inURL) );
2402 if board <> nil then begin
2403 boardPlugIn := BoardGroups[i].BoardPlugIn;
2404 threadItem := TThreadItem.Create( boardPlugIn, board, inURL );
2405 Result := threadItem.URL;
2406 threadItem.Free;
2407
2408 end;
2409 Exit;
2410 end;
2411 end;
2412 end;
2413 except
2414 // exception 縺檎匱逕溘@縺溷?エ蜷医?蜀?Κ蜃ヲ逅?↓莉サ縺帙◆縺??縺ァ縺薙%縺ァ縺ッ菴輔b縺励↑縺?/span>
2415 end;
2416
2417 if Length( Result ) = 0 then
2418 Result := GikoSys.Get2chBrowsableThreadURL( inURL );
2419
2420 end;
2421
2422 {!
2423 \brief 繧ケ繝ャ繝?ラ URL 繧呈攸 URL 縺ォ螟画鋤
2424 \param inURL 繧ケ繝ャ繝?ラ URL
2425 \return 譚ソ URL
2426 }
2427 function TGikoSys.GetThreadURL2BoardURL(
2428 inURL : string
2429 ) : string;
2430 var
2431 threadItem : TThreadItem;
2432 boardPlugIn : TBoardPlugIn;
2433 board : TBoard;
2434 i : Integer;
2435 begin
2436
2437 //===== 繝励Λ繧ー繧、繝ウ
2438 try
2439 for i := Length( BoardGroups ) - 1 downto 1 do begin
2440 if Assigned( Pointer( BoardGroups[i].BoardPlugIn.Module ) ) then begin
2441 if BoardGroups[i].BoardPlugIn.AcceptURL( inURL ) = atThread then begin
2442 board := BBSsFindBoardFromURL(BoardGroups[i].BoardPlugIn.ExtractBoardURL(inURL));
2443 boardPlugIn := BoardGroups[i].BoardPlugIn;
2444 threadItem := TThreadItem.Create( boardPlugIn, board, inURL );
2445 Result := BoardGroups[i].BoardPlugIn.GetBoardURL( Longword( threadItem ) );
2446 threadItem.Free;
2447
2448 Break;
2449 end;
2450 end;
2451 end;
2452 except
2453 // exception 縺檎匱逕溘@縺溷?エ蜷医?蜀?Κ蜃ヲ逅?↓莉サ縺帙◆縺??縺ァ縺薙%縺ァ縺ッ菴輔b縺励↑縺?/span>
2454 end;
2455
2456 if Length( Result ) = 0 then
2457 Result := GikoSys.Get2chThreadURL2BoardURL( inURL );
2458
2459 end;
2460
2461 {!
2462 \brief 2ch逕ィ:繧ケ繝ャ繝?ラ URL 繧呈攸 URL 縺ォ螟画鋤
2463 \param inURL 繧ケ繝ャ繝?ラ URL
2464 \return 譚ソ URL
2465 \see TGikoSys.GetThreadURL2BoardURL
2466 }
2467 function TGikoSys.Get2chThreadURL2BoardURL(
2468 inURL : string
2469 ) : string;
2470 var
2471 Protocol, Host, Path, Document, Port, Bookmark : string;
2472 BBSID, BBSKey : string;
2473 foundPos : Integer;
2474 begin
2475
2476 ParseURI( inURL, Protocol, Host, Path, Document, Port, Bookmark );
2477 Parse2chURL( inURL, Path, Document, BBSID, BBSKey );
2478
2479 foundPos := Pos( '/test/read.cgi', inURL );
2480 if {(Is2chHost(Host)) and} (foundPos > 0) then
2481 Result := Copy( inURL, 1, foundPos ) + BBSID + '/'
2482 else
2483 Result := Protocol + '://' + Host + '/' + BBSID + '/';
2484
2485 end;
2486
2487 {!
2488 \brief 2ch逕ィ:繧ケ繝ャ繝?ラ URL 縺ョ豁」隕丞喧
2489 \param inURL 豁」隕丞喧縺吶k繧ケ繝ャ繝?ラ URL
2490 \return 豁」隕丞喧縺輔l縺溘せ繝ャ繝?ラ URL
2491 \see TGikoSys.GetBrowsableThreadURL
2492 }
2493 function TGikoSys.Get2chBrowsableThreadURL(
2494 inURL : string
2495 ) : string;
2496 var
2497 Protocol, Host, Path, Document, Port, Bookmark : string;
2498 BBSID, BBSKey : string;
2499 foundPos : Integer;
2500 begin
2501
2502 // if Pos( KAKO_PATH, inURL ) > 0 then begin
2503 // Result := inURL;
2504 // end else begin
2505 ParseURI( inURL, Protocol, Host, Path, Document, Port, Bookmark );
2506 Parse2chURL( inURL, Path, Document, BBSID, BBSKey );
2507 foundPos := Pos( '/test/read.cgi', inURL ) - 1;
2508
2509 if Is2chHost( Host ) then begin
2510 Result := Protocol + '://' + Host +
2511 READ_PATH + BBSID + '/' + BBSKey + '/l50';
2512 end else begin
2513 if foundPos > 0 then
2514 Result := Copy( inURL, 1, foundPos ) +
2515 OLD_READ_PATH + 'bbs=' + BBSID + '&key=' + BBSKey + '&ls=50'
2516 else
2517 Result := Protocol + '://' + Host +
2518 OLD_READ_PATH + 'bbs=' + BBSID + '&key=' + BBSKey + '&ls=50';
2519 end;
2520 // end;
2521
2522 end;
2523
2524 {!
2525 \brief 2ch逕ィ:譚ソ URL 縺九i繧ケ繝ャ繝?ラ URL 繧剃ス懈?
2526 \param inBoard 譚ソ URL
2527 \param inKey 繧ケ繝ャ繝?ラ繧ュ繝シ(ex. 1000000000)
2528 \return 繧ケ繝ャ繝?ラ URL
2529 }
2530 function TGikoSys.Get2chBoard2ThreadURL(
2531 inBoard : TBoard;
2532 inKey : string
2533 ) : string;
2534 var
2535 server : string;
2536 begin
2537
2538 server := UrlToServer( inBoard.URL );
2539 //if Is2chHost( server ) then
2540 if inBoard.Is2ch then
2541 Result := server + 'test/read.cgi/' + inBoard.BBSID + '/' + inKey + '/l50'
2542 else
2543 Result := server + 'test/read.cgi?bbs=' + inBoard.BBSID + '&key=' + inKey + '&ls=50';
2544
2545 end;
2546
2547 {!
2548 \brief 繝懊?繝峨ヵ繧。繧、繝ォ蛻玲嫌
2549
2550 蛻玲嫌縺輔l縺 BBS(繝懊?繝? 縺ッ BBSs 縺ォ蜈・繧翫∪縺吶??/span>
2551 }
2552 procedure TGikoSys.ListBoardFile;
2553 var
2554 boardFileList : TStringList;
2555 i, l : Integer;
2556 sCategory : TCategory;
2557 begin
2558 // BBS 縺ョ髢区叛
2559 try
2560 for i := 0 to Length( BBSs ) - 1 do
2561 BBSs[ i ].Free;
2562 except
2563 end;
2564 SetLength( BBSs, 0 );
2565
2566 l := 0;
2567 // 譚ソ繝ェ繧ケ繝医?蛻玲嫌
2568 if FileExists( GikoSys.GetBoardFileName ) then begin
2569 SetLength( BBSs, l + 1 );
2570 BBSs[ l ] := TBBS.Create( GikoSys.GetBoardFileName );
2571 BBSs[ l ].Title := '?偵■繧?s縺ュ繧?#39;;
2572 Inc( l );
2573 end;
2574
2575 if FileExists( GikoSys.GetCustomBoardFileName ) then begin
2576 SetLength( BBSs, l + 1 );
2577 BBSs[ l ] := TBBS.Create( GikoSys.GetCustomBoardFileName );
2578 BBSs[ l ].Title := '縺昴?莉?#39;;
2579 Inc( l );
2580 end;
2581
2582 // Board 繝輔か繝ォ繝?
2583 if DirectoryExists( GikoSys.Setting.GetBoardDir ) then begin
2584 BoardFileList := TStringList.Create;
2585 try
2586 BoardFileList.BeginUpdate;
2587 GikoSys.GetFileList( GikoSys.Setting.GetBoardDir, '*.txt', BoardFileList, True, True );
2588 BoardFileList.EndUpdate;
2589 SetLength( BBSs, l + BoardFileList.Count );
2590 for i := BoardFileList.Count - 1 downto 0 do begin
2591 BBSs[ l ] := TBBS.Create( BoardFileList[ i ] );
2592 BBSs[ l ].Title := ChangeFileExt( ExtractFileName( BoardFileList[ i ] ), '' );
2593 Inc( l );
2594 end;
2595 finally
2596 BoardFileList.Free;
2597 end;
2598 end;
2599
2600 // 迚ケ谿顔畑騾韮BS逕滓?
2601 // 譌「縺ォ蟄伜惠縺吶k蝣エ蜷医?蜑企勁縺吶k
2602 DestorySpecialBBS(BoardGroup.SpecialBBS);
2603 SpecialBBS := TBBS.Create('');
2604 SpecialBBS.Title := '迚ケ谿顔畑騾?髱櫁。ィ遉コ)';
2605 sCategory := TCategory.Create;
2606 sCategory.No := 1;
2607 sCategory.Title := '迚ケ谿顔畑騾?髱櫁。ィ遉コ)';
2608 SpecialBBS.Add(sCategory);
2609 BoardGroup.SpecialBoard := TSpecialBoard.Create(nil, 'http://localhost/gikonavi/special/index.html');
2610 BoardGroup.SpecialBoard.Title := '繧ソ繝紋ク?隕ァ';
2611 BoardGroup.SpecialBoard.IsThreadDatRead := True;
2612 sCategory.Add(BoardGroup.SpecialBoard);
2613 end;
2614
2615 {!
2616 \brief 繝懊?繝峨ヵ繧。繧、繝ォ隱ュ縺ソ霎シ縺ソ
2617 \param bbs 繝懊?繝峨ヵ繧。繧、繝ォ繧定ェュ縺ソ霎シ繧? BBS
2618 }
2619 procedure TGikoSys.ReadBoardFile( bbs : TBBS );
2620 var
2621 // idx : Integer;
2622 ini : TMemIniFile;
2623 p : Integer;
2624 boardFile : TStringList;
2625 CategoryList : TStringList;
2626 BoardList : TStringList;
2627 Category : TCategory;
2628 Board : TBoard;
2629 inistr : string;
2630 tmpstring : string;
2631 // RoundItem : TRoundItem;
2632
2633 i, iBound : Integer;
2634 j, jBound : Integer;
2635 k, kBound : Integer;
2636 begin
2637
2638 if not FileExists( bbs.FilePath ) then
2639 Exit;
2640
2641 bbs.Clear;
2642 ini := TMemIniFile.Create('');
2643 boardFile := TStringList.Create;
2644
2645 try
2646 boardFile.LoadFromFile( bbs.FilePath );
2647
2648 ini.SetStrings( boardFile );
2649 CategoryList := TStringList.Create;
2650 BoardList := TStringList.Create;
2651 try
2652 ini.ReadSections( CategoryList );
2653
2654 iBound := CategoryList.Count - 1;
2655 for i := 0 to iBound do begin
2656 ini.ReadSection( CategoryList[i], BoardList );
2657 Category := TCategory.Create;
2658 Category.No := i + 1;
2659 Category.Title := CategoryList[i];
2660
2661 jBound := BoardList.Count - 1;
2662 for j := 0 to jBound do begin
2663 Board := nil;
2664 inistr := ini.ReadString(CategoryList[i], BoardList[j], '');
2665 //'http://'繧貞性縺セ縺ェ縺?枚蟄怜?縺ョ譎ゅ?辟。隕悶☆繧?/span>
2666 if (AnsiPos('http://', AnsiLowerCase(inistr)) = 0) then Continue;
2667 //===== 繝励Λ繧ー繧、繝ウ
2668 try
2669 kBound := Length(BoardGroups) - 1;
2670 for k := 1 to kBound do begin //0縺ッ縲?縺。繧?s
2671 if Assigned( Pointer( BoardGroups[k].BoardPlugIn.Module ) ) then begin
2672 if BoardGroups[k].BoardPlugIn.AcceptURL( inistr ) = atBoard then begin
2673 if not BoardGroups[k].Find(inistr, p) then begin
2674 tmpstring := BoardGroups[k].BoardPlugIn.ExtractBoardURL( inistr );
2675 if AnsiCompareStr(tmpString, inistr) <> 0 then begin
2676 if not BoardGroups[k].Find(tmpstring, p) then begin
2677 try
2678 Board := TBoard.Create( BoardGroups[k].BoardPlugIn, tmpstring );
2679 BoardGroups[k].AddObject(tmpstring, Board);
2680 Category.Add(Board);
2681 except
2682 //縺薙%縺ォ譚・繧九→縺励◆繧隠oard縺ョ菴懈?縺ォ螟ア謨励@縺溘→縺阪□縺九iBoard繧地il縺ォ縺吶k
2683 Board := nil;
2684 end;
2685 end else begin
2686 Board := TBoard(BoardGroups[k].Objects[p]);
2687 if Board.ParentCategory <> Category then
2688 Category.Add(Board);
2689 end;
2690 end else begin
2691 try
2692 Board := TBoard.Create( BoardGroups[k].BoardPlugIn, tmpstring );
2693 BoardGroups[k].AddObject(tmpstring, Board);
2694 Category.Add(Board);
2695 except
2696 //縺薙%縺ォ譚・繧九→縺励◆繧隠oard縺ョ菴懈?縺ォ螟ア謨励@縺溘→縺阪□縺九iBoard繧地il縺ォ縺吶k
2697 Board := nil;
2698 end;
2699 end;
2700 end else begin
2701 Board := TBoard(BoardGroups[k].Objects[p]);
2702 if Board.ParentCategory <> Category then
2703 Category.Add(Board);
2704 end;
2705 Break;
2706 end;
2707 end;
2708 end;
2709 except
2710 // exception 縺檎匱逕溘@縺溷?エ蜷医?蜀?Κ蜃ヲ逅?↓莉サ縺帙◆縺??縺ァ縺薙%縺ァ縺ッ菴輔b縺励↑縺?/span>
2711 end;
2712 try
2713 if (Board = nil) then begin
2714 if not BoardGroups[0].Find(inistr,p) then begin
2715 Board := TBoard.Create( nil, inistr );
2716 BoardGroups[0].AddObject(inistr, Board);
2717 Category.Add(Board);
2718 end else begin
2719 Board := TBoard(BoardGroups[0].Objects[p]);
2720 if Board.ParentCategory <> Category then
2721 Category.Add(Board);
2722 end;
2723 end;
2724
2725 if (Board.Multiplicity = 0) then begin
2726 Board.BeginUpdate;
2727 Board.No := j + 1;
2728 Board.Multiplicity := 1;
2729 Board.Title := BoardList[j];
2730 Board.RoundDate := ZERO_DATE;
2731 Board.LoadSettings;
2732 Board.EndUpdate;
2733 end else begin
2734 Board.No := j + 1;
2735 Board.Multiplicity := Board.Multiplicity + 1;
2736 end;
2737 except
2738 end;
2739 end;
2740 bbs.Add( Category );
2741 end;
2742
2743
2744 //end;
2745 bbs.IsBoardFileRead := True;
2746 finally
2747 BoardList.Free;
2748 CategoryList.Free;
2749 end;
2750 finally
2751 boardFile.Free;
2752 ini.Free;
2753 end;
2754
2755 end;
2756
2757 {!
2758 \brief 蜷咲ァー縺御ク肴?縺ェ繧ォ繝?ざ繝ェ縺ョ逕滓?
2759 \return 逕滓?縺輔l縺溘き繝?ざ繝ェ
2760 }
2761 function TGikoSys.GetUnknownCategory : TCategory;
2762 const
2763 UNKNOWN_CATEGORY = '(蜷咲ァー荳肴?)';
2764 begin
2765
2766 if Length( BBSs ) < 2 then begin
2767 Result := nil;
2768 Exit;
2769 end;
2770
2771 Result := BBSs[ 1 ].FindCategoryFromTitle( UNKNOWN_CATEGORY );
2772 if Result = nil then begin
2773 Result := TCategory.Create;
2774 Result.Title := UNKNOWN_CATEGORY;
2775 BBSs[ 1 ].Add( Result );
2776 end;
2777
2778 end;
2779
2780 {!
2781 \brief 蜷咲ァー縺御ク肴?縺ェ BBS 縺ョ逕滓?
2782 \return 逕滓?縺輔l縺 BBS
2783 }
2784 function TGikoSys.GetUnknownBoard( inPlugIn : TBoardPlugIn; inURL : string ) : TBoard;
2785 var
2786 category : TCategory;
2787 const
2788 UNKNOWN_BOARD = '(蜷咲ァー荳肴?)';
2789 begin
2790
2791 category := GetUnknownCategory;
2792 if category = nil then begin
2793 Result := nil;
2794 end else begin
2795 Result := category.FindBoardFromTitle( UNKNOWN_BOARD );
2796 if Result = nil then begin
2797 Result := TBoard.Create( inPlugIn, inURL );
2798 Result.Title := UNKNOWN_BOARD;
2799 category.Add( Result );
2800 end;
2801 end;
2802
2803 end;
2804
2805 //! Samba.ini
2806 function TGikoSys.GetSambaFileName : string;
2807 begin
2808 Result := Setting.GetSambaFileName;
2809 end;
2810 {!
2811 \brief 蛻玲嫌縺輔l縺溘Ξ繧ケ逡ェ蜿キ縺ク縺ョ繧「繝ウ繧ォ繝シ逕ィHTML菴懈?
2812 \param Numbers 蛻玲嫌縺輔l縺溘Ξ繧ケ逡ェ蜿キ
2813 \param ThreadItem 蛻玲嫌縺吶k繧ケ繝ャ繝?ラ
2814 \param limited 蛻玲嫌縺吶k謨ー繧貞宛髯舌☆繧九↑繧?莉・荳?/span>
2815 \return 蛻玲嫌縺輔l縺溘Ξ繧ケ繧「繝ウ繧ォ繝シ
2816 }
2817 function TGikoSys.CreateResAnchor(
2818 var Numbers: TStringList; ThreadItem: TThreadItem;
2819 limited: Integer):string;
2820 var
2821 i: integer;
2822 Res: TResRec;
2823 ResLink : TResLinkRec;
2824 begin
2825 // body莉・螟悶?菴ソ逕ィ縺励↑縺??縺ァ蛻晄悄蛹悶@縺ェ縺?/span>
2826 Res.FBody := '';
2827 Res.FType := glt2chNew;
2828
2829 Result := '';
2830 if (Numbers <> nil) and (Numbers.Count > 0) then begin
2831 if (limited > 0) and (Numbers.Count > limited) then begin
2832 for i := Numbers.Count - limited to Numbers.Count - 1 do begin
2833 Res.FBody := Res.FBody + '&gt;' + Numbers[i] + ' ';
2834 end;
2835 end else begin
2836 for i := 0 to Numbers.Count - 1 do begin
2837 Res.FBody := Res.FBody + '&gt;' + Numbers[i] + ' ';
2838 end;
2839 end;
2840 ResLink.FBbs := ThreadItem.ParentBoard.BBSID;
2841 ResLink.FKey := ChangeFileExt(ThreadItem.FileName, '');
2842 HTMLCreater.ConvRes(@Res, @ResLink, false);
2843 Result := Res.FBody;
2844 end;
2845 end;
2846
2847 {!
2848 \brief 蜷後§謚慕ィソ ID 繧呈戟縺、繝ャ繧ケ繧貞?謖?/span>
2849 \param AID 蛟倶ココ繧堤音螳壹☆繧区兜遞ソ ID
2850 \param ThreadItem 蛻玲嫌縺吶k繧ケ繝ャ繝?ラ
2851 \param body OUT:蛻玲嫌縺輔l縺溘Ξ繧ケ逡ェ蜿キ縺瑚ソ斐k
2852 }
2853 procedure TGikoSys.GetSameIDRes(const AID : string; ThreadItem: TThreadItem;var body: TStringList);
2854 var
2855 i: integer;
2856 ReadList: TStringList;
2857 Res: TResRec;
2858 boardPlugIn : TBoardPlugIn;
2859
2860 procedure CheckSameID(const AID:String; const Target: String; no: Integer);
2861 var
2862 pos: Integer;
2863 begin
2864 pos := AnsiPos('id:', LowerCase(Target));
2865 if (pos > 0) then begin
2866 if(AnsiPos(AID, Copy(Target, pos-1, Length(Target))) > 0) then begin
2867 body.Add(IntToStr(no));
2868 end;
2869 end else begin
2870 if(AnsiPos(AID, Target) > 0) then begin
2871 body.Add(IntToStr(no));
2872 end;
2873 end;
2874 end;
2875 begin
2876 if (not IsNoValidID(AID)) and
2877 (ThreadItem <> nil) and (ThreadItem.IsLogFile) then begin
2878 //if ThreadItem.IsBoardPlugInAvailable then begin
2879 if ThreadItem.ParentBoard.IsBoardPlugInAvailable then begin
2880 //===== 繝励Λ繧ー繧、繝ウ縺ォ繧医k陦ィ遉コ
2881 //boardPlugIn := ThreadItem.BoardPlugIn;
2882 boardPlugIn := ThreadItem.ParentBoard.BoardPlugIn;
2883
2884 for i := 0 to threadItem.Count - 1 do begin
2885 // 繝ャ繧ケ
2886 THTMLCreate.DivideStrLine(boardPlugIn.GetDat(DWORD( threadItem ), i + 1), @Res);
2887 CheckSameID(AID, Res.FDateTime, i+1);
2888 end;
2889 end else begin
2890 ReadList := TStringList.Create;
2891 try
2892 ReadList.LoadFromFile(ThreadItem.GetThreadFileName);
2893 for i := 0 to ReadList.Count - 1 do begin
2894 THTMLCreate.DivideStrLine(ReadList[i], @Res);
2895 CheckSameID(AID, Res.FDateTime, i+1);
2896 end;
2897 finally
2898 ReadList.Free;
2899 end;
2900 end;
2901 end;
2902 end;
2903
2904 {!
2905 \brief 蜷後§謚慕ィソ ID 繧呈戟縺、繝ャ繧ケ繧貞?謖?/span>
2906 \param AIDNum 蛟倶ココ繧堤音螳壹☆繧区兜遞ソ ID
2907 \param ThreadItem 蛻玲嫌縺吶k繧ケ繝ャ繝?ラ
2908 \param body OUT:蛻玲嫌縺輔l縺溘Ξ繧ケ逡ェ蜿キ縺瑚ソ斐k
2909 }
2910 procedure TGikoSys.GetSameIDRes(AIDNum : Integer; ThreadItem: TThreadItem;var body: TStringList);
2911 var
2912 AID : String;
2913 begin
2914 AID := GetResID(AIDNum, ThreadItem);
2915 if not IsNoValidID(AID) then begin
2916 GetSameIDRes(AID, ThreadItem, body);
2917 end;
2918 end;
2919 {!
2920 \brief 謚慕ィソ ID 蜿門セ?/span>
2921 \param AIDNum 謚慕ィソ 繝ャ繧ケ逡ェ蜿キ
2922 \param ThreadItem 謚慕ィソ繧ケ繝ャ繝?ラ
2923 \param body OUT:謚慕ィソID
2924 }
2925 function TGikoSys.GetResID(AIDNum: Integer; ThreadItem: TThreadItem): String;
2926 var
2927 Res: TResRec;
2928 boardPlugIn : TBoardPlugIn;
2929 begin
2930 Result := '';
2931 if (ThreadItem <> nil) and (ThreadItem.IsLogFile)
2932 and (AIDNum > 0) and (AIDNum <= ThreadItem.Count) then begin
2933 //if ThreadItem.IsBoardPlugInAvailable then begin
2934 if ThreadItem.ParentBoard.IsBoardPlugInAvailable then begin
2935 //===== 繝励Λ繧ー繧、繝ウ縺ォ繧医k陦ィ遉コ
2936 //boardPlugIn := ThreadItem.BoardPlugIn;
2937 boardPlugIn := ThreadItem.ParentBoard.BoardPlugIn;
2938 THTMLCreate.DivideStrLine(boardPlugIn.GetDat(DWORD( threadItem ), AIDNum), @Res);
2939 end else begin
2940 THTMLCreate.DivideStrLine( ReadThreadFile(ThreadItem.GetThreadFileName, AIDNum), @Res);
2941 end;
2942 Result := ExtructResID(Res.FDateTime);
2943 end;
2944 end;
2945 {!
2946 \brief 繝ャ繧ケ縺ョ譎ょ綾驛ィ縺九iID繧呈歓蜃コ縺吶k
2947 \param ADateStr 譎ょ綾驛ィ縺ョ譁?ュ怜?
2948 \return ID(ID縺ィ縺ソ縺ェ縺帙k驛ィ蛻?′縺ェ縺?→縺阪?遨コ譁?ュ怜?)
2949 }
2950 function TGikoSys.ExtructResID(ADateStr: String): String;
2951 var
2952 stlist : TStringList;
2953 begin
2954 Result := '';
2955 if AnsiPos('id', AnsiLowerCase(ADateStr)) > 0 then begin
2956 Result := Copy(ADateStr, AnsiPos('id', AnsiLowerCase(ADateStr)), Length(ADateStr));
2957 if AnsiPos(' ', Result) > 0 then begin
2958 Result := Copy(Result, 1, AnsiPos(' ', Result) - 1);
2959 end;
2960 Result := ' ' + Result;
2961 end else begin
2962 stlist := TStringList.Create;
2963 try
2964 stList.Delimiter := ' ';
2965 stList.DelimitedText := ADateStr;
2966 // 譌・莉 譎ょ綾 ID 莉悶??縺ィ蝗コ螳壹〒閠?∴繧?/span>
2967 if (stList.Count >= 3) then begin
2968 if Length(stList[3 - 1]) >= 7 then begin
2969 Result := stList[3 - 1];
2970 end;
2971 end;
2972 finally
2973 stList.Free;
2974 end;
2975 end;
2976 end;
2977
2978 {!
2979 \brief 繧ケ繝代Β:隱樊焚繧偵き繧ヲ繝ウ繝?/span>
2980 \param text 蜈?↓縺ェ繧区枚遶?
2981 \param wordCount OUT:繧ォ繧ヲ繝ウ繝医&繧後◆蜊倩ェ槭?荳?隕ァ縺瑚ソ斐k
2982 }
2983 procedure TGikoSys.SpamCountWord( const text : string; wordCount : TWordCount );
2984 begin
2985
2986 if Setting.SpamFilterAlgorithm = gsfaNone then Exit;
2987 Bayesian.CountWord( text, wordCount );
2988
2989 end;
2990
2991 {!
2992 \brief 繧ケ繝代Β:蟄ヲ鄙堤オ先棡繧呈叛譽?/span>
2993 \param wordCount 謾セ譽?☆繧句腰隱槭?荳?隕ァ
2994 \param isSpam wordCount 縺後せ繝代Β縺ィ縺励※蟄ヲ鄙偵&繧後※縺?◆縺ェ繧 True
2995 \warning 蟄ヲ鄙呈ク医∩縺ョ譁?ォ?縺九←縺?°縺ッ遒コ隱榊?譚・縺セ縺帙s縲?n
2996 Learn 縺励※縺?↑縺?枚遶?繧 isSpam 繧帝俣驕輔∴縺ヲ謖?ョ壹☆繧九→
2997 繝??繧ソ繝吶?繧ケ縺檎?エ謳阪@縺セ縺吶??n
2998 蟄ヲ鄙呈ク医∩縺九←縺?°縺ッ迢ャ閾ェ縺ォ邂。逅?@縺ヲ縺上□縺輔>縲?/span>
2999
3000 蜈ィ縺ヲ縺ョ蟄ヲ鄙堤オ先棡繧偵け繝ェ繧「縺吶k繧上¢縺ァ縺ッ縺ゅj縺セ縺帙s縲?n
3001 wordCount 繧貞セ励◆譁?ォ?縺ョ蟄ヲ鄙堤オ先棡縺ョ縺ソ繧ッ繝ェ繧「縺励∪縺吶??/span>
3002
3003 荳サ縺ォ繧ケ繝代Β縺ィ繝上Β繧貞?繧頑崛縺医k縺溘a縺ォ Forget -> Learn 縺ョ鬆?〒菴ソ逕ィ縺励∪縺吶??/span>
3004 }
3005 procedure TGikoSys.SpamForget( wordCount : TWordCount; isSpam : Boolean );
3006 begin
3007
3008 if Setting.SpamFilterAlgorithm = gsfaNone then Exit;
3009 Bayesian.Forget( wordCount, isSpam );
3010
3011 end;
3012
3013 {!
3014 \brief 繧ケ繝代Β:蟄ヲ鄙?/span>
3015 \param wordCount 蟄ヲ鄙偵☆繧句腰隱槭?荳?隕ァ
3016 \param isSpam 繧ケ繝代Β縺ィ縺励※蟄ヲ鄙偵☆繧九↑繧 True
3017 }
3018 procedure TGikoSys.SpamLearn( wordCount : TWordCount; isSpam : Boolean );
3019 begin
3020
3021 if Setting.SpamFilterAlgorithm = gsfaNone then Exit;
3022 Bayesian.Learn( wordCount, isSpam );
3023
3024 end;
3025
3026 {!
3027 \brief 繧ケ繝代Β:譁?ォ?繧定ァ」譫舌@縲√せ繝代Β蠎ヲ謨ー繧貞セ励k
3028 \param text 蜈?↓縺ェ繧区枚遶?
3029 \param wordCount OUT:繧ォ繧ヲ繝ウ繝医&繧後◆蜊倩ェ槭?荳?隕ァ縺瑚ソ斐k(SpamCountWord 縺ィ蜷檎ュ?
3030 \return 0縲? 縺ョ繧ケ繝代Β蠎ヲ謨ー
3031 }
3032 function TGikoSys.SpamParse( const text : string; wordCount : TWordCount ) : Extended;
3033 begin
3034
3035 case Setting.SpamFilterAlgorithm of
3036 gsfaNone: Result := 0;
3037 gsfaPaulGraham: Result := Bayesian.Parse( text, wordCount, gbaPaulGraham );
3038 gsfaGaryRobinson: Result := Bayesian.Parse( text, wordCount, gbaGaryRobinson );
3039 gsfaGaryRobinsonFisher: Result := Bayesian.Parse( text, wordCount, gbaGaryRobinsonFisher );
3040 else Result := 0;
3041 end;
3042
3043 end;
3044
3045 {!
3046 \brief 繝ヲ繝シ繧カ險ュ螳壹? CSS 繧堤函謌?/span>
3047 \return 逕滓?縺輔l縺 CSS
3048
3049 [繝??繝ォ]繝。繝九Η繝シ-[繧ェ繝励す繝ァ繝ウ]-[CSS 縺ィ繧ケ繧ュ繝ウ]繧ソ繝悶?
3050 [繝輔か繝ウ繝医r謖?ョ咯, [閭梧勹濶イ繧呈欠螳咯 縺ォ豐ソ縺」縺 CSS 繧堤函謌舌@縺セ縺吶??/span>
3051 }
3052 function TGikoSys.SetUserOptionalStyle(): string;
3053 begin
3054 Result := '';