diff --git a/source/decodetorrent.pas b/source/decodetorrent.pas
index e34be6f..c1ed5c5 100644
--- a/source/decodetorrent.pas
+++ b/source/decodetorrent.pas
@@ -47,7 +47,7 @@ TDecodeTorrent = class
FTotalFileSize: int64;
//Torrent file must have 'info' item.
- FBEncoded_Info:TBEncoded;
+ FBEncoded_Info: TBEncoded;
FBEncoded_Comment: TBEncoded;
FInfoHash: utf8string;
@@ -149,10 +149,12 @@ constructor TDecodeTorrent.Create;
//Every torrent have
FObjectListFileNameAndLength := TObjectList.Create;
-
+ //List for all the trackers.
TrackerList := TStringList.Create;
TrackerList.Duplicates := dupIgnore;
- TrackerList.Sorted := True;
+ //Must keep the original order.
+ TrackerList.Sorted := False;
+
FMemoryStream := TMemoryStream.Create;
end;
@@ -207,32 +209,42 @@ function TDecodeTorrent.GetAnnounceList: boolean;
var
TempBEncoded: TBEncoded;
i, Count: integer;
+ TrackerStr: UTF8String;
begin
//return false, if crash at decoding. Announce is optional in torrent file.
TrackerList.Clear;
Result := True;
try
{find 'announce-list' and copy the list content to TrackerList}
- //process 'announce'
- TempBEncoded := FBEncoded.ListData.FindElement('announce');
- if assigned(TempBEncoded) then
- begin
- TrackerList.Add(TempBEncoded.StringData);
- end;
+ //process 'announce'
+ TempBEncoded := FBEncoded.ListData.FindElement('announce');
+ if assigned(TempBEncoded) then
+ begin
+ TrackerList.Add(TempBEncoded.StringData);
+ end;
- //process 'announce-list'
- TempBEncoded := FBEncoded.ListData.FindElement('announce-list');
- if assigned(TempBEncoded) then
+ //process 'announce-list'
+ TempBEncoded := FBEncoded.ListData.FindElement('announce-list');
+ if assigned(TempBEncoded) then
+ begin
+ Count := TempBEncoded.ListData.Count;
+ if Count > 0 then
begin
- Count := TempBEncoded.ListData.Count;
- if Count > 0 then
+ for i := 0 to Count - 1 do
begin
- for i := 0 to Count - 1 do
- begin//there is a list in side a list!
- TrackerList.Add(TempBEncoded.ListData.Items[i].Data.ListData.First.Data.StringData);
+ //there is a list in side a list!
+ TrackerStr := TempBEncoded.ListData.Items[
+ i].Data.ListData.First.Data.StringData;
+
+ // TrackerList is not sorted. Must use IndexOf to ignore duplicated enteries.
+ if TrackerList.IndexOf(TrackerStr) < 0 then
+ begin
+ TrackerList.Add(TrackerStr);
end;
+
end;
end;
+ end;
except
Result := False;
@@ -242,7 +254,7 @@ function TDecodeTorrent.GetAnnounceList: boolean;
function TDecodeTorrent.GetFileList: boolean;
var
//TempBEncodedInfo,
- TempBEncodedInfoFiles, TempBEncodedInfoFilesPath: TBEncoded;
+ TempBEncodedInfoFiles, TempBEncodedInfoFilesPath: TBEncoded;
TempBEncodedInfoFilesData: TBEncodedData;
i, x, countFiles, countPath: integer;
@@ -262,60 +274,60 @@ function TDecodeTorrent.GetFileList: boolean;
try
{find 'info.files' }
- TempBEncodedInfoFiles := FBEncoded_Info.ListData.FindElement('files');
+ TempBEncodedInfoFiles := FBEncoded_Info.ListData.FindElement('files');
- if assigned(TempBEncodedInfoFiles) then
- begin //'info.files' found
- countFiles := TempBEncodedInfoFiles.ListData.Count;
- if countFiles > 0 then
+ if assigned(TempBEncodedInfoFiles) then
+ begin //'info.files' found
+ countFiles := TempBEncodedInfoFiles.ListData.Count;
+ if countFiles > 0 then
+ begin
+ for i := 0 to countFiles - 1 do
begin
- for i := 0 to countFiles - 1 do
+ //Get the info.files node.
+ TempBEncodedInfoFilesData := TempBEncodedInfoFiles.ListData.Items[i];
+
+ //Get the file name with path
+ FilenameWithPathStr := '';
+ TempBEncodedInfoFilesPath :=
+ TempBEncodedInfoFilesData.Data.ListData.FindElement('path');
+ countPath := TempBEncodedInfoFilesPath.ListData.Count;
+ for x := 0 to countPath - 1 do
begin
- //Get the info.files node.
- TempBEncodedInfoFilesData := TempBEncodedInfoFiles.ListData.Items[i];
-
- //Get the file name with path
- FilenameWithPathStr := '';
- TempBEncodedInfoFilesPath :=
- TempBEncodedInfoFilesData.Data.ListData.FindElement('path');
- countPath := TempBEncodedInfoFilesPath.ListData.Count;
- for x := 0 to countPath - 1 do
- begin
- FilenameWithPathStr :=
- FilenameWithPathStr + DirectorySeparator +
- TempBEncodedInfoFilesPath.ListData.Items[x].Data.StringData;
- end;
-
-
- //Get the file length
- FileLength := TempBEncodedInfoFilesData.Data.ListData.FindElement(
- 'length').IntegerData;
-
- DecodeTorrentFileName := TDecodeTorrentFileNameAndLength.Create;
- DecodeTorrentFileName.Filename := FilenameWithPathStr;
- DecodeTorrentFileName.FileLength := FileLength;
- FObjectListFileNameAndLength.Add(DecodeTorrentFileName);
- //add it to the total sum of all files inside the torrent.
- Inc(FTotalFileSize, FileLength);
+ FilenameWithPathStr :=
+ FilenameWithPathStr + DirectorySeparator +
+ TempBEncodedInfoFilesPath.ListData.Items[x].Data.StringData;
end;
+
+ //Get the file length
+ FileLength := TempBEncodedInfoFilesData.Data.ListData.FindElement(
+ 'length').IntegerData;
+
+ DecodeTorrentFileName := TDecodeTorrentFileNameAndLength.Create;
+ DecodeTorrentFileName.Filename := FilenameWithPathStr;
+ DecodeTorrentFileName.FileLength := FileLength;
+ FObjectListFileNameAndLength.Add(DecodeTorrentFileName);
+ //add it to the total sum of all files inside the torrent.
+ Inc(FTotalFileSize, FileLength);
end;
- end
- else //there is no 'info.files' found. This is an 'one file' torrent.
- begin// Look for'info.name' and 'info.length'
- //Get the file name
- Filename := FBEncoded_Info.ListData.FindElement('name').StringData;
- FileLength := FBEncoded_Info.ListData.FindElement('length').IntegerData;
+ end;
+ end
+ else //there is no 'info.files' found. This is an 'one file' torrent.
+ begin// Look for'info.name' and 'info.length'
+ //Get the file name
+ Filename := FBEncoded_Info.ListData.FindElement('name').StringData;
- DecodeTorrentFileName := TDecodeTorrentFileNameAndLength.Create;
- DecodeTorrentFileName.Filename := Filename;
- DecodeTorrentFileName.FileLength := FileLength;
- FObjectListFileNameAndLength.Add(DecodeTorrentFileName);
+ FileLength := FBEncoded_Info.ListData.FindElement('length').IntegerData;
+ DecodeTorrentFileName := TDecodeTorrentFileNameAndLength.Create;
+ DecodeTorrentFileName.Filename := Filename;
+ DecodeTorrentFileName.FileLength := FileLength;
+ FObjectListFileNameAndLength.Add(DecodeTorrentFileName);
- Inc(FTotalFileSize, FileLength);
- end;
+
+ Inc(FTotalFileSize, FileLength);
+ end;
@@ -358,12 +370,12 @@ function TDecodeTorrent.DecodeTorrent: boolean;
//torrent file MUST begin with befDictionary.
if FBEncoded.Format <> befDictionary then
- exit; //error
+ exit; //error
//torrent MUST have 'info'
FBEncoded_Info := FBEncoded.ListData.FindElement('info');
if not assigned(FBEncoded_Info) then
- exit; //error
+ exit; //error
//Accept torrent only when there is no issue in reading AnnounceList and file list
@@ -372,13 +384,13 @@ function TDecodeTorrent.DecodeTorrent: boolean;
Result := True;
end;
- FInfoHash := GetInfoHash;
- FCreatedBy := GetCreatedBy;
- FCreatedDate := GetCreatedDate;
- FComment := GetComment;
- FName := GetName;
- FPieceLenght := GetPieceLenght;
- FPrivateTorrent:=GetPrivateTorrent;
+ FInfoHash := GetInfoHash;
+ FCreatedBy := GetCreatedBy;
+ FCreatedDate := GetCreatedDate;
+ FComment := GetComment;
+ FName := GetName;
+ FPieceLenght := GetPieceLenght;
+ FPrivateTorrent := GetPrivateTorrent;
except
end;
@@ -417,11 +429,12 @@ function TDecodeTorrent.GetPrivateTorrent: boolean;
procedure TDecodeTorrent.SetComment(const AValue: utf8string);
var
-// Encoded: TBEncoded;
+ // Encoded: TBEncoded;
Data: TBEncodedData;
begin
- if FComment=AValue then Exit;
- FComment:=AValue;
+ if FComment = AValue then
+ Exit;
+ FComment := AValue;
try
//if empty comment then remove the element.
if FComment = '' then
@@ -477,18 +490,18 @@ procedure TDecodeTorrent.RemovePrivateTorrentFlag;
procedure TDecodeTorrent.AddPrivateTorrentFlag;
var
- Encoded: TBEncoded;
+ Encoded: TBEncoded;
Data: TBEncodedData;
begin//remove the old one and create a new one
RemovePrivateTorrentFlag;
try
- Encoded := TBEncoded.Create;
- Encoded.Format := befInteger;
- Encoded.IntegerData := 1;
- Data := TBEncodedData.Create(Encoded);
- Data.Header := 'private';
- FBEncoded_Info.ListData.Add(Data);
- FBEncoded_Info.ListData.Sort(@sort_);//text must be in alfabetical order.
+ Encoded := TBEncoded.Create;
+ Encoded.Format := befInteger;
+ Encoded.IntegerData := 1;
+ Data := TBEncodedData.Create(Encoded);
+ Data.Header := 'private';
+ FBEncoded_Info.ListData.Add(Data);
+ FBEncoded_Info.ListData.Sort(@sort_);//text must be in alfabetical order.
except
end;
//read databack again
@@ -498,7 +511,7 @@ procedure TDecodeTorrent.AddPrivateTorrentFlag;
procedure TDecodeTorrent.RemoveAnnounce;
begin
try
- FBEncoded.ListData.RemoveElement('announce');
+ FBEncoded.ListData.RemoveElement('announce');
except
end;
end;
@@ -506,7 +519,7 @@ procedure TDecodeTorrent.RemoveAnnounce;
procedure TDecodeTorrent.RemoveAnnounceList;
begin
try
- FBEncoded.ListData.RemoveElement('announce-list');
+ FBEncoded.ListData.RemoveElement('announce-list');
except
end;
end;
@@ -542,13 +555,13 @@ procedure TDecodeTorrent.ChangeAnnounce(const TrackerURL: utf8string);
begin//remove the old one and create a new one
RemoveAnnounce;
try
- Encoded := TBEncoded.Create;
- Encoded.Format := befString;
- Encoded.StringData := TrackerURL;
- Data := TBEncodedData.Create(Encoded);
- Data.Header := 'announce';
- FBEncoded.ListData.Add(Data);
- FBEncoded.ListData.Sort(@sort_);//text must be in alfabetical order.
+ Encoded := TBEncoded.Create;
+ Encoded.Format := befString;
+ Encoded.StringData := TrackerURL;
+ Data := TBEncodedData.Create(Encoded);
+ Data.Header := 'announce';
+ FBEncoded.ListData.Add(Data);
+ FBEncoded.ListData.Sort(@sort_);//text must be in alfabetical order.
except
end;
end;
@@ -556,47 +569,45 @@ procedure TDecodeTorrent.ChangeAnnounce(const TrackerURL: utf8string);
procedure TDecodeTorrent.ChangeAnnounceList(StringList: TStringList);
var
EncodedListRoot, EncodedList, EncodedString: TBEncoded;
- Data, Data2, DataRootBEncodedData: TBEncodedData;
+ DataRootBEncodedData: TBEncodedData;
i: integer;
begin
//remove the present one.
RemoveAnnounceList;
+
//if there is nothing in the list then exit.
if StringList.Count = 0 then
Exit;
+
//create a new anounce list
try
- //Create the 'announce-list'
- EncodedListRoot := TBEncoded.Create;
- EncodedListRoot.Format := befList;
- EncodedListRoot.ListData := TBEncodedDataList.Create;
- DataRootBEncodedData := TBEncodedData.Create(EncodedListRoot);
- DataRootBEncodedData.Header := 'announce-list';
- FBEncoded.ListData.Add(DataRootBEncodedData); //root
-
- //Create list inside 'announce-list'
- // Str := TempBEncoded.ListData.Items[i].Data.ListData.First.Data.StringData;
-
- for i := 0 to StringList.Count - 1 do
- begin
- //create a list with string element
- EncodedList := TBEncoded.Create;
- EncodedList.Format := befList;
- EncodedList.ListData := TBEncodedDataList.Create;
- Data := TBEncodedData.Create(EncodedList);
- // add list to the list
- EncodedListRoot.ListData.Add(Data);
-
- //String ellement inside the list
- EncodedString := TBEncoded.Create;
- EncodedString.Format := befString;
- EncodedString.StringData := StringList[i];
- Data2 := TBEncodedData.Create(EncodedString);
-
- EncodedList.ListData.Add(DAta2);
- end;
+ //Create the 'announce-list'
+ EncodedListRoot := TBEncoded.Create;
+ EncodedListRoot.Format := befList;
+ DataRootBEncodedData := TBEncodedData.Create(EncodedListRoot);
+ DataRootBEncodedData.Header := 'announce-list';
+ FBEncoded.ListData.Add(DataRootBEncodedData); //root
- FBEncoded.ListData.Sort(@sort_);//text must be in alfabetical order.
+ //Create list inside 'announce-list'
+ // Str := TempBEncoded.ListData.Items[i].Data.ListData.First.Data.StringData;
+
+ for i := 0 to StringList.Count - 1 do
+ begin
+ //create a list with string element
+ EncodedList := TBEncoded.Create;
+ EncodedList.Format := befList;
+ // add list to the list via TBEncodedData
+ EncodedListRoot.ListData.Add(TBEncodedData.Create(EncodedList));
+
+ //String ellement inside the list
+ EncodedString := TBEncoded.Create;
+ EncodedString.Format := befString;
+ EncodedString.StringData := StringList[i];
+ // add string to the list via TBEncodedData
+ EncodedList.ListData.Add(TBEncodedData.Create(EncodedString));
+ end;
+
+ FBEncoded.ListData.Sort(@sort_);//text must be in alfabetical order.
except
end;
end;
@@ -606,8 +617,8 @@ function TDecodeTorrent.GetInfoHash: utf8string;
Result := '';
try
//The info.value will be hash with SHA1
- TBEncoded.Encode(FBEncoded_Info, Result);
- Result := UpperCase( SHA1Print(SHA1String(Result)));
+ TBEncoded.Encode(FBEncoded_Info, Result);
+ Result := UpperCase(SHA1Print(SHA1String(Result)));
except
end;
end;
@@ -618,9 +629,9 @@ function TDecodeTorrent.GetCreatedBy: utf8string;
begin
Result := '';
try
- TempBEncoded := FBEncoded.ListData.FindElement('created by');
- if assigned(TempBEncoded) then
- Result := TempBEncoded.StringData;
+ TempBEncoded := FBEncoded.ListData.FindElement('created by');
+ if assigned(TempBEncoded) then
+ Result := TempBEncoded.StringData;
except
end;
@@ -632,9 +643,9 @@ function TDecodeTorrent.GetCreatedDate: TDateTime;
begin
Result := 0; //Some torrent have no creation date
try
- TempBEncoded := FBEncoded.ListData.FindElement('creation date');
- if assigned(TempBEncoded) then
- Result := UnixToDateTime(TempBEncoded.IntegerData);
+ TempBEncoded := FBEncoded.ListData.FindElement('creation date');
+ if assigned(TempBEncoded) then
+ Result := UnixToDateTime(TempBEncoded.IntegerData);
except
end;
end;
@@ -643,9 +654,9 @@ function TDecodeTorrent.GetComment: utf8string;
begin
Result := '';
try
- FBEncoded_Comment := FBEncoded.ListData.FindElement('comment');
- if assigned(FBEncoded_Comment) then
- Result := UTF8Trim( FBEncoded_Comment.StringData);
+ FBEncoded_Comment := FBEncoded.ListData.FindElement('comment');
+ if assigned(FBEncoded_Comment) then
+ Result := UTF8Trim(FBEncoded_Comment.StringData);
except
end;
end;
@@ -657,7 +668,7 @@ function TDecodeTorrent.GetName: utf8string;
Result := '';
try
{find 'name' }
- TempBEncoded := FBEncoded_Info.ListData.FindElement('name');
+ TempBEncoded := FBEncoded_Info.ListData.FindElement('name');
if assigned(TempBEncoded) then
Result := TempBEncoded.StringData;
except
diff --git a/source/main.lfm b/source/main.lfm
index 9cb2541..4949e56 100644
--- a/source/main.lfm
+++ b/source/main.lfm
@@ -1,7 +1,7 @@
object FormTrackerModify: TFormTrackerModify
- Left = 635
+ Left = 743
Height = 607
- Top = 177
+ Top = 103
Width = 1179
AllowDropFiles = True
Caption = 'Bittorrent Tracker Editor'
@@ -16,7 +16,7 @@ object FormTrackerModify: TFormTrackerModify
OnDropFiles = FormDropFiles
OnShow = FormShow
Position = poScreenCenter
- LCLVersion = '1.2.6.0'
+ LCLVersion = '1.4.2.0'
object PageControl: TPageControl
Left = 0
Height = 587
@@ -301,7 +301,18 @@ object FormTrackerModify: TFormTrackerModify
object MenuUpdateTorrent: TMenuItem
Caption = '&Update torrent'
Hint = 'Update the torrent files'
- OnClick = MenuUpdateTorrentClick
+ object MenuUpdateTorrentAddBefore: TMenuItem
+ Caption = 'Add new trackers &Before original trackers (new trackers + original trackers)'
+ OnClick = MenuUpdateTorrentAddBeforeClick
+ end
+ object MenuUpdateTorrentAddAfter: TMenuItem
+ Caption = 'Add new trackers &After original trackers (original trackers + new trackers)'
+ OnClick = MenuUpdateTorrentAddAfterClick
+ end
+ object MenuUpdateTorrentSort: TMenuItem
+ Caption = '&Sort the trackers by name.'
+ OnClick = MenuUpdateTorrentSortClick
+ end
end
object MenuHelp: TMenuItem
Caption = '&Help'
diff --git a/source/main.pas b/source/main.pas
index 7972d9e..5388fc4 100644
--- a/source/main.pas
+++ b/source/main.pas
@@ -22,6 +22,10 @@ interface
type
+ //Updated torrent file trackers list order.
+ TTrackerListOrder = (tloInsertBefore, tloAppendAfter, tloSort);
+
+
{ TFormTrackerModify }
TFormTrackerModify = class(TForm)
@@ -37,6 +41,9 @@ TFormTrackerModify = class(TForm)
MenuFileTorrentFolder: TMenuItem;
MenuFileOpenTrackerList: TMenuItem;
MenuHelpReportingIssue: TMenuItem;
+ MenuUpdateTorrentSort: TMenuItem;
+ MenuUpdateTorrentAddAfter: TMenuItem;
+ MenuUpdateTorrentAddBefore: TMenuItem;
MenuItemTorrentFilesTreeHideAll: TMenuItem;
MenuItemTorrentFilesTreeShowTrackers: TMenuItem;
MenuItemTorrentFilesTreeShowInfo: TMenuItem;
@@ -92,7 +99,9 @@ TFormTrackerModify = class(TForm)
procedure MenuTrackersKeepOrDeleteAllTrackersClick(Sender: TObject);
//Menu update torrent
- procedure MenuUpdateTorrentClick(Sender: TObject);
+ procedure MenuUpdateTorrentAddAfterClick(Sender: TObject);
+ procedure MenuUpdateTorrentAddBeforeClick(Sender: TObject);
+ procedure MenuUpdateTorrentSortClick(Sender: TObject);
private
{ private declarations }
@@ -100,6 +109,8 @@ TFormTrackerModify = class(TForm)
FTrackerAddedByUserList, //Trackers that we want too add.
FTrackerBanByUserList, //trackers that must not be present inside torrent.
FTrackerFromInsideTorrentFilesList, //Trackers that are already inside the torrent.
+ FTrackerDeselectedByUserList, //trackers that must not be present inside torrent.
+
FTorrentFileNameList,// All the torrent files that must be updated
FLogStringList //Log string text output
: TStringList;
@@ -107,6 +118,10 @@ TFormTrackerModify = class(TForm)
FConcoleMode, //user have start the program in console mode
FFilePresentBanByUserList//There is a file 'remove_trackers.txt' detected
: boolean;
+
+ //The new trackers list order
+ FTrackerListOrderForUpdatedTorrent: TTrackerListOrder;
+
FLogFile, FTrackerFile: TextFile;
FTotalFileInsideTorrent: integer;
FTotalFileSizeInsideTorrent: int64;
@@ -114,6 +129,10 @@ TFormTrackerModify = class(TForm)
FTreeNodeRoot: TTreeNode;
FControlerGridTorrentData: TControlerGridTorrentData;
+ procedure RemoveTrackersFromList(RemoveList, UpdatedList: TStringList);
+ procedure UpdateTorrent;
+ procedure AddButIngnoreDuplicates(StringList: TStringList; const Str: UTF8String);
+
function ByteSizeToBiggerSizeFormatStr(ByteSize: int64): string;
procedure ShowHourGlassCursor(HourGlass: boolean);
@@ -136,7 +155,8 @@ TFormTrackerModify = class(TForm)
function DecodeTorrentFile(const FileName: UTF8String): boolean;
procedure UpdateTrackerInsideFileList;
procedure UpdateTorrentTrackerList;
- procedure CombineThreeTrackerListToOne;
+ procedure CombineFourTrackerListToOne;
+ procedure CombineFiveTrackerListToOne(TrackerListOrder: TTrackerListOrder);
procedure ShowTrackerInsideFileList;
procedure CheckedOnOffAllTrackers(Value: boolean);
@@ -206,25 +226,30 @@ procedure TFormTrackerModify.FormCreate(Sender: TObject);
FTrackerBanByUserList.Duplicates := dupIgnore;
FTrackerBanByUserList.Sorted := False;
+ //Create deselect tracker list where the user select via user interface checkbox
+ FTrackerDeselectedByUserList := TStringList.Create;
+ FTrackerDeselectedByUserList.Duplicates := dupIgnore;
+ FTrackerDeselectedByUserList.Sorted := False;
+
//Create tracker list where the user can manualy add items to it
FTrackerAddedByUserList := TStringList.Create;
FTrackerAddedByUserList.Duplicates := dupIgnore;
- //must be sorted. is visible to user.
+ //Trackers List added by user must keep in the same order.
+ FTrackerAddedByUserList.Sorted := False;
+
//drag and drop tracker list will accept duplicates in memo text, if false. Need to check out why.
- FTrackerAddedByUserList.Sorted := True;
//Create tracker list where all the trackers from all the torrent files are collected
FTrackerFromInsideTorrentFilesList := TStringList.Create;
FTrackerFromInsideTorrentFilesList.Duplicates := dupIgnore;
- //must be sorted. is visible to user. In tracker list tab page.
+ //Must be sorted. is visible to user. In tracker list tab page.
FTrackerFromInsideTorrentFilesList.Sorted := True;
- //Create tracker list that combine FTrackerFromInsideTorrentFilesList + FTrackerAddedByUserList together.
+ //Create tracker list that combine all other together.
FTrackerFinalList := TStringList.Create;
FTrackerFinalList.Duplicates := dupIgnore;
-
- //must be sorted. because we want to insert it in torrent files.
- FTrackerFinalList.Sorted := True;
+ //must NOT be sorted. Must keep the original order intact.
+ FTrackerFinalList.Sorted := False;
//Decoding class for torrent.
@@ -257,6 +282,7 @@ procedure TFormTrackerModify.FormDestroy(Sender: TObject);
FTrackerFromInsideTorrentFilesList.Free;
FTorrentFileNameList.Free;
FControlerGridTorrentData.Free;
+ FTrackerDeselectedByUserList.Free;
end;
procedure TFormTrackerModify.MenuFileTorrentFolderClick(Sender: TObject);
@@ -344,8 +370,10 @@ procedure TFormTrackerModify.MenuItemTorrentFilesTreeShowOrHideItemClick(
//The tag number define if it is for files, trackers or info items
itemsNr := TMenuItem(Sender).tag;
+
//Must show or hide the items
ShowNode := TMenuItem(Sender).Checked;
+
//process all the torrent files one by one.
for i := 0 to CountTorrents - 1 do
begin
@@ -361,14 +389,13 @@ procedure TFormTrackerModify.MenuItemTorrentFilesTreeShowOrHideItemClick(
end;
end;
-
-procedure TFormTrackerModify.MenuUpdateTorrentClick(Sender: TObject);
+procedure TFormTrackerModify.UpdateTorrent;
var
Reply, BoxStyle, i, CountTrackers: integer;
PopUpMenuStr: string;
begin
- //Update the all the torrent files.
+ //Update all the torrent files.
//The StringGridTorrentData where the comment are place by user
// must be in sync again with FTorrentFileNameList.
@@ -420,10 +447,19 @@ procedure TFormTrackerModify.MenuUpdateTorrentClick(Sender: TObject);
//There are 3 list that must be combine
//FTrackerFinalList := FTrackerAddedByUserList + FTrackerFromInsideTorrentFilesList
// - FTrackerBanByUserList
- CombineThreeTrackerListToOne;
+ CombineFourTrackerListToOne;
+
+ //for tloSort we only need to update the list one time for all the torrent files.
+ if FTrackerListOrderForUpdatedTorrent = tloSort then
+ begin
+ FTrackerFinalList.Sort;
+ end;
+
+ //How many trackers must be put inside each torrent file.
+ CountTrackers := FTrackerFinalList.Count;
//In console mode we can ignore this warning
- if not FConcoleMode and (FTrackerFinalList.Count = 0) then
+ if not FConcoleMode and (CountTrackers = 0) then
begin //Torrent without a tracker is posible. But is this what the user realy want? a DHT torrent.
BoxStyle := MB_ICONWARNING + MB_OKCANCEL;
Reply := Application.MessageBox(
@@ -438,9 +474,6 @@ procedure TFormTrackerModify.MenuUpdateTorrentClick(Sender: TObject);
ShowHourGlassCursor(True);
end;
- //How many trackers must be put inside each torrent file
- CountTrackers := FTrackerFinalList.Count;
-
//process all the files one by one.
//FTorrentFileNameList is not sorted it is still in sync with CheckListBoxPublicPrivateTorrent
for i := 0 to FTorrentFileNameList.Count - 1 do
@@ -450,6 +483,17 @@ procedure TFormTrackerModify.MenuUpdateTorrentClick(Sender: TObject);
if not FDecodePresentTorrent.DecodeTorrent(FTorrentFileNameList[i]) then
Continue;
+ //tloInsertBefore and tloAppendAfter need the list be updated or each torrent file.
+ if (FTrackerListOrderForUpdatedTorrent = tloInsertBefore) or
+ (FTrackerListOrderForUpdatedTorrent = tloAppendAfter) then
+ begin
+ //Add the new tracker before of after the original trackers inside the torrent.
+ CombineFiveTrackerListToOne(FTrackerListOrderForUpdatedTorrent);
+
+ //How many trackers must be put inside each torrent file
+ CountTrackers := FTrackerFinalList.Count;
+ end;
+
case CountTrackers of
0://if no tracker selected then delete 'announce' and 'announce-list'
begin
@@ -470,8 +514,6 @@ procedure TFormTrackerModify.MenuUpdateTorrentClick(Sender: TObject);
end;
end;
-
-
//update the torrent public/private flag
if CheckListBoxPublicPrivateTorrent.Checked[i] then
begin
@@ -524,6 +566,25 @@ procedure TFormTrackerModify.MenuUpdateTorrentClick(Sender: TObject);
end;
+procedure TFormTrackerModify.AddButIngnoreDuplicates(StringList: TStringList;
+ const Str: UTF8String);
+begin
+ //Stringlist that are not sorted must use IndexOf to ignore Duplicates.
+ if not StringList.Sorted then
+ begin
+ if StringList.IndexOf(Str) < 0 then
+ begin
+ StringList.add(Str);
+ end;
+ end
+ else
+ begin
+ StringList.add(Str);
+ end;
+
+end;
+
+
function TFormTrackerModify.ByteSizeToBiggerSizeFormatStr(ByteSize: int64): string;
begin
if ByteSize >= (1024 * 1024 * 1024) then
@@ -605,7 +666,8 @@ procedure TFormTrackerModify.ConsoleMode;
//Some tracker must be removed. Console and windows mode.
UpdateViewRemoveTracker;
//update torrent
- MenuUpdateTorrentClick(self);
+ FTrackerListOrderForUpdatedTorrent := tloSort;
+ UpdateTorrent;
end;
end
else //a torrent file is selected?
@@ -625,7 +687,8 @@ procedure TFormTrackerModify.ConsoleMode;
//Some tracker must be removed. Console and windows mode.
UpdateViewRemoveTracker;
//update torrent
- MenuUpdateTorrentClick(self);
+ FTrackerListOrderForUpdatedTorrent := tloSort;
+ UpdateTorrent;
finally
StringList.Free;
end;
@@ -719,7 +782,7 @@ procedure TFormTrackerModify.UpdateTorrentTrackerList;
begin
//Copy the trackers found in one torrent file to FTrackerFromInsideTorrentFilesList
for TrackerStr in FDecodePresentTorrent.TrackerList do
- FTrackerFromInsideTorrentFilesList.Add(TrackerStr);
+ AddButIngnoreDuplicates(FTrackerFromInsideTorrentFilesList, TrackerStr);
end;
procedure TFormTrackerModify.ShowTrackerInsideFileList;
@@ -754,7 +817,8 @@ procedure TFormTrackerModify.CheckedOnOffAllTrackers(Value: boolean);
function TFormTrackerModify.ValidTrackerURL(const TrackerURL: UTF8String): boolean;
begin
//TrackerURL should be cleanup with UTF8trim()
- Result := (Pos('http://', TrackerURL) = 1) or (Pos('https://', TrackerURL) = 1) or (Pos('udp://', TrackerURL) = 1);
+ Result := (Pos('http://', TrackerURL) = 1) or (Pos('https://', TrackerURL) = 1) or
+ (Pos('udp://', TrackerURL) = 1);
end;
function TFormTrackerModify.CopyUserInputNewTrackersToList: boolean;
@@ -778,7 +842,7 @@ function TFormTrackerModify.CopyUserInputNewTrackersToList: boolean;
//All the tracker must begin with 'http(s)://' or 'udp://'
if ValidTrackerURL(TrackerStr) then
begin
- FTrackerAddedByUserList.Add(TrackerStr);
+ AddButIngnoreDuplicates(FTrackerAddedByUserList, TrackerStr);
end
else
begin
@@ -793,7 +857,7 @@ function TFormTrackerModify.CopyUserInputNewTrackersToList: boolean;
Application.MessageBox(PChar(@TrackerStr[1]),
'Error: Tracker URL must begin with http(s):// or udp://', MB_ICONERROR);
end;
- //dot not continue with error.
+ //do not continue with error.
Result := False;
exit;
end;
@@ -808,31 +872,115 @@ function TFormTrackerModify.CopyUserInputNewTrackersToList: boolean;
end;
-
-
-procedure TFormTrackerModify.CombineThreeTrackerListToOne;
+procedure TFormTrackerModify.CombineFourTrackerListToOne;
var
TrackerStr: UTF8String;
- i: integer;
begin
- // FTrackerFinalList = (FTrackerAddedByUserList + FTrackerFromInsideTorrentFilesList)
- // - FTrackerBanByUserList
+ // FTrackerFinalList =
+ // (FTrackerAddedByUserList
+ // + FTrackerFromInsideTorrentFilesList)
+ // - FTrackerBanByUserList
+ // - FTrackerDeselectedByUserList
FTrackerFinalList.Clear;
for TrackerStr in FTrackerAddedByUserList do
- FTrackerFinalList.Add(TrackerStr);
+ AddButIngnoreDuplicates(FTrackerFinalList, TrackerStr);
for TrackerStr in FTrackerFromInsideTorrentFilesList do
- FTrackerFinalList.Add(TrackerStr);
+ AddButIngnoreDuplicates(FTrackerFinalList, TrackerStr);
- //Remove the trackers must be the last step.
- for TrackerStr in FTrackerBanByUserList do
- begin
- //Find the tracker and remove it from the list.
- //FTrackerBanByUserList is not UTF8Trim() before. Must use with UTF8Trim()
- i := FTrackerFinalList.IndexOf(UTF8Trim(TrackerStr));
- if i >= 0 then
- FTrackerFinalList.Delete(i);
+ //Trackers from FTrackerAddedByUserList overrule the one from FTrackerDeselectedByUserList
+ RemoveTrackersFromList(FTrackerAddedByUserList, FTrackerDeselectedByUserList);
+
+ //Remove the trackers that we do not want must be the last step.
+ RemoveTrackersFromList(FTrackerBanByUserList, FTrackerFinalList);
+ RemoveTrackersFromList(FTrackerDeselectedByUserList, FTrackerFinalList);
+
+end;
+
+procedure TFormTrackerModify.CombineFiveTrackerListToOne(
+ TrackerListOrder: TTrackerListOrder);
+var
+ TrackerStr: UTF8String;
+ TrackerFromInsideOneTorrentFile: TStringList;
+begin
+ //Must keep the original order of trackers inside the torrent file.
+ //The new trackers can be added at the begin of end of the list.
+
+ // FTrackerFinalList =
+ // (TrackerFromInsideOneTorrentFile
+ // + FTrackerAddedByUserList
+ // + FTrackerFromInsideTorrentFilesList)
+ // - FTrackerBanByUserList
+ // - FTrackerDeselectedByUserList
+
+
+ TrackerFromInsideOneTorrentFile := TStringList.Create;
+
+ try
+ //Begin with a empty list
+ FTrackerFinalList.Clear;
+
+ //Read the trackers inside the torrent file
+ //Copy the trackers found in one torrent file to TrackerFromInsideOneTorrentFile
+ for TrackerStr in FDecodePresentTorrent.TrackerList do
+ begin
+ AddButIngnoreDuplicates(TrackerFromInsideOneTorrentFile, TrackerStr);
+ end;
+
+ //Add the new tracker list before of after the original trackers list inside the torrent file.
+ case TrackerListOrder of
+
+ tloInsertBefore:
+ begin
+ //Before
+
+ //Must be place as first FTrackerAddedByUserList
+ for TrackerStr in FTrackerAddedByUserList do
+ AddButIngnoreDuplicates(FTrackerFinalList, TrackerStr);
+
+ //original tracker list is second place
+ for TrackerStr in TrackerFromInsideOneTorrentFile do
+ AddButIngnoreDuplicates(FTrackerFinalList, TrackerStr);
+
+ //'Others' trackers added as last.
+ for TrackerStr in FTrackerFromInsideTorrentFilesList do
+ AddButIngnoreDuplicates(FTrackerFinalList, TrackerStr);
+ end;
+
+ tloAppendAfter:
+ begin
+ //After
+
+ //original tracker list must be place first.
+ for TrackerStr in TrackerFromInsideOneTorrentFile do
+ AddButIngnoreDuplicates(FTrackerFinalList, TrackerStr);
+
+ //Must be place after TrackerFromInsideOneTorrentFile
+ for TrackerStr in FTrackerAddedByUserList do
+ AddButIngnoreDuplicates(FTrackerFinalList, TrackerStr);
+
+ //'Others' trackers added as last.
+ for TrackerStr in FTrackerFromInsideTorrentFilesList do
+ AddButIngnoreDuplicates(FTrackerFinalList, TrackerStr);
+
+ end;
+
+ else
+ begin
+ Assert(True, 'case else: Should never been called. CombineFourTrackerListToOne');
+ end;
+ end;
+
+ //Trackers from FTrackerAddedByUserList overrule the one from FTrackerDeselectedByUserList
+ RemoveTrackersFromList(FTrackerAddedByUserList, FTrackerDeselectedByUserList);
+
+ //Remove the trackers that we do not want must be the last step.
+ RemoveTrackersFromList(FTrackerBanByUserList, FTrackerFinalList);
+ RemoveTrackersFromList(FTrackerDeselectedByUserList, FTrackerFinalList);
+
+ finally
+ TrackerFromInsideOneTorrentFile.Free;
end;
end;
@@ -842,12 +990,31 @@ procedure TFormTrackerModify.UpdateTrackerInsideFileList;
i: integer;
begin
//Copy items from CheckListBoxTrackersList to FTrackerFromInsideTorrentFilesList
+ //Copy items from CheckListBoxTrackersList to FTrackerDeselectedByUserList
+
FTrackerFromInsideTorrentFilesList.Clear;
- with CheckListBoxTrackersList do
- if Count > 0 then
- for i := 0 to Count - 1 do
- if Checked[i] then
- FTrackerFromInsideTorrentFilesList.add(Items[i]);
+ FTrackerDeselectedByUserList.Clear;
+
+ if CheckListBoxTrackersList.Count > 0 then
+ begin
+ for i := 0 to CheckListBoxTrackersList.Count - 1 do
+ begin
+
+ if CheckListBoxTrackersList.Checked[i] then
+ begin
+ //Selected by user
+ AddButIngnoreDuplicates(FTrackerFromInsideTorrentFilesList,
+ CheckListBoxTrackersList.Items[i]);
+ end
+ else
+ begin
+ //Delected by user
+ AddButIngnoreDuplicates(
+ FTrackerDeselectedByUserList, CheckListBoxTrackersList.Items[i]);
+ end;
+
+ end;
+ end;
end;
procedure TFormTrackerModify.LoadTrackersTextFileAddTrackers;
@@ -983,6 +1150,43 @@ procedure TFormTrackerModify.MenuTrackersKeepOrDeleteAllTrackersClick(Sender: TO
CheckedOnOffAllTrackers(TMenuItem(Sender).Tag = 1);
end;
+procedure TFormTrackerModify.MenuUpdateTorrentAddAfterClick(Sender: TObject);
+begin
+ //User can select to add new tracker before after the original
+ FTrackerListOrderForUpdatedTorrent := tloAppendAfter;
+ UpdateTorrent;
+end;
+
+procedure TFormTrackerModify.MenuUpdateTorrentAddBeforeClick(Sender: TObject);
+begin
+ //User can select to add new tracker before after the original
+ FTrackerListOrderForUpdatedTorrent := tloInsertBefore;
+ UpdateTorrent;
+end;
+
+procedure TFormTrackerModify.MenuUpdateTorrentSortClick(Sender: TObject);
+begin
+ //User can select to add new tracker as sorted.
+ FTrackerListOrderForUpdatedTorrent := tloSort;
+ UpdateTorrent;
+end;
+
+procedure TFormTrackerModify.RemoveTrackersFromList(RemoveList,
+ UpdatedList: TStringList);
+var
+ TrackerStr: string;
+ i: integer;
+begin
+ //Remove the trackers that we do not want in the list
+ for TrackerStr in RemoveList do
+ begin
+ //Find the tracker and remove it from the list.
+ i := UpdatedList.IndexOf(UTF8Trim(TrackerStr));
+ if i >= 0 then
+ UpdatedList.Delete(i);
+ end;
+end;
+
function TFormTrackerModify.LoadTorrentViaDir(const Dir: UTF8String): boolean;
var
@@ -1018,9 +1222,12 @@ procedure TFormTrackerModify.FormDropFiles(Sender: TObject;
TorrentFileNameStringList, //for the torrent files
TrackerFileNameStringList //for the trackers files
: TStringList;
- TorrentFileSelectionDetected, ViewUpdateBeginActiveOneTimeOnly
+
+ TorrentFileSelectionDetected,
+
//ViewUpdateBegin must be called one time. Keep track of it.
- : boolean;
+ ViewUpdateBeginActiveOneTimeOnly: boolean;
+
FileNameOrDirStr: UTF8String;
begin
//Drag and drop a folder or files?
@@ -1431,7 +1638,7 @@ procedure TFormTrackerModify.ViewUpdateEnd;
procedure TFormTrackerModify.ViewUpdateFormCaption;
//var
- //ProcessTimeStr: string;
+//ProcessTimeStr: string;
// Hour, Minute, Second, MilliSecond: word;
begin
//Called when user load the torrent + update the torrent.
@@ -1460,9 +1667,6 @@ procedure TFormTrackerModify.ShowHourGlassCursor(HourGlass: boolean);
FProcessTimeTotal := now - FProcessTimeStart;
end;
-
-
-
end;
diff --git a/source/trackereditor.lpi b/source/trackereditor.lpi
index 9e400cc..7455455 100644
--- a/source/trackereditor.lpi
+++ b/source/trackereditor.lpi
@@ -9,7 +9,6 @@
-
@@ -35,17 +34,13 @@
-
+
-
-
-
-
+
-
@@ -53,44 +48,38 @@
-
-
-
-
-
+
+
+
+
+
-
-
-
+
-
-
-
+
-
-
+
-
-
-
-
+
+
+
@@ -98,549 +87,467 @@
-
-
-
-
+
+
+
-
-
-
+
+
-
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
-
+
-
-
+
-
-
-
-
+
-
-
-
+
-
-
+
-
-
+
-
-
-
+
+
-
-
-
-
+
-
-
-
+
+
-
-
+
-
-
+
-
-
+
-
-
-
-
+
+
-
-
+
-
-
-
-
+
+
+
+
+
-
-
-
-
+
+
+
+
+
-
-
-
+
+
-
-
+
-
-
+
-
-
+
-
-
-
+
+
-
-
-
+
-
-
-
-
+
-
-
+
-
-
+
-
-
+
-
-
-
+
+
-
-
-
+
+
-
-
+
-
-
-
+
-
-
-
-
-
+
+
+
+
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
-
+
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
-
+
-
-
+
-
-
-
-
-
-
-
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
-
-
+
+
-
-
+
+
-
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
@@ -658,8 +565,7 @@
-
-
+
@@ -669,12 +575,6 @@
-
-
-
-
-
-
@@ -689,5 +589,4 @@
-