6 Windows, Messages, SysUtils, Classes,
7 GikoSystem, BoardGroup;
10 TGikoRoundType = (grtBoard, grtItem);
13 TRoundList = class(TObject)
15 FOldFileRead: Boolean;
18 function GetCount(RoundType: TGikoRoundType): Integer;
19 function GetRoundItem(Index: Integer; RoundType: TGikoRoundType): TRoundItem;
20 function ParseRoundBoardLine(Line: string): Boolean;
21 function ParseRoundThreadLine(Line: string): Boolean;
22 function ParseOldRoundBoardLine(Line: string): Boolean;
23 function ParseOldRoundThreadLine(Line: string): Boolean;
25 RoundNameList: TStringList;
28 destructor Destroy; override;
29 function Add(Board: TBoard): Integer; overload;
30 function Add(ThreadItem: TThreadItem): Integer; overload;
31 procedure Delete(Board: TBoard); overload;
32 procedure Delete(ThreadItem: TThreadItem); overload;
33 procedure Delete(URL: string; RoundType: TGikoRoundType); overload;
35 function Find(Board: TBoard): Integer; overload;
36 function Find(ThreadItem: TThreadItem): Integer; overload;
37 function Find(URL: string; RoundType: TGikoRoundType): Integer; overload;
38 property Count[RoundType: TGikoRoundType]: Integer read GetCount;
39 property OldFileRead: Boolean read FOldFileRead;
40 property Items[Index: integer; RoundType: TGikoRoundType]: TRoundItem read GetRoundItem;
41 //procedure SetRoundName(Board: TBoard; RoundName: string); overload;
42 //procedure SetRoundName(ThreadItem: TThreadItem; RoundName: string); overload;
44 procedure LoadRoundBoardFile;
45 procedure LoadRoundThreadFile;
46 procedure SaveRoundFile;
48 procedure URLReplace(oldURLs: TStringList; newURLs :TStringList);
51 TRoundItem = class(TObject)
55 FBBSType: TGikoBBSType;
57 FRoundType: TGikoRoundType;
60 //FBoardTitle: string;
61 //FThreadTitle: string;
64 FBoolData: Boolean; //
\82¢
\82ë
\82¢
\82ë
\8eg
\82¤
\82å
\82£
65 function GetBoardTitle : string;
66 function GetThreadTitle : string;
67 function GetURL : string;
68 function GetFileName : string;
72 property Item : TObject read FItem;
73 //property BBSType: TGikoBBSType read FBBSType write FBBSType;
74 property RoundName: string read FRoundName write FRoundName;
75 property RoundType: TGikoRoundType read FRoundType write FRoundType;
76 //property Item : TObject read FItem write FItem;
77 property URL : string read GetURL;
78 property TmpURL : string read FTmpURL write FTmpURL;
79 property BoardTitle: string read GetBoardTitle;
80 property ThreadTitle: string read GetThreadTitle;
81 property FileName: string read GEtFileName;
82 property BoolData: Boolean read FBoolData write FBoolData;
86 RoundList: TRoundList;
90 ROUND_BOARD_FILENAME: string = 'RoundBoard.2ch'; //
\82 \82Æ
\82ÅBoardGroup
\82Ö
\88Ú
\93®
91 ROUND_ITEM_FILENAME: string = 'RoundItem.2ch'; //
\93¯
\8fã
92 ROUND_INDEX_VERSION: string = '2.00';
93 ERROR_BOARD_FILENAME: string = 'ErrorBoard.2ch'; //Error
\8ds
\82ð
\95Û
\8aÇ
\82·
\82é
94 ERROR_ITEM_FILENAME: string = 'ErrorItem.2ch'; //Error
\8ds
\82ð
\95Û
\8aÇ
\82·
\82é
95 constructor TRoundItem.Create;
99 function TRoundItem.GetBoardTitle : string;
102 if( Self.FItem <> nil) then begin
103 if( Self.FItem is TBoard) then begin
104 Result := TBoard(Self.FItem).Title;
105 end else if( Self.FItem is TThreadItem) then begin
106 Result := TThreadItem(Self.FItem).ParentBoard.Title;
110 function TRoundItem.GetThreadTitle : string;
113 if( Self.FItem <> nil) then begin
114 if( Self.FItem is TThreadItem) then begin
115 Result := TThreadItem(Self.FItem).Title;
119 function TRoundItem.GetURL : string;
122 if( Self.FItem <> nil) then begin
123 if( Self.FItem is TBoard) then begin
124 Result := TBoard(Self.FItem).URL;
125 end else if( Self.FItem is TThreadItem) then begin
126 Result := TThreadItem(Self.FItem).URL;
130 function TRoundItem.GetFileName : string;
133 if( Self.FItem <> nil) then begin
134 if( Self.FItem is TThreadItem) then begin
135 Result := TThreadItem(Self.FItem).FileName;
139 constructor TRoundList.Create;
142 FBoardList := TList.Create;
143 FItemList := TList.Create;
144 RoundNameList := TStringList.Create;
145 RoundNameList.Sorted := True;
146 RoundNameList.Duplicates := dupIgnore;
147 FOldFileRead := false;
150 destructor TRoundList.Destroy;
159 function TRoundList.Add(Board: TBoard): Integer;
166 //RoundNameList.Add(Board.RoundName);
167 if idx = -1 then begin
168 Item := TRoundItem.Create;
170 // Item.BBSType := gbt2ch; //
\82Æ
\82è
\82 \82¦
\82¸
171 Item.RoundType := grtBoard;
172 // Item.Item := Board;
173 //Item.URL := Board.URL;
174 //Item.BoardTitle := Board.Title;
175 //Item.ThreadTitle := '';
176 //Item.FileName := '';
177 Item.RoundName := Board.RoundName;
178 Result := FBoardList.Add(Item);
182 function TRoundList.Add(ThreadItem: TThreadItem): Integer;
188 idx := Find(ThreadItem);
189 //RoundNameList.Add(ThreadItem.RoundName);
190 if idx = -1 then begin
191 Item := TRoundItem.Create;
192 Item.FItem := ThreadItem;
193 // Item.BBSType := gbt2ch; //
\82Æ
\82è
\82 \82¦
\82¸
194 Item.RoundType := grtItem;
195 // Item.Item := ThreadItem;
196 //Item.URL := Threaditem.URL;
197 //Item.BoardTitle := ThreadItem.ParentBoard.Title;
198 //Item.ThreadTitle := ThreadItem.Title;
199 //Item.FileName := ThreadItem.FileName;
200 Item.RoundName := ThreadItem.RoundName;
201 Result := FItemList.Add(Item);
205 procedure TRoundList.Delete(Board: TBoard);
211 if idx <> -1 then begin
212 TBoard(TRoundItem(FBoardList[idx]).FItem).RoundName := '';
213 TRoundItem(FBoardList[idx]).Free;
214 FBoardList.Delete(idx);
218 procedure TRoundList.Delete(ThreadItem: TThreadItem);
223 idx := Find(ThreadItem);
224 if idx <> -1 then begin
225 TThreadItem(TRoundItem(FItemList[idx]).FItem).RoundName := '';
226 TRoundItem(FItemList[idx]).Free;
227 FItemList.Delete(idx);
231 procedure TRoundList.Clear;
235 for i := FBoardList.Count - 1 downto 0 do begin
236 if FBoardList[i] <> nil then
237 TRoundItem(FBoardList[i]).Free;
238 FBoardList.Delete(i);
240 FBoardList.Capacity := FBoardList.Count;
241 for i := FItemList.Count - 1 downto 0 do begin
242 if FItemList[i] <> nil then
243 TRoundItem(FItemList[i]).Free;
246 FItemList.Capacity := FItemList.Count;
249 function TRoundList.Find(Board: TBoard): Integer;
255 for i := 0 to FBoardList.Count - 1 do begin
256 Item := TRoundItem(FBoardList[i]);
257 if Item.FRoundType <> grtBoard then Continue;
258 if Item.FItem = Board then begin
265 function TRoundList.Find(ThreadItem: TThreadItem): Integer;
271 for i := 0 to FItemList.Count - 1 do begin
272 Item := TRoundItem(FItemList[i]);
273 if Item.FRoundType <> grtItem then Continue;
274 if Item.FItem = ThreadItem then begin
280 function TRoundList.Find(URL: string; RoundType: TGikoRoundType): Integer;
286 if RoundType = grtItem then begin
287 for i := 0 to FItemList.Count - 1 do begin
288 Item := TRoundItem(FItemList[i]);
289 if Item.FRoundType <> RoundType then Continue;
290 if Item.URL = URL then begin
296 for i := 0 to FBoardList.Count - 1 do begin
297 Item := TRoundItem(FBoardList[i]);
298 if Item.FRoundType <> RoundType then Continue;
299 if Item.URL = URL then begin
306 procedure TRoundList.Delete(URL: string; RoundType: TGikoRoundType);
311 threadItem: TThreadItem;
313 idx := Find(URL, RoundType);
314 if idx <> -1 then begin
316 if RoundType = grtBoard then begin
317 Item := TRoundItem(FBoardList[idx]);
318 board := TBoard(Item);
320 FBoardList.Delete(idx);
321 //board := BBSsFindBoardFromURL(URL);
322 if board <> nil then begin
323 board.Round := False;
324 board.RoundName := '';
327 Item := TRoundItem(FItemList[idx]);
328 threadItem := TThreadItem(Item.FItem);
330 FItemList.Delete(idx);
332 //threadItem := BBSsFindThreadFromURL(URL);
333 if threadItem <> nil then begin
334 threadItem.Round := false;
335 threadItem.RoundName := '';
341 procedure TRoundList.SetRoundName(Board: TBoard; RoundName: string);
347 if idx <> -1 then begin
348 Item := TRoundItem(FBoardList[idx]);
349 Item.RoundName := RoundName;
354 procedure TRoundList.SetRoundName(ThreadItem: TThreadItem; RoundName: string);
359 idx := Find(ThreadItem);
360 if idx <> -1 then begin
361 Item := TRoundItem(FItemList[idx]);
362 Item.RoundName := RoundName;
366 function TRoundList.GetCount(RoundType: TGikoRoundType): Integer;
369 if RoundType = grtBoard then
370 Result := FBoardList.Count
371 else if RoundType = grtItem then
372 Result := FItemList.Count;
375 function TRoundList.GetRoundItem(Index: Integer; RoundType: TGikoRoundType): TRoundItem;
378 if RoundType = grtBoard then begin
379 if (Index >= 0) and (Index < FBoardList.Count) then
380 Result := TRoundItem(FBoardList[Index]);
381 end else if RoundType = grtItem then begin
382 if (Index >= 0) and (Index < FItemList.Count) then
383 Result := TRoundItem(FItemList[Index]);
386 procedure TRoundList.LoadRoundBoardFile;
390 FileName, bFileName: string;
391 errorSl: TStringList;
392 errorFileName: string;
396 sl := TStringList.Create;
397 errorSl := TStringList.Create;
398 errorSl.Duplicates := dupIgnore;
400 //
\83{
\81[
\83h
\8f\84\89ñ
\83t
\83@
\83C
\83\8b\93Ç
\82Ý
\8d\9e\82Ý
401 FileName := GikoSys.GetConfigDir + ROUND_BOARD_FILENAME;
402 bFileName := GikoSys.GetConfigDir + '~' + ROUND_BOARD_FILENAME;
403 //
\83G
\83\89\81[
\8ds
\95Û
\91¶
\83t
\83@
\83C
\83\8b\93Ç
\82Ý
\8d\9e\82Ý
404 errorFileName := GikoSys.GetConfigDir + ERROR_BOARD_FILENAME;
406 if FileExists(FileName) then begin
407 sl.LoadFromFile(FileName);
408 if FileExists(bFileName) then
409 DeleteFile(bFileName);
410 //
\83o
\83b
\83N
\83A
\83b
\83v
\97p
\82Ì
\83t
\83@
\83C
\83\8b\82ð
\8dì
\90¬
\82·
\82é
411 sl.SaveToFile(bFileName);
412 if FileExists(errorFileName) then begin
414 errorSl.LoadFromFile(errorFileName);
418 //Item := TRoundItem.Create;
420 //
\82P
\8ds
\96Ú
\82Í
\83o
\81[
\83W
\83\87\83\93
421 if sl[0] = ROUND_INDEX_VERSION then begin
422 for i := 1 to sl.Count - 1 do begin
423 if not ParseRoundBoardLine(sl[i - delCount]) then begin
424 errorSl.Add( sl[i - delCount] );
425 sl.Delete(i- delCount);
430 if FOldFileRead then begin //
\83M
\83R
\83i
\83r
\96{
\91Ì
\82ª
\83{
\81[
\83h
\83t
\83@
\83C
\83\8b\82ð
\82æ
\82Ý
\82Æ
\82Á
\82½
\8cã
\82¶
\82á
\82È
\82¢
\82Æ
\83N
\83\89\83b
\83V
\83\85\82·
\82é
\82Ì
\82Å
431 for i := 1 to sl.Count - 1 do begin
432 if not ParseOldRoundBoardLine(sl[i - delCount]) then begin
433 errorSl.Add( sl[i- delCount] );
434 sl.Delete(i- delCount);
439 FOldFileRead := true;
442 if errorSl.Count > 0 then
443 errorSl.SaveToFile(errorFileName);
449 procedure TRoundList.LoadRoundThreadFile;
454 FileName, bFileName: string;
455 errorSl: TStringList;
456 errorFileName: string;
459 // boardList : TStringList;
461 // boardList := TStringList.Create;
462 // boardList.Duplicates := dupIgnore;
463 errorSl := TStringList.Create;
464 errorSl.Duplicates := dupIgnore;
465 sl := TStringList.Create;
467 //
\83X
\83\8c\8f\84\89ñ
\83t
\83@
\83C
\83\8b\93Ç
\82Ý
\8d\9e\82Ý
468 FileName := GikoSys.GetConfigDir + ROUND_ITEM_FILENAME;
469 bFileName := GikoSys.GetConfigDir + '~' + ROUND_ITEM_FILENAME;
470 //
\83G
\83\89\81[
\8ds
\95Û
\91¶
\83t
\83@
\83C
\83\8b\93Ç
\82Ý
\8d\9e\82Ý
471 errorFileName := GikoSys.GetConfigDir + ERROR_ITEM_FILENAME;
472 if FileExists(FileName) then begin
473 sl.LoadFromFile(FileName);
474 if FileExists(bFileName) then
475 DeleteFile(bFileName);
476 sl.SaveToFile(bFileName);
477 if FileExists(errorFileName) then begin
479 errorSl.LoadFromFile(errorFileName);
483 //Item := TRoundItem.Create;
485 //
\82P
\8ds
\96Ú
\82Í
\83o
\81[
\83W
\83\87\83\93
486 if sl[0] = ROUND_INDEX_VERSION then begin
487 for i := 1 to sl.Count - 1 do begin
488 if not ParseRoundThreadLine(sl[i - delCount]) then begin
489 errorSl.Add(sl[i - delCount]);
490 sl.Delete(i - delCount);
496 for i := 1 to sl.Count - 1 do begin
497 if not ParseOldRoundThreadLine(sl[i - delCount]) then begin
498 errorSl.Add(sl[i - delCount]);
499 sl.Delete(i - delCount);
504 // j := boardList.Count - 1;
505 // while j >= 0 do begin
506 // GikoSys.ReadSubjectFile( BBSsFindBoardFromURL( boardList[j] ) );
507 // boardList.Delete(j);
510 if errorSl.Count > 0 then
511 errorSl.SaveToFile(errorFileName);
519 procedure TRoundList.SaveRoundFile;
527 GikoSys.ForceDirectoriesEx(GikoSys.GetConfigDir);
529 sl := TStringList.Create;
531 FileName := GikoSys.GetConfigDir + ROUND_BOARD_FILENAME;
532 sl.Add(ROUND_INDEX_VERSION);
533 for i := 0 to FBoardList.Count - 1 do begin
534 Item := TRoundItem(FBoardList[i]);
536 if Item.TmpURL <> '' then begin
537 s := Item.TmpURL + #1
538 + Item.BoardTitle + #1
542 + Item.BoardTitle + #1
549 sl.SaveToFile(FileName);
551 FileName := GikoSys.GetConfigDir + ROUND_ITEM_FILENAME;
552 sl.Add(ROUND_INDEX_VERSION);
553 for i := 0 to FItemList.Count - 1 do begin
554 Item := TRoundItem(FItemList[i]);
556 if Item.TmpURL <> '' then begin
557 s := Item.TmpURL + #1
558 + Item.BoardTitle + #1
560 + Item.ThreadTitle + #1
564 + Item.BoardTitle + #1
566 + Item.ThreadTitle + #1
573 sl.SaveToFile(FileName);
578 function TRoundList.ParseRoundBoardLine(Line: string): Boolean;
585 //Result := TRoundItem.Create;
586 //Result.ThreadTitle := '';
587 //Result.FileName := '';
588 //Result.RoundType := grtBoard;
590 for i := 0 to 2 do begin
591 s := GikoSys.GetTokenIndex(Line, #1, i);
596 board := BBSsFindBoardFromURL(s);
599 //1: Result.BoardTitle := s;
607 if( board <> nil ) then begin
608 if not board.Round then begin
609 board.RoundName := roundname;
610 RoundNameList.Add(roundname);
611 //RoundNameList.Find(roundname, i);
612 //board.RoundName := PChar(RoundNameList[i]);
621 function TRoundList.ParseRoundThreadLine(Line: string): Boolean;
625 threadItem: TThreadItem;
627 // threadItem: TThreadItem;
629 //Result := TRoundItem.Create;
630 //Result.RoundType := grtItem;
632 for i := 0 to 4 do begin
633 s := GikoSys.GetTokenIndex(Line, #1, i);
639 threadItem := BBSsFindThreadFromURL( s );
640 //if threadItem <> nil then begin
641 // BoardList.Add( threadItem.ParentBoard.URL );
644 //1: Result.BoardTitle := s;
645 //2: Result.FileName := s;
646 //3: Result.ThreadTitle := s;
654 if( threadItem <> nil ) then begin
655 if not threadItem.Round then begin
656 threadItem.RoundName := roundname;
657 RoundNameList.Add(roundname);
658 //RoundNameList.Find(roundname, i);
659 //threadItem.RoundName := PChar(RoundNameList[i]);
660 threadItem.Round := True;
668 function TRoundList.ParseOldRoundBoardLine(Line: string): Boolean;
675 //Result := TRoundItem.Create;
676 //Result.ThreadTitle := '';
677 //Result.FileName := '';
678 //Result.RoundType := grtBoard;
680 for i := 0 to 2 do begin
681 s := GikoSys.GetTokenIndex(Line, #1, i);
686 board := BBSs[ 0 ].FindBBSID( s );
687 if board = nil then begin
688 raise Exception.Create('
\82±
\82Ì
\8f\84\89ñ
\82Í
\93Ç
\82Ý
\8d\9e\82ß
\82È
\82¢
\82æ
\81i
\91½
\95ª
\8aO
\95\94\94Â
\81j');
691 //1: Result.FBoardTitle := s;
699 if( board <> nil ) then begin
700 if not board.Round then begin
701 board.RoundName := roundname;
702 RoundNameList.Add(roundname);
703 //RoundNameList.Find(roundname, i);
704 //board.RoundName := PChar(RoundNameList[i]);
713 function TRoundList.ParseOldRoundThreadLine(Line: string): Boolean;
720 threadItem: TThreadItem;
723 // Result := TRoundItem.Create;
724 // Result.RoundType := grtItem;
726 for i := 0 to 4 do begin
727 s := GikoSys.GetTokenIndex(Line, #1, i);
731 //1: Result.BoardTitle := s;
734 //Result.FileName := s;
735 board := BBSs[ 0 ].FindBBSID(bbsID);
736 if board <> nil then begin
737 buf := Copy(board.GetSendURL,1,LastDelimiter('/', board.GetSendURL)-1);
738 buf := buf + '/read.cgi/'+ board.BBSID+ '/' +ChangeFileExt(s,'') + '/l50';
739 threadItem := BBSsFindThreadFromURL(buf);
741 raise Exception.Create('
\82±
\82Ì
\8f\84\89ñ
\82Í
\93Ç
\82Ý
\8d\9e\82ß
\82È
\82¢
\82æ');
744 //3: Result.ThreadTitle := s;
752 if( threadItem <> nil ) then begin
753 if not threadItem.Round then begin
754 threadItem.RoundName := roundname;
755 RoundNameList.Add(roundname);
756 //RoundNameList.Find(roundname, i);
757 //threadItem.RoundName := PChar(RoundNameList[i]);
758 threadItem.Round := true;
766 procedure TRoundList.URLReplace(oldURLs: TStringList; newURLs :TStringList);
773 oldBoardName: string;
775 newBoardName: string;
777 if oldURLs.Count <> newURLs.Count then
779 //
\82±
\82±
\82©
\82ç
\81ABoard
\82ÌURL
\82Ì
\95Ï
\8dX
780 for j :=0 to oldURLs.Count - 1 do begin
781 for i :=0 to FBoardList.Count - 1 do begin
782 if TRoundItem(FBoardList[i]).URL = oldURLs[j] then
783 TRoundItem(FBoardList[i]).TmpURL := newURLs[j];
786 //
\82±
\82±
\82Ü
\82Å
\81ABoard
\82ÌURL
\82Ì
\95Ï
\8dX
788 //
\82±
\82±
\82©
\82ç
\81AThread
\82ÌURL
\82Ì
\95Ï
\8dX
789 //
\96Ê
\93|
\82¾
\82¯
\82Çthread
\82Í
\82»
\82ê
\82¼
\82êURL
\82ð
\83`
\83\83\83b
\83N
\82µ
\82È
\82ª
\82ç
\82â
\82Á
\82Ä
\82©
\82È
\82«
\82á
\82¢
\82¯
\82È
\82¢
\81B
790 for i := 0 to oldURLs.Count - 1 do begin
791 tmpURL := Copy(oldURLs[i], 1, Length(oldURLs[i]) -1);
792 oldHost := Copy(tmpURL, 1, LastDelimiter('/', tmpURL) );
793 oldBoardName := Copy(tmpURL, LastDelimiter('/', tmpURL), Length(tmpURL) ) + '/';
794 tmpURL := Copy(newURLs[i], 1, Length(newURLs[i]) -1);
795 newHost := Copy(tmpURL, 1, LastDelimiter('/', tmpURL) );
796 newBoardName := Copy(tmpURL, LastDelimiter('/', tmpURL), Length(tmpURL) ) + '/';
798 for j := 0 to FItemList.Count - 1 do begin
799 tempString := TRoundItem(FItemList[j]).URL;
800 if ( AnsiPos(oldBoardName, tempString) <> 0 ) and ( AnsiPos(oldHost, tempString ) <> 0 ) then begin
801 tempString := StringReplace(tempString, oldHost, newHost,[]);
802 TRoundItem(FItemList[j]).TmpURL := tempString;
806 //
\82±
\82±
\82Ü
\82Å
\81AThread
\82ÌURL
\82Ì
\95Ï
\8dX