diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
index 53e4e94..8e71c95 100644
--- a/.github/ISSUE_TEMPLATE.md
+++ b/.github/ISSUE_TEMPLATE.md
@@ -6,8 +6,16 @@
-### What version of the product are you using? On what operating system? ###
+### What version of the product are you using. (Please use the latest version of bittorrent-tracker-editor and your torrent client) ###
+
+
+
+### On what operating system? ###
### Please provide any additional information below. ###
+
+
+
+### Add a modified sintel torrent files example to reproduce the issue. [Download from Github: sintel](https://github.com/GerryFerdinandus/bittorrent-tracker-editor/tree/master/test_torrent) ###
diff --git a/.gitignore b/.gitignore
index 7ae3021..1a1906f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,9 +1,11 @@
# ignore possible temporary file added in the root
/*.txt
+# ignore bakup files
+*.bak
+
# folders generated by compiler. Should always be ignored.
/lib
#items in these folder should be added explicit
/enduser
-/source
diff --git a/.gitmodules b/.gitmodules
index 5db01de..71353b1 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +1,3 @@
[submodule "travis-lazarus"]
path = travis-lazarus
- url = https://github.com/nielsAD/travis-lazarus.git
+ url = https://github.com/GerryFerdinandus/travis-lazarus.git
diff --git a/.travis.yml b/.travis.yml
index 56e150f..b06d67e 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,47 +1,87 @@
# Part of `travis-lazarus` (https://github.com/nielsAD/travis-lazarus)
# License: MIT
-sudo: true
+language: shell
-os:
- - linux
- - osx
+# Linux compability issue.
+# Need to build in xenial with lazarus 1.8.2.
+# Do not use bionic or newer Lazarus version
-env:
- global:
- - LPIEDITORPATH=source/project/tracker_editor
- - WINEPREFIX=~/.winelaz
- - DISPLAY=:99.0
- matrix: #For linux and mac osx build
- - LAZ_VER=1.4.4
+# For linux headless.
+# See travis_unit_test.sh will install and use xvfb-run
+#services: (- xvfb) does not work must use xvfb-run
-matrix: #For windows build with linux wine. Use the same lazarus version as linux/mac build.
+jobs:
include:
- - os: linux
- env: LAZ_VER=1.4.4 LAZ_ENV=wine WINEARCH=win32 LAZ_OPT="--os=win32 --cpu=i386"
+ - name: Ubuntu 16.04 AMD64 (1.8.2)
+ os: linux
+ dist: xenial
+ env: LAZ_VER=1.8.2 RELEASE_ZIP_FILE="trackereditor_linux_amd64.zip"
+ - name: Ubuntu 16.04 AArch64 (1.6)
+ os: linux
+ dist: xenial
+ arch: arm64
+ env: LAZ_PKG=true RELEASE_ZIP_FILE="trackereditor_linux_AArch64.zip"
+ - name: macOS 10.14 (PKG)
+ os: osx
+ osx_image: xcode11.3
+ env: LAZ_PKG=true LAZ_OPT="--widgetset=cocoa" RELEASE_ZIP_FILE="trackereditor_macOS.zip"
+ - name: Windows (PKG) Build 32-bit software
+ os: windows
+ env: LAZ_PKG=true LAZ_REL=32 RELEASE_ZIP_FILE="trackereditor_win32.zip"
before_install:
- # Start virtual display server
- - sh -e /etc/init.d/xvfb start || true
+# Install python in windows OS
+- if [[ "$TRAVIS_OS_NAME" == "windows" ]]; then choco install python3 --params "/InstallDir:C:\python3"; fi
+- if [[ "$TRAVIS_OS_NAME" == "windows" ]]; then export PATH=/c/Python3:/c/Python3/Scripts:/c/lazarus:$PATH; fi
install:
- # Install prerequisites (fpc/lazarus/wine/qemu)
- - ./travis-lazarus/.travis.install.py
+# Output something at regular time or Travis will kills the job
+- while sleep 60; do echo "===== 1 minute mark ====="; done &
+- if [[ "$TRAVIS_OS_NAME" == "windows" ]]; then python ./travis-lazarus/.travis.install.py; fi
+- if [[ "$TRAVIS_OS_NAME" != "windows" ]]; then ./travis-lazarus/.travis.install.py; fi
+# Killing background sleep loop
+- kill %1
script:
- - lazbuild $LAZ_OPT $LPIEDITORPATH/trackereditor.lpi # Build trackereditor project
+# Output something at regular time or Travis will kill the job
+ - echo "start script"
+ - while sleep 60; do echo "===== 1 minute mark ====="; done &
+
+# Build trackereditor project (Release mode)
+ - lazbuild --build-mode=Release $LAZ_OPT $PROJECT_LPI_EDITOR_PATH
+
+# Build unit test project (Debug mode)
+ - lazbuild --build-mode=Debug $LAZ_OPT $PROJECT_LPI_UNIT_TEST_PATH
+
+# Start the unit test
+ - source ./scripts/travis_unit_test.sh
+
+# Killing background sleep loop
+ - kill %1
before_deploy:
+# Create the zip file for deployment
- source ./scripts/travis_deploy.sh
deploy:
- provider: releases
- prerelease: false
- skip_cleanup: true
- api_key:
- secure: "s2OquTSTFNECWme15GLuLHGykXQK9Q/ie38eI8wwzPZUQ3WCFJxYRGrR6XSaFWe/VfjNlDTfPaUsKfo4Fi9atOec1fp7ewA9JNnFUclw38o9UHirDYgzDNQD8BMhXXMaaxvYJBT+aN3CFvaBkkTyIb8jYO6RsvHfBQmOb6B//Fl2IFAgI/j8+qUKVtZWYEezGUCMCKZ+r/sFgfK91DsKtH7T51WVrJ9oI/HvvGISw6K1sG0X56LZry/shy8f3NPvGfFofooZ/9uPUamDmZwNR7YR91P10cykihZnarPDbCaCAD77D+AeFSDpcRyusr07dRfqIqNFQ1Hcu3GMIZL2W1dfGdZ9z0PJWQcMZQtwmjimV+2cEgIQTCvmG1wzbOTOW4T9QnDFB72M5njcxd1RYlVJwXq3SgSN1smQzRfArUd1bFeD0crGQ4urhfU12CJ50isgXXgXrOT7RclWUR2i1QISFS2ISDtGuCyh1vSGjVPQ9RSYSgG7/OufwdUXA/ZyK2mFpbZ0iKGNEYtZaL8/ZQMM9KlkyWPoQaSve/zTs+D3N5rFcOfQ7EHAAPTzz/fjpU7Yd3a0yf4pLSpr+ConVw1Kwc7d3VYSsoxhnLp2fgij+Xs/skRud8PLiOUsk8L3hUMS4p9X4ANkE181aQTAmzv7qc6qtXOSkhpzsIIxWGY="
- file: "${RELEASE_ZIP_FILE}"
- on:
- tags: true
- repo: GerryFerdinandus/bittorrent-tracker-editor
-
+ - provider: releases
+ prerelease: false
+ cleanup: false
+ edge: true # opt in to dpl v2
+ token:
+ secure: hmjev+YIClSOec6wMclUv5W4lgyLpdX7DlUpF2LQ1W/EO/x/b8RzmSPjNZ5sa7IDUe1WoVXm89G6HtkGGHcRqJrZjNn18HvpvEOnIYgIEXBVtW9uaURsSJ2LYve9beHHvYzs0doEQp1I24qTENUOqMABStk7MKRTATZ7nBWIinZVkpojEYIizQtCnUWwJXpzgs9mx7BEAVqLJPJ35oXNVjEgE96gsWMaYuX82BsVpL9VjGIaYpbEc1iBFBr2RHTgHG03H+2wBewJ4gh3hFwq9vt6mEqdC6Y9UIqmAEUMzCpokqrIfV2cfnPe24miPqmCLboua7Ddu8OpLj/yQ9DvC8xVEVh8aiGszzPvnytaFuRfLxI5HdAtUkA/9P3dXwjJKLJs568kyCTz4Tk7Icrb7seS1i84BJs3Vp2/lkmqDRDR0OqVGTczZGsxfTK+iaZJaNXb999BmGBw+xnPuG1lgrjHUYyEH2ha9D/9eOXiQfxdKUktPs1cF0II7uv5Cg3LEcFyN/A7jblNpM5B9cnf5kJ13lbpqL+Eyig90b9Q9YsrwGGOqtXJG+jSqXOv0O9/warFJfadA0avJljOFv4Pxl4tYe73EA/gP1GVG5UVC/F9nWZhUzP1kPCjzTzHoYBDCmHf8/GErdpCtibqRHoMIelrbcpe0jr+j5aNPxnTKAc=
+ file: "${RELEASE_ZIP_FILE}"
+ on:
+ tags: true
+ repo: GerryFerdinandus/bittorrent-tracker-editor
+ - provider: s3
+ access_key_id: $AWS_ACCESS_KEY
+ secret_access_key: $AWS_SECRET_KEY
+ bucket: "bittorrent-tracker-editor"
+ cleanup: false
+ region: eu-central-1
+ local_dir: s3
+ edge: true # opt in to dpl v2
+ on:
+ branch: to_be_deleted_unit_test
diff --git a/README.md b/README.md
index 41b9f78..0970bd1 100644
--- a/README.md
+++ b/README.md
@@ -1,78 +1,125 @@
**bittorrent-tracker-editor** will add/remove bittorrent tracker from the torrent file(s).
-This software works on Windows XP SP3, Windows 7+, Mac OS X and Linux.
+This software works on Windows XP SP3, Windows 7+, macOS and Linux.
---
-## Code Status: ##
-[](https://travis-ci.org/GerryFerdinandus/bittorrent-tracker-editor)
-for Windows, Mac OS X and Linux build.
+## Software latest release: ##
+[](https://github.com/GerryFerdinandus/bittorrent-tracker-editor/releases)
+
+---
+## Code Status: ##
+Continuous integration|Status| Build operating system
+------------|---------|---------
+Travis-CI |[](https://travis-ci.com/GerryFerdinandus/bittorrent-tracker-editor) |Linux, macOS and Windows
+Snapcraft-CI |[](https://build.snapcraft.io/user/GerryFerdinandus/bittorrent-tracker-editor)|Linux
---
## Warning: ##
-There is no backup function in this software. Used it at your own risk. Bittorrent work fine without this program. You probably don't need this software.
+There is no backup function in this software. Use it at your own risk. Bittorrent works fine without this program. You probably don't need this software.
---
## Which program to use for add/remove bittorrent trackers? ##
* **Edit one torrent file:** You can use http://torrenteditor.com/
- * **Edit multiple torrent file:** Use this program. It is made for changing multiple torrent files.
+ * **Edit multiple torrent files:** Use this program. It is made for changing multiple torrent files.
---
## Features: ##
* Select one torrent file or a folder with torrent files.
- * Add one or more tracker at the same time.
- * Remove one or more tracker at the same time.
- * Remove all the tracker to create tracker less torrent. DHT torrent
+ * Add one or more trackers at the same time.
+ * Remove one or more trackers at the same time.
+ * Remove all the trackers to create trackerless torrent. DHT torrent
* Change public/private flag. Warning: This will change the torrent info HASH.
- * Preset add/remove tracker via add\_trackers.txt and remove\_trackers.txt files when present in the same folder as the executable file.
+ * Preset add/remove tracker via add\_trackers.txt and remove\_trackers.txt files when present in the same folder as the executable file. (For linux snap version use: home/snap/bittorrent-tracker-editor/common/ )
* Optional start as console program. (See readme.txt inside download)
* Show torrent files content.
+ * Download stable trackers from newTrackon or ngosang.
---
## Downloads: ##
- * [From GitHub: Executable file for Windows, Mac OS X and Linux.](https://github.com/GerryFerdinandus/bittorrent-tracker-editor/releases)
+ * [From GitHub: Executable file for Windows, macOS and Linux.](https://github.com/GerryFerdinandus/bittorrent-tracker-editor/releases)
+ * [From GitHub: Trackers list (from GitHub user: ngosang )](https://github.com/ngosang/trackerslist)
+ * [From newtrackon.com: Trackers list (from GitHub user: CorralPeltzer )](https://newtrackon.com)
---
-## Software version ##
+## Software history: ##
+
+### 1.33.0.beta.6 ###
+ * ADD: Direct download support for ngosang via menu.
+ * ADD: Extra tabpage 'private torrent'. For issue 31 and 34
+ * ADD: Check box 'Skip Announce Check in the URL' ([Issue 31](https://github.com/GerryFerdinandus/bittorrent-tracker-editor/issues/31))
+ * ADD: Command parameter '-SAC' -> 'Skip Announce Check' in the URL ([Issue 31](https://github.com/GerryFerdinandus/bittorrent-tracker-editor/issues/31))
+ * ADD: Support 'Info Source' tag for private trackers ([Issue 34](https://github.com/GerryFerdinandus/bittorrent-tracker-editor/issues/34))
+ * ADD: Command parameter '-SOURCE' -> info Source tag for private trackers. See readme.txt file ([Issue 34](https://github.com/GerryFerdinandus/bittorrent-tracker-editor/issues/34))
+
+### 1.33.0.beta.5 ###
+ * FiX: support for '/announce.php'([Issue 27](https://github.com/GerryFerdinandus/bittorrent-tracker-editor/issues/27))
+
+### 1.33.0.beta.4 ###
+ * FIX: There was an issue with uploading tracker list to newTrackon.
+
+### 1.33.0.beta.3 ###
+ * FIX: WebTorrent do not have '/announce' ([Issue 24](https://github.com/GerryFerdinandus/bittorrent-tracker-editor/issues/24))
+
+### 1.33.0.beta.2 ###
+ * ADD: Wrong tracker URL format from torrent files should be unselected by default ([Issue 22](https://github.com/GerryFerdinandus/bittorrent-tracker-editor/issues/22))
+ * ADD: Upload trackers to newTrackon ([Issue 23](https://github.com/GerryFerdinandus/bittorrent-tracker-editor/issues/23))
+
+### 1.33.0.beta.1 ###
+ * ADD: Verify the working status of public trackers. (Data from newTrackon) ([Issue 21](https://github.com/GerryFerdinandus/bittorrent-tracker-editor/issues/21))
+
+### 1.32.0 ###
+ * ADD: Add more options for updating the torrent tracker list. ([Issue 8](https://github.com/GerryFerdinandus/bittorrent-tracker-editor/issues/8))
+ * ADD: Add trackers but keep the original unique trackers list intact. ([Issue 12](https://github.com/GerryFerdinandus/bittorrent-tracker-editor/issues/12))
+ * ADD: Randomize tracker order for each torrent file. ([Issue 19](https://github.com/GerryFerdinandus/bittorrent-tracker-editor/issues/19))
+ * FIX: Trackers with https ([Issue 9](https://github.com/GerryFerdinandus/bittorrent-tracker-editor/issues/9))
+ * FIX: Read torrent file with string size larger that 1MB ([Issue 10](https://github.com/GerryFerdinandus/bittorrent-tracker-editor/issues/10))
+ * FIX: Give user a warning when torrent file is read only file. ([Issue 14](https://github.com/GerryFerdinandus/bittorrent-tracker-editor/issues/14))
+ * FIX: Give user a warning when torrent file update failed. ([Issue 15](https://github.com/GerryFerdinandus/bittorrent-tracker-editor/issues/15))
+ * FIX: Can not be opened by dragging a file. ([Issue 17](https://github.com/GerryFerdinandus/bittorrent-tracker-editor/issues/17))
+ * FIX: Need sanitize URL tracker. ([Issue 18](https://github.com/GerryFerdinandus/bittorrent-tracker-editor/issues/18))
+ * FIX: WebSocket ws:// and wss:// should be accepted as input. ([Issue 20](https://github.com/GerryFerdinandus/bittorrent-tracker-editor/issues/20))
+
### 1.31 ###
- * Add: Edit comment in data/info grid column.
- * FIX: ([Issue 6](https://github.com/GerryFerdinandus/bittorrent-tracker-editor/issues/6))
+ * ADD: Edit comment in data/info grid column.
+ * FIX: The data/info column can be moved but it is not updated correctly when torrent is reloaded. ([Issue 6](https://github.com/GerryFerdinandus/bittorrent-tracker-editor/issues/6))
### 1.30 ###
- * Add: Tab page Files/trackers/info
- * Add: Optional start as console program. (See readme.txt inside download)
- * Add: remove\_trackers.txt will remove specific trackers form torrent.
- * Add: export\_trackers.txt is created after updating the torrent.
- * Add: drag and drop of trackers file (with '.txt' file extension)
- * FIX: ([Issue 4](https://github.com/GerryFerdinandus/bittorrent-tracker-editor/issues/4)) + ([Issue 5](https://github.com/GerryFerdinandus/bittorrent-tracker-editor/issues/5))
+ * ADD: Tab page Files/trackers/info
+ * ADD: Optional start as console program. (See readme.txt inside download)
+ * ADD: remove\_trackers.txt will remove specific trackers from torrent.
+ * ADD: export\_trackers.txt is created after updating the torrent.
+ * ADD: drag and drop of trackers file (with '.txt' file extension)
+ * FIX: Can not remove duplicate Tracker automatically ([Issue 4](https://github.com/GerryFerdinandus/bittorrent-tracker-editor/issues/4))
+ * FIX: Can't open some of .torrent files. ([Issue 5](https://github.com/GerryFerdinandus/bittorrent-tracker-editor/issues/5))
### 1.21 ###
* FIX: Support for Unicode in filename. (Chinese etc.)
### 1.20 ###
- * Add: Tab page torrent info/data.
- * Add: Drag & Drop torrent files or a folder with torrent files inside.
+ * ADD: Tab page torrent info/data.
+ * ADD: Drag & Drop torrent files or a folder with torrent files inside.
### 1.10 ###
- * Add: Tab page for public/private flag. ([Issue 1](https://github.com/GerryFerdinandus/bittorrent-tracker-editor/issues/1))
- * Add: Load tracker list from file via menu or at start-up, when file add\_trackers.txt is present in the same folder as the executable file.
+ * ADD: Tab page for public/private flag. ([Issue 1](https://github.com/GerryFerdinandus/bittorrent-tracker-editor/issues/1))
+ * ADD: Load tracker list from file via menu or at start-up, when file add\_trackers.txt is present in the same folder as the executable file.
### 1.00 ###
* First release
---
-
+
-This screen shot show the program, after a folder is selected with 97 torrent files inside. The normal procedure is to deselect the trackers that no longer working. Optionally add your one trackers. And press the 'Update torrent'
+This screen shot show the program, after a folder is selected with torrent files inside. The normal procedure is to deselect the trackers that are no longer working. Optionally add your own trackers. And select the 'Update torrent' menu.
---
-
+
---
@@ -82,3 +129,7 @@ This screen shot show the program, after a folder is selected with 97 torrent fi
---
This program is developed using [Lazarus](http://lazarus.freepascal.org/) RAD and [Free Pascal](http://www.freepascal.org/) compiler.
+
+---
+
+This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/)
diff --git a/SourceCodeBuild.txt b/SourceCodeBuild.txt
index 653e0b7..616f378 100644
--- a/SourceCodeBuild.txt
+++ b/SourceCodeBuild.txt
@@ -14,8 +14,9 @@ Executable file is created in the 'enduser' directory.
-------- Linux Ubuntu 14.04
sudo apt-get update
-sudo apt-get install lazarus -y
-cd source/project/tracker_editor/
-lazbuild trackereditor.lpi
+sudo apt-get install git lazarus -y
+cd ~
+git clone --recursive https://github.com/GerryFerdinandus/bittorrent-tracker-editor.git
+lazbuild bittorrent-tracker-editor/source/project/tracker_editor/trackereditor.lpi
Executable file is created in the 'enduser' directory.
diff --git a/enduser/add_trackers.txt b/enduser/add_trackers.txt
index f1d2079..b382aaf 100644
--- a/enduser/add_trackers.txt
+++ b/enduser/add_trackers.txt
@@ -1,4 +1,3 @@
-udp://tracker.openbittorrent.com:80/announce
-udp://tracker.publicbt.com:80/announce
-udp://tracker.istole.it:80/announce
-udp://open.demonii.com:1337/announce
+udp://tracker.coppersurfer.tk:6969/announce
+udp://tracker.opentrackr.org:1337/announce
+wss://tracker.openwebtorrent.com
diff --git a/enduser/libeay32.dll b/enduser/libeay32.dll
new file mode 100644
index 0000000..b66c6bb
Binary files /dev/null and b/enduser/libeay32.dll differ
diff --git a/enduser/trackereditor.app/Contents/Info.plist b/enduser/macos/app/trackereditor.app/Contents/Info.plist
similarity index 95%
rename from enduser/trackereditor.app/Contents/Info.plist
rename to enduser/macos/app/trackereditor.app/Contents/Info.plist
index 87de0ce..36c8919 100644
--- a/enduser/trackereditor.app/Contents/Info.plist
+++ b/enduser/macos/app/trackereditor.app/Contents/Info.plist
@@ -39,6 +39,8 @@
+ CFBundleIconFile
+ iconfile
NSHighResolutionCapable
diff --git a/enduser/trackereditor.app/Contents/MacOS/.gitkeep b/enduser/macos/app/trackereditor.app/Contents/MacOS/.gitkeep
similarity index 100%
rename from enduser/trackereditor.app/Contents/MacOS/.gitkeep
rename to enduser/macos/app/trackereditor.app/Contents/MacOS/.gitkeep
diff --git a/enduser/trackereditor.app/Contents/PkgInfo b/enduser/macos/app/trackereditor.app/Contents/PkgInfo
similarity index 100%
rename from enduser/trackereditor.app/Contents/PkgInfo
rename to enduser/macos/app/trackereditor.app/Contents/PkgInfo
diff --git a/enduser/macos/app/trackereditor.app/Contents/Resources/iconfile.icns b/enduser/macos/app/trackereditor.app/Contents/Resources/iconfile.icns
new file mode 100644
index 0000000..3120700
Binary files /dev/null and b/enduser/macos/app/trackereditor.app/Contents/Resources/iconfile.icns differ
diff --git a/enduser/macos/entitlements.plist b/enduser/macos/entitlements.plist
new file mode 100644
index 0000000..a046386
--- /dev/null
+++ b/enduser/macos/entitlements.plist
@@ -0,0 +1,12 @@
+
+
+
+
+ com.apple.security.app-sandbox
+
+ com.apple.security.files.user-selected.read-write
+
+ com.apple.security.network.client
+
+
+
diff --git a/enduser/readme.txt b/enduser/readme.txt
index 80e2508..2787c3d 100644
--- a/enduser/readme.txt
+++ b/enduser/readme.txt
@@ -4,14 +4,71 @@ If you do not want to use it this way, then just remove both the files 'add_trac
These '.txt' files must be place in the same directory as the program.
--------------------
+--- Linux usage example : 1 (public trackers)
+Update all the torrent files with only the latest tested stable tracker.
+
+curl https://newtrackon.com/api/stable --output add_trackers.txt
+echo > remove_trackers.txt
+./trackereditor ../test_torrent -U0
+
+Line 1: This will download the latest stable trackers into add_trackers.txt
+Line 2: Remove_trackers.txt is now a empty file. All trackers from the present torrent will be REMOVED.
+Line 3: Update all the torrent files inside the test_torrent folder.
+
+note -U0 parameter can be change to -U4 (sort by name)
+This is my prefer setting for the rtorrent client.
+rtorrent client announce to all the trackers inside the torrent file.
+I prefer to see all the trackers in alphabetical order inside rtorrent client console view.
+rtorrent client need to have the 'session' folder cleared and restart rtorrent to make this working.
+This can be run via regular cron job to keep the client running with 100% functional trackers.
+
+--- Linux usage example: 2 (public trackers)
+Mix the latest tested stable tracker with the present trackers already present inside the torrent files.
+
+curl https://raw.githubusercontent.com/ngosang/trackerslist/master/trackers_best.txt --output add_trackers.txt
+curl https://raw.githubusercontent.com/ngosang/trackerslist/master/blacklist.txt --output remove_trackers.txt
+./trackereditor ../test_torrent -U0
+
+Line 1: This will download the latest stable trackers into add_trackers.txt
+Line 2: Remove_trackers.txt now contain blacklisted trackers
+Line 3: Update all the torrent files inside the test_torrent folder.
+
+Diference betwean example 1 vs 2
+Example 1 is guarantee that all the trackers are working.
+Example 2 You are responseble for the trackers working that are not part of add_trackers.txt
+
+--- Linux usage example: 3 (private trackers)
+In add_trackers.txt file manualy the private tracker URL
+echo > remove_trackers.txt
+./trackereditor ../test_torrent -U0 -SAC -SOURCE "abcd"
+
+Line 2: Remove_trackers.txt is now a empty file. All trackers from the present torrent will be REMOVED.
+Line 3: Update all the torrent files inside the test_torrent folder.
+ -SAC (Skip Annouce Check) This is needed to skip private tracker URL check.
+ -SOURCE Add private tracker source tag "abcd"
+
+-SOURCE is optionally.
+-SOURCE "" Empty sting will remove all the source tag
+--------------------
+
+Usage example Windows desktop short cut for private tracker user.
+This is the same idea as "Usage example: 3 (private trackers)"
+But start it from the desktop shortcut (double click) and not from windows console via bat file etc.
+
+Desktop shortcut can have extra parameter append.
+C:\Users\root\Documents\github\bittorrent-tracker-editor\enduser\trackereditor.exe ..\test_torrent -U0 -SAC -SOURCE abc
-Console mode:
+Make sure that add_trackers.txt is filled with the private URL
+And remove_trackers.txt is a empty file.
+
+--------------------
+
+Console mode windows example:
Start program with a parameter to torrent file or dir
-trackereditor.exe "C:\dir\torrent\file.torrent"
-trackereditor.exe "C:\dir\torrent"
+trackereditor.exe "C:\dir\torrent\file.torrent" -U4
+trackereditor.exe "C:\dir\torrent" -U4
What tracker will be added/removed depend the content of the add_trackers.txt and remove_trackers.txt files.
---------------------
Additional Files: Trackers file and log file
These 3 files can be optionally present in the same dir as the trackereditor executable file.
@@ -64,7 +121,7 @@ no new tracker + remove some or all tracker inside torrent.
--------------------
Updated torrent file trackers list order with '-Ux' parameter.
-This is optional parameter. The default setting is -U4. The same as previous software version.
+This is a mandatory parameter.
trackereditor.exe "C:\dir\torrent" -U0
@@ -95,3 +152,9 @@ Console parameter: -U6
Append new trackers list AFTER, the original trackers list inside the torrent file.
Keep original tracker list unchanged and remove nothing.
+Console parameter: -U7
+ Randomize the trackers list.
+
+--------------------
+Acknowledgment:
+This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/)
diff --git a/enduser/ssleay32.dll b/enduser/ssleay32.dll
new file mode 100644
index 0000000..2ebf965
Binary files /dev/null and b/enduser/ssleay32.dll differ
diff --git a/enduser/trackereditor.app/Contents/Resources/.gitkeep b/enduser/trackereditor.app/Contents/Resources/.gitkeep
deleted file mode 100644
index e69de29..0000000
diff --git a/enduser/version.txt b/enduser/version.txt
index 3487df0..fd2f63b 100644
--- a/enduser/version.txt
+++ b/enduser/version.txt
@@ -1,3 +1,30 @@
+------ Version 1.33
+ADD: Verify the working status of public trackers. (Issue 21)
+ADD: Wrong tracker URL format from torrent files should be unselected by default (Issue 22)
+ADD: Upload trackers to newTrackon (Issue 23)
+FIX: WebTorrent do not have '/announce' (Issue 24)
+FiX: add support for '/announce.php'(Issue 27)
+ADD: Extra tabpage 'private torrent'. For issue 31 and 34
+ADD: Check box 'Skip Announce Check in the URL' (Issue 31)
+ADD: Command parameter '-SAC' -> 'Skip Announce Check' in the URL (Issue 31)
+ADD: Support 'Info Source' tag for private trackers (issue 34)
+ADD: Command parameter '-SOURCE' -> info Source tag for private trackers. See readme.txt file (issue 34)
+ADD: Direct download support for ngosang via menu (Issue 35)
+Compiler Lazarus: v2.04
+
+------ Version 1.32
+ADD: Add more options for updating the torrent tracker list. (Issue 8)
+ADD: Add trackers but keep the original unique trackers list instact. (Issue 12)
+ADD: Randomize tracker order for each torrent file. (Issue 19)
+FIX: Trackers with https (Issue 9)
+FIX: Read torrent file with string size langer that 1MB (Issue 10)
+FIX: Give user a warning when torrent file is read only file. (Issue 14)
+FIX: Give user a warning when torrent file update failed. (Issue 15)
+FIX: Can not be opened by dragging a file. (Issue 17)
+FIX: Need sanitize URL tracker. (Issue 18)
+FIX: WebSocket ws:// and wss:// should be accepted as input. (Issue 20)
+Compiler Lazarus: v1.62
+
------ Version 1.31
ADD: tab page 'Files/Trackers/Info' show how many files count in one torrent
ADD: tab page 'Files/Trackers/Info' show how many trackers count in one torrent
diff --git a/pictures/filestrackersinfo.png b/pictures/filestrackersinfo.png
new file mode 100644
index 0000000..e86897c
Binary files /dev/null and b/pictures/filestrackersinfo.png differ
diff --git a/pictures/trackereditor.png b/pictures/trackereditor.png
new file mode 100644
index 0000000..b562ab9
Binary files /dev/null and b/pictures/trackereditor.png differ
diff --git a/scripts/install_and_run_unit_test_in_desktop_ubuntu.sh b/scripts/install_and_run_unit_test_in_desktop_ubuntu.sh
new file mode 100644
index 0000000..5b5202b
--- /dev/null
+++ b/scripts/install_and_run_unit_test_in_desktop_ubuntu.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+
+# for local testing of the project in Ubuntu 14.04 (via VirtualBox)
+
+#create download folder 'download_FPC'
+cd ~
+mkdir download_FPC
+cd download_FPC
+
+#download the FPC + lazarus IDE (1.6.2)
+wget http://mirrors.iwi.me/lazarus/releases/Lazarus%20Linux%20amd64%20DEB/Lazarus%201.6.2/fpc_3.0.0-151205_amd64.deb
+wget http://mirrors.iwi.me/lazarus/releases/Lazarus%20Linux%20amd64%20DEB/Lazarus%201.6.2/fpc-src_3.0.0-151205_amd64.deb
+wget http://mirrors.iwi.me/lazarus/releases/Lazarus%20Linux%20amd64%20DEB/Lazarus%201.6.2/lazarus-project_1.6.2-1_amd64.deb
+
+#Install the downloaded FPC + lazarus IDE
+sudo dpkg -i ./*.deb
+#install all the software dependency it needed
+sudo apt install -f -y
+
+#install git
+sudo apt-get install git -y
+
+#Download the source code in the home folder
+cd ~
+git clone --recursive https://github.com/GerryFerdinandus/bittorrent-tracker-editor.git
+
+#build the source code trackereditor. (optional: --build-mode=Release)
+lazbuild --build-mode=Debug bittorrent-tracker-editor/source/project/tracker_editor/trackereditor.lpi
+
+#build the source code tracker_editor_test
+lazbuild --build-mode=Debug bittorrent-tracker-editor/source/project/unit_test/tracker_editor_test.lpi
+
+#Run the unit test
+./bittorrent-tracker-editor/enduser/test_trackereditor -a --format=plain
+
+
+
+
+
+
diff --git a/scripts/travis_add_macos_cert.sh b/scripts/travis_add_macos_cert.sh
new file mode 100755
index 0000000..9ad919c
--- /dev/null
+++ b/scripts/travis_add_macos_cert.sh
@@ -0,0 +1,36 @@
+#!/usr/bin/env sh
+
+#must run on griet server only
+if [ -z "${TRAVIS}" ]
+then
+ echo "This is not TRAVIS CI build server "
+ exit 1
+fi
+
+# secure/hidden variable from travis
+# CERTIFICATE_OSX_P12
+# CERTIFICATE_PASSWORD
+
+
+# constant variable
+KEY_CHAIN=build.keychain
+CERTIFICATE_P12=certificate.p12
+
+# Recreate the certificate from the secure environment variable
+echo $CERTIFICATE_OSX_P12 | base64 --decode > $CERTIFICATE_P12
+
+# create a keychain
+security create-keychain -p travis $KEY_CHAIN
+
+# Make the keychain the default so identities are found
+security default-keychain -s $KEY_CHAIN
+
+# Unlock the keychain
+security unlock-keychain -p travis $KEY_CHAIN
+
+security import $CERTIFICATE_P12 -k $KEY_CHAIN -P $CERTIFICATE_PASSWORD -T /usr/bin/codesign;
+
+security set-key-partition-list -S apple-tool:,apple: -s -k travis $KEY_CHAIN
+
+# remove certs
+rm -fr *.p12
diff --git a/scripts/travis_deploy.sh b/scripts/travis_deploy.sh
index 9c89af3..dcaf45c 100644
--- a/scripts/travis_deploy.sh
+++ b/scripts/travis_deploy.sh
@@ -1,48 +1,36 @@
-#!/bin/bash
+#!/bin/sh
-#Create a zip file for Windows, Linux and Apple OS X
+# Create a zip file for Windows, Linux and macOS.
-#this will be set later
-unset RELEASE_ZIP_FILE
-
-#----------- check for Windows, Linux and Apple OS X build
+#----------- check for Windows, Linux and macOS build
if [ "$TRAVIS_OS_NAME" = "linux" ]
then
-
- #wine = windows
- if [ "$LAZ_ENV" = "wine" ]
- then
-
- #windows
- export RELEASE_ZIP_FILE="trackereditor_win32.zip"
- zip -j $RELEASE_ZIP_FILE enduser/*.txt enduser/trackereditor.exe
-
- else
-
- #linux
- export RELEASE_ZIP_FILE="trackereditor_linux_amd64.zip"
+ # Linux
+ sudo apt-get install zip -y
+ echo "Building zip file for Linux amd64"
zip -j $RELEASE_ZIP_FILE enduser/*.txt enduser/trackereditor
- fi
-
elif [ "$TRAVIS_OS_NAME" = "osx" ]
then
- #Apple os x
- export RELEASE_ZIP_FILE="trackereditor_os_x.zip"
- cd enduser
-
- #move the executable to the application bundle
- mv trackereditor trackereditor.app/Contents/MacOS
+ # Apple macOS
+ echo "Building zip file for macOS"
- #move the trackers list to application bundle
- mv add_trackers.txt trackereditor.app/Contents/MacOS
- mv remove_trackers.txt trackereditor.app/Contents/MacOS
+ # Add certificate into the macOS system
+ source ./scripts/travis_add_macos_cert.sh
- #Create the zip file.
- zip -j ../$RELEASE_ZIP_FILE *.txt
- zip -r ../$RELEASE_ZIP_FILE trackereditor.app
- cd ..
+ # sign + zip the app
+ source ./scripts/travis_sign_macos_app.sh
+elif [ "$TRAVIS_OS_NAME" = "windows" ]
+then
+ # Windows
+ echo "Building zip file for windows"
+ choco install zip
+ zip -j $RELEASE_ZIP_FILE enduser/*.txt enduser/trackereditor.exe enduser/*.dll
fi
+echo "Create Amazon s3 folder"
+mkdir -p s3
+cp $RELEASE_ZIP_FILE s3/$(date +%F_%R)_$RELEASE_ZIP_FILE
+
echo "Created $RELEASE_ZIP_FILE for GitHub"
diff --git a/scripts/travis_sign_macos_app.sh b/scripts/travis_sign_macos_app.sh
new file mode 100755
index 0000000..b38796a
--- /dev/null
+++ b/scripts/travis_sign_macos_app.sh
@@ -0,0 +1,142 @@
+#!/usr/bin/env sh
+
+# secure/hidden variable from travis
+#CERTIFICATE_ID="..."
+#USERNAME="..."
+#APP_SPECIFIC_PASSWORD="..."
+#RELEASE_ZIP_FILE="..."
+
+# path to app
+FILE_APP='enduser/macos/app/trackereditor.app'
+PLISTBUDDY_APP='/usr/libexec/PlistBuddy'
+
+if [ ! -x "${PLISTBUDDY_APP}" ]
+then
+ echo "Couldn't find PlistBuddy"
+ exit 1
+fi
+
+# copy everything into enduser/macos/app folder
+#
+# Move the executable to the application bundle
+mv enduser/trackereditor enduser/macos/app/trackereditor.app/Contents/MacOS
+
+# Move the trackers list to application bundle
+mv enduser/add_trackers.txt enduser/macos/app/trackereditor.app/Contents/MacOS
+mv enduser/remove_trackers.txt enduser/macos/app/trackereditor.app/Contents/MacOS
+
+# move all the *.txt file
+mv enduser/*.txt enduser/macos/app
+
+# sign the app. -sign is the developer cetificate ID
+# entitlements does not work at this moment
+#codesign --timestamp --entitlements enduser/macos/entitlements.plist --force --options runtime --deep --sign $CERTIFICATE_ID $FILE_APP
+codesign --timestamp --force --options runtime --deep --sign $CERTIFICATE_ID $FILE_APP
+
+# Check exit code
+exit_code=$?
+if [ "${exit_code}" != "0" ]
+then
+ echo "codesign failed: ${exit_code}"
+ exit 1
+fi
+
+#must use ditto to compress the file application folder only for notarize. Zip program will not work!
+/usr/bin/ditto -c -k --keepParent "$FILE_APP" "$RELEASE_ZIP_FILE"
+
+# upload zip to notarize service. for RequestUUID
+# -- username is the normal apple ID. example myname@mail.com
+# -- password is 'app specific password' generated via apple web site. Security -> app-specific password
+echo "Uploading to notarize server"
+xcrun altool --notarize-app --output-format xml --primary-bundle-id "trackereditor" --username $USERNAME --password $APP_SPECIFIC_PASSWORD --file $RELEASE_ZIP_FILE > "result.plist"
+
+# remove the uploaded zip file. need to be created again later.
+rm $RELEASE_ZIP_FILE
+
+
+# Check exit code
+exit_code=$?
+if [ "${exit_code}" != "0" ]
+then
+ echo "notarize-app failed: ${exit_code}"
+ cat "result.plist"
+ exit 1
+fi
+
+# Get the RequestUUID
+RequestUUID="$("${PLISTBUDDY_APP}" -c "Print notarization-upload:RequestUUID" "result.plist")"
+echo "RequestUUID: ${RequestUUID}"
+
+# wait till notarize apple server is finish with the processing the zip upload.
+for (( ; ; ))
+do
+
+ # get status from apple notarize server
+ xcrun altool --output-format xml --notarization-info "${RequestUUID}" -u $USERNAME -p $APP_SPECIFIC_PASSWORD > "result.plist"
+ # Check exit code
+ exit_code=$?
+ if [ "${exit_code}" != "0" ]
+ then
+ echo "notarization-info failed: ${exit_code}"
+ cat "result.plist"
+ # print the error in the URL
+ LogFileURL="$("${PLISTBUDDY_APP}" -c "Print notarization-info:LogFileURL" "result.plist")"
+ if [ ! -z "${LogFileURL}" ]
+ then
+ curl "${LogFileURL}"
+ fi
+ exit 1
+ fi
+
+ # get the status.
+ StatusCode="$("${PLISTBUDDY_APP}" -c "Print notarization-info:Status" "result.plist")"
+ echo "Status: ${StatusCode}"
+
+ # if no status code present in result then it is still busy
+ if [ "${StatusCode}" == "in progress" ]
+ then
+ sleep 15
+ else
+ echo "Finish waiting."
+ #cat "result.plist"
+ # Check if everything is correct
+ StatusCode="$("${PLISTBUDDY_APP}" -c "Print notarization-info:'Status Code'" "result.plist")"
+ echo "Status code: ${StatusCode}"
+ if [ "${StatusCode}" == "0" ]
+ then
+ # there are no error.
+ break
+ else
+ # print the error in the URL
+ LogFileURL="$("${PLISTBUDDY_APP}" -c "Print notarization-info:LogFileURL" "result.plist")"
+ if [ ! -z "${LogFileURL}" ]
+ then
+ curl "${LogFileURL}"
+ fi
+ exit 1
+ fi
+ fi
+done
+
+# verify sign *.app is succes full
+spctl --assess --type execute --verbose $FILE_APP
+# Check exit code
+exit_code=$?
+if [ "${exit_code}" != "0" ]
+then
+ echo "spctl failed: ${exit_code}"
+ exit 1
+fi
+
+# staple the *.app
+xcrun stapler staple $FILE_APP
+# Check exit code
+exit_code=$?
+if [ "${exit_code}" != "0" ]
+then
+ echo "spctl stapler: ${exit_code}"
+ exit 1
+fi
+
+# zip only the app folder with extra text file.
+/usr/bin/ditto -c -k "enduser/macos/app" "$RELEASE_ZIP_FILE"
diff --git a/scripts/travis_unit_test.sh b/scripts/travis_unit_test.sh
new file mode 100644
index 0000000..33772eb
--- /dev/null
+++ b/scripts/travis_unit_test.sh
@@ -0,0 +1,47 @@
+#!/bin/sh
+
+# Run unit test in Windows, Linux and macOS
+
+#----------- check for Windows, Linux and macOS build
+if [ "$TRAVIS_OS_NAME" = "linux" ]
+then
+ # show Linux OS version
+ uname -a
+
+ # show openSSL version
+ openssl version
+
+ # Exit immediately if a command exits with a non-zero status.
+ set -e
+ xvfb-run enduser/test_trackereditor -a --format=plain
+ set +e
+
+elif [ "$TRAVIS_OS_NAME" = "osx" ]
+then
+ # show macOS version
+ sw_vers
+
+ # show openSSL version
+ openssl version
+
+ # Exit immediately if a command exits with a non-zero status.
+ set -e
+ enduser/test_trackereditor -a --format=plain
+ set +e
+
+elif [ "$TRAVIS_OS_NAME" = "windows" ]
+then
+ # Exit immediately if a command exits with a non-zero status.
+ set -e
+ enduser/test_trackereditor.exe -a --format=plain
+ set +e
+fi
+
+
+# Remove all the extra file created by test
+# We do not what it in the ZIP release files.
+rm -f enduser/console_log.txt
+rm -f enduser/export_trackers.txt
+
+# Undo all changes made by testing.
+git reset --hard
diff --git a/snap/gui/bittorrent-tracker-editor.desktop b/snap/gui/bittorrent-tracker-editor.desktop
new file mode 100644
index 0000000..a6cc131
--- /dev/null
+++ b/snap/gui/bittorrent-tracker-editor.desktop
@@ -0,0 +1,10 @@
+[Desktop Entry]
+Version=1.0
+Name=Bittorrent tracker editor
+Comment=Software for add or remove tracker from torrent files.
+Exec=bittorrent-tracker-editor
+Icon=${SNAP}/meta/gui/bittorrent-tracker-editor.png
+Terminal=false
+Type=Application
+Categories=Utility;
+Keywords=bittorrent;tracker;editor;
diff --git a/snap/gui/bittorrent-tracker-editor.png b/snap/gui/bittorrent-tracker-editor.png
new file mode 100644
index 0000000..392dbf6
Binary files /dev/null and b/snap/gui/bittorrent-tracker-editor.png differ
diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml
new file mode 100644
index 0000000..001b96f
--- /dev/null
+++ b/snap/snapcraft.yaml
@@ -0,0 +1,114 @@
+name: bittorrent-tracker-editor
+version: '1.33.0'
+base: core18
+summary: Software for add or remove tracker from torrent files.
+description: |
+ Features:
+ - Select one torrent file or a folder with torrent files.
+ - Add one or more trackers at the same time.
+ - Remove one or more trackers at the same time.
+ - Remove all the trackers to create trackerless torrent. DHT torrent
+ - Change public/private flag. Warning: This will change the torrent info HASH.
+ - Preset add/remove tracker via add_trackers.txt and remove_trackers.txt files.
+ - Optional start as console program.
+ - Show torrent files content.
+ - Download stable trackers from newTrackon or ngosang
+grade: stable
+confinement: strict
+
+architectures:
+ - build-on: amd64
+ - build-on: i386
+ - build-on: arm64
+ - build-on: armhf
+
+apps:
+ bittorrent-tracker-editor:
+ command: desktop-launch $SNAP/app/trackereditor
+ environment:
+ # Fallback to XWayland if running in a Wayland session.
+ DISABLE_WAYLAND: 1
+ plugs:
+ - desktop
+ - desktop-legacy
+ - x11
+ - unity7
+ - home
+ - network
+ - wayland
+ - removable-media
+
+build-packages:
+ - fpc
+ - fpc-source
+ - lcl-nogui
+ - lazarus
+
+parts:
+ bittorrent-tracker-editor:
+ source: https://github.com/GerryFerdinandus/bittorrent-tracker-editor.git
+ plugin: nil
+ override-build: |
+ snapcraftctl build
+ lazbuild --build-mode=Release --widgetset=gtk2 source/project/tracker_editor/trackereditor.lpi
+ mkdir $SNAPCRAFT_PART_INSTALL/app
+ mv enduser/trackereditor $SNAPCRAFT_PART_INSTALL/app
+ stage-packages:
+ - libcanberra-gtk-module
+ - openssl
+ - libgail-common
+ - libatk-adaptor
+ - overlay-scrollbar-gtk2
+ after:
+ - desktop-gtk2
+
+ # This part installs the `desktop-launch` script which initialises desktop
+ # features such as fonts, themes and the XDG environment. It also installs
+ # the GTK2 runtime libraries.
+ #
+ # It is copied straight from the snapcraft desktop helpers project. Please
+ # periodically check the source for updates and copy the changes.
+ # https://github.com/ubuntu/snapcraft-desktop-helpers/blob/master/snapcraft.yaml
+ #
+ desktop-gtk2:
+ source: https://github.com/ubuntu/snapcraft-desktop-helpers.git
+ source-subdir: gtk
+ plugin: make
+ make-parameters: ["FLAVOR=gtk2"]
+ build-packages:
+ - libgtk2.0-dev
+ stage-packages:
+ - libxkbcommon0 # XKB_CONFIG_ROOT
+ - ttf-ubuntu-font-family
+ - dmz-cursor-theme
+ - light-themes
+ - adwaita-icon-theme
+ - gnome-themes-standard
+ - shared-mime-info
+ - libgtk2.0-0
+ - libgdk-pixbuf2.0-0
+ - libglib2.0-bin
+ - libgtk2.0-bin
+ - unity-gtk2-module
+ - libappindicator1
+ - locales-all
+ - ibus-gtk
+ - libibus-1.0-5
+
+plugs:
+ gtk-2-engines:
+ interface: content
+ target: $SNAP/lib/gtk-2.0
+ default-provider: gtk2-common-themes
+ gtk-2-themes:
+ interface: content
+ target: $SNAP/data-dir/themes
+ default-provider: gtk-common-themes
+ icon-themes:
+ interface: content
+ target: $SNAP/data-dir/icons
+ default-provider: gtk-common-themes
+ sound-themes:
+ interface: content
+ target: $SNAP/data-dir/sounds
+ default-provider: gtk-common-themes
diff --git a/source/code/bencode.pas b/source/code/bencode.pas
index 3626c2c..715a16a 100644
--- a/source/code/bencode.pas
+++ b/source/code/bencode.pas
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: CC0-1.0
{
public domain code?
Source code from:
@@ -33,7 +34,7 @@ TBEncoded = class;
TBEncodedData = class
public
- Header: string;
+ Header: UTF8String;
Data: TBEncoded;
destructor Destroy; override;
public
@@ -47,13 +48,13 @@ TBEncodedDataList = class(TObjectList)
function GetItems(Index: Integer): TBEncodedData;
procedure SetItems(Index: Integer; AClass: TBEncodedData);
public
- function FindElement(Header: string): TBEncoded;
+ function FindElement(Header: UTF8String): TBEncoded;
function Add(AClass: TBEncodedData): Integer;
function Extract(Item: TBEncodedData): TBEncodedData;
function Remove(AClass: TBEncodedData): Integer;
function IndexOf(AClass: TBEncodedData): Integer;
- function RemoveElement(Header: string): integer;//2011-1030
+ function RemoveElement(Header: UTF8String): integer;//2011-1030
function First: TBEncodedData;
function Last: TBEncodedData;
@@ -67,11 +68,11 @@ TBEncoded = class(TObject)
FFormat: TBEncodedFormat;
procedure SetFormat(Format: TBEncodedFormat);
public
- StringData: string;
+ StringData: UTF8String;
IntegerData: int64;
ListData: TBEncodedDataList;
property Format: TBEncodedFormat read FFormat write SetFormat;
- class procedure Encode(Encoded: TBEncoded; var Output: string);
+ class procedure Encode(Encoded: TBEncoded; var Output: UTF8String);
destructor Destroy; override;
constructor Create(Stream: TStream);
constructor Create;
@@ -237,7 +238,7 @@ constructor TBEncoded.Create;
inherited Create;
end;
-class procedure TBEncoded.Encode(Encoded: TBEncoded; var Output: string);
+class procedure TBEncoded.Encode(Encoded: TBEncoded; var Output: UTF8String);
var
i: integer;
begin
@@ -277,7 +278,7 @@ procedure TBEncoded.SetFormat(Format: TBEncodedFormat);
FFormat := Format;
end;
-function TBEncodedDataList.FindElement(Header: string): TBEncoded;
+function TBEncodedDataList.FindElement(Header: UTF8String): TBEncoded;
var
i: integer;
begin
@@ -317,7 +318,7 @@ function TBEncodedDataList.IndexOf(AClass: TBEncodedData): Integer;
Result := inherited IndexOf(AClass);
end;
-function TBEncodedDataList.RemoveElement(Header: string): Integer;
+function TBEncodedDataList.RemoveElement(Header: UTF8String): Integer;
var
i: integer;
begin
diff --git a/source/code/controler_trackerlist_online.pas b/source/code/controler_trackerlist_online.pas
new file mode 100644
index 0000000..431fb4e
--- /dev/null
+++ b/source/code/controler_trackerlist_online.pas
@@ -0,0 +1,202 @@
+// SPDX-License-Identifier: MIT
+unit controler_trackerlist_online;
+
+{
+ Show the present status of the trackerURL via TStringGrid
+}
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils, Grids, trackerlist_online, newtrackon;
+
+type
+
+ TDefaultChecked = function(const TrackerURL: UTF8String): boolean of object;
+
+ { TControlerTrackerListOnline }
+
+ TControlerTrackerListOnline = class
+ private
+ FStringGridTorrentURL: TStringGrid;
+ FNewTrackon: TNewTrackon;
+ FTrackerListOnline: TTrackerListOnline;
+ FTrackerList: TStringList;
+ FDefaultChecked: TDefaultChecked;
+
+ //The collumn must be in this design order.
+ FSelect, //< 0
+ FTorrentURL, //< 1
+ FTorrentURL_Status //< 2
+ : TGridColumn;
+
+ function GetChecked(index: integer): boolean;
+ procedure SetChecked(index: integer; AValue: boolean);
+ procedure ShowTrackerStatus(Visible: boolean);
+ procedure AppendRow(Checked: boolean; Status: TTrackerListOnlineStatus;
+ const TrackerURL: UTF8String);
+ public
+ property Checked[index: integer]: boolean read GetChecked write SetChecked;
+ function TrackerURL(index: integer): string;
+ function TrackerStatus(index: integer): TTrackerListOnlineStatus;
+ function Count: integer;
+ function StableTrackers: TStringList;
+
+ //must be called if the tracker list is updated
+ procedure UpdateView;
+
+ function DownloadTrackers_All_Live_Stable: boolean;
+
+ //Submit tracker to newTrackon via http POST
+ function SubmitTrackers(TrackerList: TStringList;
+ out TrackersSendCount: integer): boolean;
+
+ constructor Create(StringGridTorrentURL: TStringGrid; TrackerList: TStringList;
+ DefaultChecked: TDefaultChecked);
+ destructor Destroy; override;
+ end;
+
+
+implementation
+
+uses Graphics;
+
+{ TControlerTrackerListOnline }
+
+
+function TControlerTrackerListOnline.DownloadTrackers_All_Live_Stable: boolean;
+begin
+ Result := FNewTrackon.Download_All_Live_Stable;
+ UpdateView;
+ ShowTrackerStatus(Result);
+end;
+
+function TControlerTrackerListOnline.SubmitTrackers(TrackerList: TStringList;
+ out TrackersSendCount: integer): boolean;
+begin
+ Result := FNewTrackon.SubmitTrackers(TrackerList, TrackersSendCount);
+end;
+
+constructor TControlerTrackerListOnline.Create(StringGridTorrentURL: TStringGrid;
+ TrackerList: TStringList; DefaultChecked: TDefaultChecked);
+begin
+
+ FTrackerList := TrackerList;
+ FDefaultChecked := DefaultChecked;
+
+ FStringGridTorrentURL := StringGridTorrentURL;
+ FStringGridTorrentURL.RowCount := 1;
+ FStringGridTorrentURL.FixedRows := 1;
+ FStringGridTorrentURL.AlternateColor := clCream;
+
+ FSelect := FStringGridTorrentURL.Columns.Add;
+ FSelect.Title.Caption := 'Keep';
+ FSelect.ButtonStyle := cbsCheckboxColumn;
+ FSelect.ReadOnly := False;
+
+
+ FTorrentURL_Status := FStringGridTorrentURL.Columns.Add;
+ FTorrentURL_Status.Title.Caption := 'Online status';
+ ShowTrackerStatus(False);
+ FTorrentURL_Status.ReadOnly := True;
+
+ FTorrentURL := FStringGridTorrentURL.Columns.Add;
+ FTorrentURL.Title.Caption := 'Tracker URL';
+ FTorrentURL.ReadOnly := True;
+
+ //make sure all text are fit inside the columns
+ FStringGridTorrentURL.AutoSizeColumns;
+
+ FNewTrackon := TNewTrackon.Create;
+ FTrackerListOnline := TTrackerListOnline.Create;
+
+ //copy tracker list from TNewTrackon to TTrackerListOnline
+ FTrackerListOnline.TrackerList_Live := FNewTrackon.TrackerList_Live;
+ FTrackerListOnline.TrackerList_Dead := FNewTrackon.TrackerList_Dead;
+ FTrackerListOnline.TrackerList_Stable := FNewTrackon.TrackerList_Stable;
+end;
+
+destructor TControlerTrackerListOnline.Destroy;
+begin
+ FTrackerListOnline.Free;
+ FNewTrackon.Free;
+ inherited Destroy;
+end;
+
+procedure TControlerTrackerListOnline.ShowTrackerStatus(Visible: boolean);
+begin
+ FTorrentURL_Status.Visible := Visible;
+end;
+
+function TControlerTrackerListOnline.GetChecked(index: integer): boolean;
+begin
+ //read the select checkbox. If '1' then it is True
+ Result := FStringGridTorrentURL.Cells[0, index +
+ FStringGridTorrentURL.FixedRows] = '1';
+end;
+
+procedure TControlerTrackerListOnline.SetChecked(index: integer; AValue: boolean);
+begin
+ FStringGridTorrentURL.Cells[0, index + FStringGridTorrentURL.FixedRows] :=
+ BoolToStr(AValue, '1', '0');
+end;
+
+
+procedure TControlerTrackerListOnline.AppendRow(Checked: boolean;
+ Status: TTrackerListOnlineStatus; const TrackerURL: UTF8String);
+var
+ CheckedStr, StatusStr: string;
+begin
+ CheckedStr := BoolToStr(Checked, '1', '0');
+ StatusStr := FTrackerListOnline.TrackerListOnlineStatusToString(Status);
+
+ //append to the end of the view list
+ FStringGridTorrentURL.InsertRowWithValues(FStringGridTorrentURL.RowCount,
+ [CheckedStr, StatusStr, TrackerURL]);
+end;
+
+function TControlerTrackerListOnline.TrackerURL(index: integer): string;
+begin
+ Result := FStringGridTorrentURL.Cells[2, index + FStringGridTorrentURL.FixedRows];
+end;
+
+function TControlerTrackerListOnline.TrackerStatus(index: integer):
+TTrackerListOnlineStatus;
+begin
+ Result := FTrackerListOnline.TrackerStatus(TrackerURL(index));
+end;
+
+function TControlerTrackerListOnline.Count: integer;
+begin
+ Result := FStringGridTorrentURL.RowCount - FStringGridTorrentURL.FixedRows;
+end;
+
+function TControlerTrackerListOnline.StableTrackers: TStringList;
+begin
+ Result := FNewTrackon.TrackerList_Stable;
+end;
+
+procedure TControlerTrackerListOnline.UpdateView;
+var
+ tracker: string;
+begin
+ //Clear all the previeus data in the view
+ FStringGridTorrentURL.RowCount := FStringGridTorrentURL.FixedRows;
+
+ FStringGridTorrentURL.BeginUpdate;
+
+ //Show the TrackerList list in string grid view
+ for tracker in FTrackerList do
+ begin
+ AppendRow(FDefaultChecked(tracker), FTrackerListOnline.TrackerStatus(
+ tracker), tracker);
+ end;
+
+ //make sure all text are fit inside the columns
+ FStringGridTorrentURL.AutoSizeColumns;
+
+ FStringGridTorrentURL.EndUpdate;
+end;
+
+end.
diff --git a/source/code/controler_treeview_torrent_data.pas b/source/code/controler_treeview_torrent_data.pas
new file mode 100644
index 0000000..99ab014
--- /dev/null
+++ b/source/code/controler_treeview_torrent_data.pas
@@ -0,0 +1,376 @@
+// SPDX-License-Identifier: MIT
+unit controler_treeview_torrent_data;
+
+{
+ Show the torrent files content in a tree view format.
+}
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils, Controls, ComCtrls, Menus, StdCtrls, DecodeTorrent;
+
+type
+
+ { Tcontroler_treeview_torrent_data }
+ Tcontroler_treeview_torrent_data_items = (
+ ctv_ShowAllFiles = 0,
+ ctv_ShowAllTrackers = 1,
+ ctv_ShowAllInfo = 2,
+ ctv_ShowEverything,
+ ctv_HideAll
+ );
+
+ Tcontroler_treeview_torrent_data = class
+ private
+ FTotalFileInsideTorrent: integer;
+ FTotalFileSizeInsideTorrent: int64;
+
+ FGroupBoxTorrentContents: TGroupBox;
+ FPopupMenuTorrentFilesContent: TPopupMenu;
+ FOwner: TWinControl;
+ FTreeViewFileContents: TTreeView;
+ FTreeNodeRoot: TTreeNode;
+ FMenuItemTorrentFilesTreeHideAll: TMenuItem;
+ FMenuItemTorrentFilesTreeShowTrackers: TMenuItem;
+ FMenuItemTorrentFilesTreeShowInfo: TMenuItem;
+ FMenuItemTorrentFilesTreeShowAll: TMenuItem;
+ FMenuItemTorrentFilesTreeShowFiles: TMenuItem;
+ procedure FillThePopupMenu;
+ procedure AddMenuItem(var MenuItem: TMenuItem; Onclick: TNotifyEvent;
+ const Caption: string; tag: integer);
+ procedure MenuItemTorrentFilesTreeShowOrHideItemClick(Sender: TObject);
+ procedure MenuItemTorrentFilesTreeHideAllClick(Sender: TObject);
+ procedure MenuItemTorrentFilesTreeShowAllClick(Sender: TObject);
+ procedure Clear;
+ procedure MenuItemTorrentFilesTreeSyncWithPopupMenu;
+ public
+ //called before AddOneTorrentFileDecoded
+ procedure BeginUpdate;
+
+ //called after AddOneTorrentFileDecoded
+ procedure EndUpdate;
+
+ //Add every torrent one by one to the list
+ procedure AddOneTorrentFileDecoded(DecodeTorrent: TDecodeTorrent);
+
+ constructor Create(Owner: TWinControl);
+
+ destructor Destroy; override;
+ end;
+
+
+
+implementation
+
+uses torrent_miscellaneous;
+
+const
+ TORRENT_FILES_CONTENTS_FORM_CAPTION =
+ 'Show all the files inside the torrents. (Use right mouse for popup menu.)';
+
+{ Tcontroler_treeview_torrent_data }
+
+procedure Tcontroler_treeview_torrent_data.FillThePopupMenu;
+begin
+ FPopupMenuTorrentFilesContent := TPopupMenu.Create(FTreeViewFileContents);
+ FTreeViewFileContents.PopupMenu := FPopupMenuTorrentFilesContent;
+
+ //There are 5 menu items the user can select/click on
+ //Create all these 5 menu items.
+
+ //'Show Everything'
+ AddMenuItem(FMenuItemTorrentFilesTreeShowAll, @MenuItemTorrentFilesTreeShowAllClick,
+ 'Show Everything', Ord(ctv_ShowEverything));//-1
+
+ //'Hide All'
+ AddMenuItem(FMenuItemTorrentFilesTreeHideAll, @MenuItemTorrentFilesTreeHideAllClick,
+ 'Hide All', Ord(ctv_HideAll));//0
+
+ //'Show All Files'
+ AddMenuItem(FMenuItemTorrentFilesTreeShowFiles,
+ @MenuItemTorrentFilesTreeShowOrHideItemClick, 'Show All Files',
+ Ord(ctv_ShowAllFiles));
+ FMenuItemTorrentFilesTreeShowFiles.AutoCheck := True;
+ FMenuItemTorrentFilesTreeShowFiles.Checked := True;
+
+ //'Show All Trackers'
+ AddMenuItem(FMenuItemTorrentFilesTreeShowTrackers,
+ @MenuItemTorrentFilesTreeShowOrHideItemClick, 'Show All Trackers',
+ Ord(ctv_ShowAllTrackers));
+ FMenuItemTorrentFilesTreeShowTrackers.AutoCheck := True;
+ FMenuItemTorrentFilesTreeShowTrackers.Checked := True;
+
+ //'Show All Info'
+ AddMenuItem(FMenuItemTorrentFilesTreeShowInfo,
+ @MenuItemTorrentFilesTreeShowOrHideItemClick, 'Show All Info', Ord(ctv_ShowAllInfo));
+ FMenuItemTorrentFilesTreeShowInfo.AutoCheck := True;
+ FMenuItemTorrentFilesTreeShowInfo.Checked := True;
+
+end;
+
+procedure Tcontroler_treeview_torrent_data.AddMenuItem(var MenuItem: TMenuItem;
+ Onclick: TNotifyEvent; const Caption: string; tag: integer);
+begin
+ MenuItem := TMenuItem.Create(FPopupMenuTorrentFilesContent);
+ MenuItem.OnClick := Onclick;
+ MenuItem.Caption := Caption;
+ MenuItem.Tag := tag;
+ FPopupMenuTorrentFilesContent.Items.Add(MenuItem);
+end;
+
+constructor Tcontroler_treeview_torrent_data.Create(Owner: TWinControl);
+begin
+ inherited Create;
+ FOwner := Owner;
+
+ //create TGroupBox
+ FGroupBoxTorrentContents := TGroupBox.Create(FOwner);
+ FGroupBoxTorrentContents.Parent := FOwner;
+ FGroupBoxTorrentContents.Align := alClient;
+ FGroupBoxTorrentContents.Caption := TORRENT_FILES_CONTENTS_FORM_CAPTION;
+
+ //create TTreeView
+ FTreeViewFileContents := TTreeView.Create(FGroupBoxTorrentContents);
+ FTreeViewFileContents.Parent := FGroupBoxTorrentContents;
+ FTreeViewFileContents.Align := alClient;
+ FTreeViewFileContents.ReadOnly := True;
+ FTreeViewFileContents.ShowRoot := False;
+ FTreeViewFileContents.Options :=
+ FTreeViewFileContents.Options + [tvoAutoExpand, tvoReadOnly] - [tvoShowRoot];
+
+ //create popupmenu
+ FillThePopupMenu;
+
+end;
+
+destructor Tcontroler_treeview_torrent_data.Destroy;
+begin
+ inherited Destroy;
+end;
+
+
+procedure Tcontroler_treeview_torrent_data.MenuItemTorrentFilesTreeHideAllClick(
+ Sender: TObject);
+var
+ i, CountTorrents: integer;
+begin
+ //hide all -> Show only torrent file names
+
+ //user what to hide all the items.
+ //All the popup menu item must first be unchecked.
+ FMenuItemTorrentFilesTreeShowInfo.Checked := False;
+ FMenuItemTorrentFilesTreeShowFiles.Checked := False;
+ FMenuItemTorrentFilesTreeShowTrackers.Checked := False;
+ //Update the TorrentFilesTree
+ // MenuItemTorrentFilesTreeSyncWithPopupMenu;
+
+ if not assigned(FTreeNodeRoot) then
+ exit;
+
+ //how many torrent files are there.
+ CountTorrents := FTreeNodeRoot.Count;
+ if CountTorrents = 0 then
+ exit;
+
+ //Show the torrent files names only.
+ for i := 0 to CountTorrents - 1 do
+ begin
+ FTreeNodeRoot.Items[i].Collapse(True);
+ end;
+
+end;
+
+procedure Tcontroler_treeview_torrent_data.MenuItemTorrentFilesTreeShowAllClick(
+ Sender: TObject);
+begin
+ //show everything
+ if assigned(FTreeNodeRoot) then
+ FTreeNodeRoot.Expand(True);
+
+ //user what to see all the items.
+ //All the popup menu item must first be checked.
+ FMenuItemTorrentFilesTreeShowInfo.Checked := True;
+ FMenuItemTorrentFilesTreeShowFiles.Checked := True;
+ FMenuItemTorrentFilesTreeShowTrackers.Checked := True;
+ //Update the TorrentFilesTree
+ // MenuItemTorrentFilesTreeSyncWithPopupMenu;
+end;
+
+procedure Tcontroler_treeview_torrent_data.Clear;
+begin
+ FTreeViewFileContents.Items.Clear;
+ FTreeNodeRoot := FTreeViewFileContents.Items.Add(nil, 'Torrent Files');
+ FTotalFileInsideTorrent := 0;
+ FTotalFileSizeInsideTorrent := 0;
+end;
+
+procedure Tcontroler_treeview_torrent_data.MenuItemTorrentFilesTreeSyncWithPopupMenu;
+begin
+ MenuItemTorrentFilesTreeShowOrHideItemClick(FMenuItemTorrentFilesTreeShowTrackers);
+ MenuItemTorrentFilesTreeShowOrHideItemClick(FMenuItemTorrentFilesTreeShowInfo);
+ MenuItemTorrentFilesTreeShowOrHideItemClick(FMenuItemTorrentFilesTreeShowFiles);
+end;
+
+procedure Tcontroler_treeview_torrent_data.BeginUpdate;
+begin
+ //Called before loading torrent file.
+
+ //do not update the view
+ FTreeViewFileContents.BeginUpdate;
+
+ //Clear everything before adding new torrent files
+ Clear;
+end;
+
+procedure Tcontroler_treeview_torrent_data.EndUpdate;
+begin
+ //The view can be updated again
+ FTreeViewFileContents.EndUpdate;
+
+ //Update the text about howmany files are there etc.
+ //Show the size of all the files inside the torrent
+ //http://en.wikipedia.org/wiki/Gigabyte
+ FGroupBoxTorrentContents.Caption :=
+ TORRENT_FILES_CONTENTS_FORM_CAPTION + ' (Files count: ' +
+ IntToStr(FTotalFileInsideTorrent) + ') Files sizes: ' +
+ ByteSizeToBiggerSizeFormatStr(FTotalFileSizeInsideTorrent) + '';
+
+ //Sync the popup menu with show/hide items.
+ MenuItemTorrentFilesTreeSyncWithPopupMenu;
+
+end;
+
+
+procedure Tcontroler_treeview_torrent_data.MenuItemTorrentFilesTreeShowOrHideItemClick(
+ Sender: TObject);
+var
+ i, CountTorrents, itemsNr: integer;
+ ShowNode: boolean;
+begin
+ //Show or hide all the items below the torrent files.
+
+ //Get the top node.
+ if not assigned(FTreeNodeRoot) then
+ exit;
+
+ //how many torrent files are there.
+ CountTorrents := FTreeNodeRoot.Count;
+ if CountTorrents = 0 then
+ exit;
+
+ //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
+ if ShowNode then
+ begin
+ FTreeNodeRoot.Items[i].Expand(False); //Show the torrent name + child
+ FTreeNodeRoot.Items[i].Items[itemsNr].Expand(False); //expand child
+ end
+ else
+ begin
+ FTreeNodeRoot.Items[i].Items[itemsNr].Collapse(False);
+ end;
+ end;
+end;
+
+procedure Tcontroler_treeview_torrent_data.AddOneTorrentFileDecoded(
+ DecodeTorrent: TDecodeTorrent);
+var
+ CountFiles: integer;
+ TorrentFileNameStr, TrackerStr: UTF8String;
+ TreeNodeTorrent, TreeNodeFiles, TreeNodeTrackers, TreeNodeInfo: TTreeNode;
+
+begin
+ //--------------------- Fill the treeview with torrent files
+
+ TorrentFileNameStr := ExtractFileName(DecodeTorrent.FilenameTorrent);
+
+ //Add the torrent file name + size of all the files combined.
+ TorrentFileNameStr := TorrentFileNameStr + ' SIZE: ' +
+ ByteSizeToBiggerSizeFormatStr(DecodeTorrent.TotalFileSize) +
+ ' Files: ' + IntToStr(DecodeTorrent.InfoFilesCount) + '' +
+ ' Tracker: ' + IntToStr(DecodeTorrent.TrackerList.Count) + '';
+
+
+ TreeNodeTorrent := FTreeViewFileContents.Items.AddChild(FTreeNodeRoot,
+ //FTrackerList.TorrentFileNameList[RowIndex]); //With directory path
+ TorrentFileNameStr); //Without directory path
+
+ //must be in this order (Files, Trackers, Info)
+ TreeNodeFiles := FTreeViewFileContents.Items.AddChild(TreeNodeTorrent, 'Files');
+ TreeNodeTrackers := FTreeViewFileContents.Items.AddChild(TreeNodeTorrent,
+ 'Trackers');
+ TreeNodeInfo := FTreeViewFileContents.Items.AddChild(TreeNodeTorrent, 'Info');
+
+ //Show all the files inside the torrent
+ if DecodeTorrent.InfoFilesCount > 0 then
+ begin
+ for CountFiles := 0 to DecodeTorrent.InfoFilesCount - 1 do
+ begin
+ FTreeViewFileContents.Items.AddChild(TreeNodeFiles,
+ DecodeTorrent.InfoFilesNameIndex(CountFiles) + ' SIZE: ' +
+ ByteSizeToBiggerSizeFormatStr(DecodeTorrent.InfoFilesLengthIndex(CountFiles)));
+ end;
+ end;
+
+ //Show a how many files are there
+ TreeNodeFiles.Text := TreeNodeFiles.Text + ' (' + IntToStr(TreeNodeFiles.Count) + ')';
+
+ //Show all the trackers inside the torrent
+ for TrackerStr in DecodeTorrent.TrackerList do
+ begin
+ FTreeViewFileContents.Items.AddChild(TreeNodeTrackers, TrackerStr);
+ end;
+
+ //Show a how many trackers are there
+ TreeNodeTrackers.Text := TreeNodeTrackers.Text + ' (' +
+ IntToStr(TreeNodeTrackers.Count) + ')';
+
+
+ //Show all the info of torrent
+ FTreeViewFileContents.Items.AddChild(TreeNodeInfo, 'Name: ' + DecodeTorrent.Name);
+
+ FTreeViewFileContents.Items.AddChild(TreeNodeInfo, 'Comment: ' +
+ DecodeTorrent.Comment);
+ FTreeViewFileContents.Items.AddChild(TreeNodeInfo, 'Info Hash: ' +
+ DecodeTorrent.InfoHash);
+ FTreeViewFileContents.Items.AddChild(TreeNodeInfo, 'Created On: ' +
+ DateTimeToStr(DecodeTorrent.CreatedDate));
+ FTreeViewFileContents.Items.AddChild(TreeNodeInfo, 'Created By: ' +
+ DecodeTorrent.CreatedBy);
+ FTreeViewFileContents.Items.AddChild(TreeNodeInfo, 'Piece Lenght: ' +
+ IntToStr(DecodeTorrent.PieceLenght div 1024) + ' KiB');
+ if DecodeTorrent.PrivateTorrent then
+ begin
+ FTreeViewFileContents.Items.AddChild(TreeNodeInfo, 'Private: yes');
+ end
+ else
+ begin
+ FTreeViewFileContents.Items.AddChild(TreeNodeInfo, 'Private: no');
+ end;
+ // some private torrent have info:source
+ if DecodeTorrent.InfoSource <> '' then
+ begin
+ FTreeViewFileContents.Items.AddChild(TreeNodeInfo, 'Source: ' +
+ DecodeTorrent.InfoSource);
+ end;
+
+ //All the files count inside the torrent must be added to FTotalFileInsideTorrent
+ Inc(FTotalFileInsideTorrent, DecodeTorrent.InfoFilesCount);
+
+ //The file size of all files inside the torrent must be added to FTotalFileSizeInsideTorrent
+ Inc(FTotalFileSizeInsideTorrent, DecodeTorrent.TotalFileSize);
+
+end;
+
+
+
+end.
diff --git a/source/code/controlergridtorrentdata.pas b/source/code/controlergridtorrentdata.pas
index 1f7fe80..1f81c41 100644
--- a/source/code/controlergridtorrentdata.pas
+++ b/source/code/controlergridtorrentdata.pas
@@ -1,22 +1,4 @@
-{ MIT licence
-Copyright (c) Gerry Ferdinandus
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of this software
-and associated documentation files (the "Software"), to deal in the Software without restriction,
-including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
-and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
-TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
-CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
-}
-
+// SPDX-License-Identifier: MIT
unit controlergridtorrentdata;
{
@@ -51,9 +33,10 @@ TControlerGridTorrentData = class
FCreatedBy, //4
FComment, //5
FPrivateTorrent, //6
- FPieceLength, //7
- FTotaSize, //8
- FIndexOrder //9
+ FInfoSource, //7
+ FPieceLength, //8
+ FTotaSize, //9
+ FIndexOrder //10
: TGridColumn;
FRowIsMovedNeedUpdate: boolean;
@@ -71,9 +54,10 @@ TControlerGridTorrentData = class
CreatedBy, //4
Comment, //5
PrivateTorrent, //6
- PieceLength, //7
- TotaSize, //8
- IndexOrder //9
+ InfoSource, //7
+ PieceLength, //8
+ TotaSize, //9
+ IndexOrder //10
: UTF8String;
procedure ClearAllImageIndex;
@@ -88,7 +72,7 @@ implementation
{ TControlerGridTorrentData }
const
- COLUMN_COUNT = 10;
+ COLUMN_COUNT = 11;
procedure TControlerGridTorrentData.StringGridTorrentDataColRowMoved(Sender: TObject;
IsColumn: boolean; sIndex, tIndex: integer);
@@ -156,6 +140,7 @@ procedure TControlerGridTorrentData.AppendRow;
WriteCell(FCreatedBy, CreatedBy);
WriteCell(FComment, Comment);
WriteCell(FPrivateTorrent, PrivateTorrent);
+ WriteCell(FInfoSource, InfoSource);
WriteCell(FPieceLength, PieceLength);
WriteCell(FTotaSize, TotaSize);
WriteCell(FIndexOrder, IndexOrder);
@@ -193,7 +178,7 @@ constructor TControlerGridTorrentData.Create(StringGridTorrentData: TStringGrid)
FStringGridTorrentData.OnColRowMoved := @StringGridTorrentDataColRowMoved;
//The view and the controler part must have the same column count.
- Assert(FStringGridTorrentData.Columns.Count <> COLUMN_COUNT, 'Wrong column count');
+ Assert(FStringGridTorrentData.Columns.Count = COLUMN_COUNT, 'Wrong column count');
//Track the column
AddColumn(FTorrentFile, 0);
@@ -203,9 +188,10 @@ constructor TControlerGridTorrentData.Create(StringGridTorrentData: TStringGrid)
AddColumn(FCreatedBy, 4);
AddColumn(FComment, 5);
AddColumn(FPrivateTorrent, 6);
- AddColumn(FPieceLength, 7);
- AddColumn(FTotaSize, 8);
- AddColumn(FIndexOrder, 9);
+ AddColumn(FInfoSource, 7);
+ AddColumn(FPieceLength, 8);
+ AddColumn(FTotaSize, 9);
+ AddColumn(FIndexOrder, 10);
//Fillin the tag value
UpdateColumnTag;
diff --git a/source/code/decodetorrent.pas b/source/code/decodetorrent.pas
index c0be621..d035540 100644
--- a/source/code/decodetorrent.pas
+++ b/source/code/decodetorrent.pas
@@ -1,22 +1,4 @@
-{ MIT licence
-Copyright (c) Gerry Ferdinandus
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of this software
-and associated documentation files (the "Software"), to deal in the Software without restriction,
-including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
-and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
-TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
-CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
-}
-
+// SPDX-License-Identifier: MIT
unit DecodeTorrent;
{$mode objfpc}{$H+}
@@ -68,6 +50,7 @@ TDecodeTorrent = class
FCreatedBy: utf8string;
FCreatedDate: TDateTime;
FComment: utf8string;
+ FInfoSource: utf8string;
FName: utf8string;
FPieceLenght: int64;
FPrivateTorrent: boolean;
@@ -83,6 +66,7 @@ TDecodeTorrent = class
function GetName: utf8string;
function GetPieceLenght: int64;
function GetPrivateTorrent: boolean;
+ function GetInfoSource: utf8string;
procedure SetComment(const AValue: utf8string);
public
//All the trackers inside this torrent file
@@ -117,6 +101,11 @@ TDecodeTorrent = class
procedure RemovePrivateTorrentFlag;
procedure AddPrivateTorrentFlag;
+ //info.source
+ property InfoSource: utf8string read FInfoSource;
+ procedure InfoSourceRemove;
+ procedure InfoSourceAdd(const Value: utf8string);
+
//info.files
function InfoFilesCount: integer;
function InfoFilesNameIndex(index: integer): utf8string;
@@ -405,7 +394,7 @@ function TDecodeTorrent.DecodeTorrent: boolean;
FName := GetName;
FPieceLenght := GetPieceLenght;
FPrivateTorrent := GetPrivateTorrent;
-
+ FInfoSource := GetInfoSource;
except
end;
end;
@@ -441,9 +430,22 @@ function TDecodeTorrent.GetPrivateTorrent: boolean;
end;
end;
+function TDecodeTorrent.GetInfoSource: utf8string;
+var
+ TempBEncoded: TBEncoded;
+begin
+ Result := '';
+ try
+ {find 'source' }
+ TempBEncoded := FBEncoded_Info.ListData.FindElement('source');
+ if assigned(TempBEncoded) then
+ Result := TempBEncoded.StringData;
+ except
+ end;
+end;
+
procedure TDecodeTorrent.SetComment(const AValue: utf8string);
var
- // Encoded: TBEncoded;
Data: TBEncodedData;
begin
if FComment = AValue then
@@ -477,7 +479,6 @@ procedure TDecodeTorrent.SetComment(const AValue: utf8string);
end;
-
{
try
Encoded := TBEncoded.Create;
@@ -499,7 +500,7 @@ procedure TDecodeTorrent.RemovePrivateTorrentFlag;
except
end;
//read databack again
- GetPrivateTorrent;
+ FPrivateTorrent := GetPrivateTorrent;
end;
procedure TDecodeTorrent.AddPrivateTorrentFlag;
@@ -519,7 +520,36 @@ procedure TDecodeTorrent.AddPrivateTorrentFlag;
except
end;
//read databack again
- GetPrivateTorrent;
+ FPrivateTorrent := GetPrivateTorrent;
+end;
+
+procedure TDecodeTorrent.InfoSourceRemove;
+begin
+ try
+ FBEncoded_Info.ListData.RemoveElement('source');
+ except
+ end;
+ //read databack again
+ FInfoSource := GetInfoSource;
+end;
+
+procedure TDecodeTorrent.InfoSourceAdd(const Value: utf8string);
+var
+ Encoded: TBEncoded;
+ Data: TBEncodedData;
+begin//remove the old one and create a new one
+ InfoSourceRemove;
+ try
+ Encoded := TBEncoded.Create;
+ Encoded.Format := befString;
+ Encoded.StringData := Value;
+ Data := TBEncodedData.Create(Encoded);
+ Data.Header := 'source';
+ FBEncoded_Info.ListData.Add(Data);
+ FBEncoded_Info.ListData.Sort(@sort_);//text must be in alfabetical order.
+ except
+ end;
+ FInfoSource := GetInfoSource;
end;
procedure TDecodeTorrent.RemoveAnnounce;
diff --git a/source/code/main.lfm b/source/code/main.lfm
index 5e72bc8..5fa3346 100644
--- a/source/code/main.lfm
+++ b/source/code/main.lfm
@@ -1,7 +1,7 @@
object FormTrackerModify: TFormTrackerModify
- Left = 1386
+ Left = 429
Height = 607
- Top = 210
+ Top = 183
Width = 1179
AllowDropFiles = True
Caption = 'Bittorrent Tracker Editor'
@@ -16,7 +16,7 @@ object FormTrackerModify: TFormTrackerModify
OnDropFiles = FormDropFiles
OnShow = FormShow
Position = poScreenCenter
- LCLVersion = '1.4.4.0'
+ LCLVersion = '2.0.4.0'
object PageControl: TPageControl
Left = 0
Height = 587
@@ -72,15 +72,20 @@ object FormTrackerModify: TFormTrackerModify
Constraints.MinHeight = 100
ParentBidiMode = False
TabOrder = 1
- object CheckListBoxTrackersList: TCheckListBox
+ object StringGridTrackerOnline: TStringGrid
Left = 0
Height = 335
Top = 0
Width = 1165
Align = alClient
- Constraints.MinHeight = 50
- ItemHeight = 0
+ AlternateColor = clWhite
+ ColCount = 0
+ FixedCols = 0
+ FixedRows = 0
+ Options = [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, goEditing, goSmoothScroll]
+ RowCount = 0
TabOrder = 0
+ TitleFont.Height = -11
end
end
object Splitter1: TSplitter
@@ -139,7 +144,7 @@ object FormTrackerModify: TFormTrackerModify
Top = 0
Width = 1171
Align = alClient
- ColCount = 10
+ ColCount = 11
ColumnClickSorts = True
Columns = <
item
@@ -177,6 +182,10 @@ object FormTrackerModify: TFormTrackerModify
Title.Caption = 'Private'
Width = 50
end
+ item
+ Title.Caption = 'Source'
+ Width = 64
+ end
item
Alignment = taRightJustify
ReadOnly = True
@@ -210,6 +219,7 @@ object FormTrackerModify: TFormTrackerModify
145
160
50
+ 64
100
100
0
@@ -218,31 +228,66 @@ object FormTrackerModify: TFormTrackerModify
end
object TabSheetTorrentsContents: TTabSheet
Caption = 'Files/Trackers/Info'
+ end
+ object TabSheetPrivateTrackers: TTabSheet
+ Caption = 'Private Trackers'
ClientHeight = 561
ClientWidth = 1171
- object GroupBoxTorrentContents: TGroupBox
+ object GroupBoxItemsForPrivateTrackers: TGroupBox
Left = 0
- Height = 561
- Top = 0
- Width = 1171
- Align = alClient
- Caption = 'Show all the files inside the torrents'
- ClientHeight = 543
- ClientWidth = 1167
+ Height = 176
+ Hint = 'Private trackers URL may not end with /announce'
+ Top = 8
+ Width = 288
+ Caption = 'Items for private trackers'
+ ClientHeight = 158
+ ClientWidth = 284
TabOrder = 0
- object TreeViewFileContents: TTreeView
- Left = 0
- Height = 543
+ object CheckBoxSkipAnnounceCheck: TCheckBox
+ Left = 16
+ Height = 19
Top = 0
- Width = 1167
- Align = alClient
- AutoExpand = True
- DefaultItemHeight = 16
- PopupMenu = PopupMenuTorrentFilesContent
- ReadOnly = True
- ShowRoot = False
+ Width = 221
+ Caption = 'Skip Announce Check in the URL (-SAC)'
+ OnChange = CheckBoxSkipAnnounceCheckChange
+ ParentShowHint = False
+ ShowHint = True
TabOrder = 0
- Options = [tvoAutoExpand, tvoAutoItemHeight, tvoHideSelection, tvoKeepCollapsedNodes, tvoReadOnly, tvoShowButtons, tvoShowLines, tvoToolTips, tvoThemedDraw]
+ end
+ object GroupBoxInfoSource: TGroupBox
+ Left = 16
+ Height = 120
+ Top = 32
+ Width = 264
+ Caption = 'Warning: This will change the torrent info HASH'
+ ClientHeight = 102
+ ClientWidth = 260
+ TabOrder = 1
+ object CheckBoxRemoveAllSourceTag: TCheckBox
+ Left = 8
+ Height = 19
+ Top = 8
+ Width = 132
+ Caption = 'Remove all source tag'
+ OnChange = CheckBoxRemoveAllSourceTagChange
+ TabOrder = 0
+ end
+ object LabeledEditInfoSource: TLabeledEdit
+ Left = 8
+ Height = 21
+ Hint = 'Keep empty if you do not want to add or change anything.'
+ Top = 56
+ Width = 221
+ EditLabel.Height = 13
+ EditLabel.Width = 221
+ EditLabel.Caption = 'Add/Change source tag value: (-SOURCE)'
+ EditLabel.ParentColor = False
+ ParentShowHint = False
+ ShowHint = True
+ TabOrder = 1
+ TabStop = False
+ OnEditingDone = LabeledEditInfoSourceEditingDone
+ end
end
end
end
@@ -288,6 +333,26 @@ object FormTrackerModify: TFormTrackerModify
Caption = '&Delete all the present trackers'
OnClick = MenuTrackersKeepOrDeleteAllTrackersClick
end
+ object MenuTrackersSeperator1: TMenuItem
+ Caption = '-'
+ end
+ object MenuTrackersDeleteUnstableTrackers: TMenuItem
+ Caption = 'Delete UNSTABLE trackers (Data from newTrackon)'
+ OnClick = MenuTrackersDeleteTrackersWithStatusClick
+ end
+ object MenuTrackersDeleteDeadTrackers: TMenuItem
+ Tag = 1
+ Caption = 'Delete DEAD trackers (Data from newTrackon)'
+ OnClick = MenuTrackersDeleteTrackersWithStatusClick
+ end
+ object MenuTrackersDeleteUnknownTrackers: TMenuItem
+ Tag = 2
+ Caption = 'Delete UNKNOWN trackers (Data from newTrackon)'
+ OnClick = MenuTrackersDeleteTrackersWithStatusClick
+ end
+ object MenuTrackersSeperator2: TMenuItem
+ Caption = '-'
+ end
object MenuTrackersAllTorrentArePublic: TMenuItem
Tag = 1
Caption = 'All torrent are &public'
@@ -304,81 +369,113 @@ object FormTrackerModify: TFormTrackerModify
object MenuUpdateTorrentAddAfter: TMenuItem
Caption = 'Insert new trackers list &BEFORE, the original trackers list inside the torrent file'
object MenuUpdateTorrentAddBeforeRemoveOriginal: TMenuItem
- Caption = 'And remove possible duplicated trackers from the ORIGINAL trackers list.'
+ Caption = 'And remove possible duplicated trackers from the ORIGINAL trackers list.(-U0)'
OnClick = MenuUpdateTorrentAddBeforeRemoveOriginalClick
end
object MenuUpdateTorrentAddBeforeRemoveNew: TMenuItem
- Caption = 'And remove possible duplicated trackers from the NEW trackers list.'
+ Caption = 'And remove possible duplicated trackers from the NEW trackers list.(-U1)'
OnClick = MenuUpdateTorrentAddBeforeRemoveNewClick
end
object MenuUpdateTorrentAddBeforeKeepOriginalInstactAndRemoveNothing: TMenuItem
- Caption = 'Keep original tracker list unchanged and remove nothing.'
+ Caption = 'Keep original tracker list unchanged and remove nothing.(-U5)'
OnClick = MenuUpdateTorrentAddBeforeKeepOriginalInstactAndRemoveNothingClick
end
end
object MenuUpdateTorrentAddBefore: TMenuItem
Caption = 'Append new trackers list &AFTER, the original trackers list inside the torrent file.'
object MenuUpdateTorrentAddAfterRemoveOriginal: TMenuItem
- Caption = 'And remove possible duplicated trackers from the ORIGINAL trackers list.'
+ Caption = 'And remove possible duplicated trackers from the ORIGINAL trackers list.(-U2)'
OnClick = MenuUpdateTorrentAddAfterRemoveOriginalClick
end
object MenuUpdateTorrentAddAfterRemoveNew: TMenuItem
- Caption = 'And remove possible duplicated trackers from the NEW trackers list.'
+ Caption = 'And remove possible duplicated trackers from the NEW trackers list.(-U3)'
OnClick = MenuUpdateTorrentAddAfterRemoveNewClick
end
object MenuUpdateTorrentAddAfterKeepOriginalInstactAndRemoveNothing: TMenuItem
- Caption = 'Keep original tracker list unchanged and remove nothing.'
+ Caption = 'Keep original tracker list unchanged and remove nothing.(-U6)'
OnClick = MenuUpdateTorrentAddAfterKeepOriginalInstactAndRemoveNothingClick
end
end
object MenuUpdateTorrentSort: TMenuItem
- Caption = '&Sort the trackers list by name.'
+ Caption = '&Sort the trackers list by name.(-U4)'
OnClick = MenuUpdateTorrentSortClick
end
+ object MenuUpdateRandomize: TMenuItem
+ Caption = '&Randomize the trackers list.(-U7)'
+ OnClick = MenuUpdateRandomizeClick
+ end
+ end
+ object MenuOnlineCheck: TMenuItem
+ Caption = 'Online Check'
+ object MenuItemOnlineCheckDownloadNewTrackon: TMenuItem
+ Caption = 'Check Status Trackers (From newTrackon)'
+ OnClick = MenuItemOnlineCheckDownloadNewTrackonClick
+ end
+ object MenuItemOnlineCheckAppendStableTrackers: TMenuItem
+ Caption = 'Append Stable Trackers (From newTrackon)'
+ OnClick = MenuItemOnlineCheckAppendStableTrackersClick
+ end
+ object MenuItemOnlineCheckSubmitNewTrackon: TMenuItem
+ Caption = 'Upload trackers to newTrackon'
+ OnClick = MenuItemOnlineCheckSubmitNewTrackonClick
+ end
+ end
+ object MenuItem1: TMenuItem
+ Caption = 'ngosang/trackerslist'
+ object MenuItemNgosangAppendBest: TMenuItem
+ Caption = 'Append best'
+ OnClick = MenuItemNgosangAppendBestClick
+ end
+ object MenuItemNgosangAppendAll: TMenuItem
+ Caption = 'Append all'
+ OnClick = MenuItemNgosangAppendAllClick
+ end
+ object MenuItemNgosangAppendAllUdp: TMenuItem
+ Caption = 'Append all udp'
+ OnClick = MenuItemNgosangAppendAllUdpClick
+ end
+ object MenuItemNgosangAppendAllHttp: TMenuItem
+ Caption = 'Append all http'
+ OnClick = MenuItemNgosangAppendAllHttpClick
+ end
+ object MenuItemNgosangAppendAllHttps: TMenuItem
+ Caption = 'Append all https'
+ OnClick = MenuItemNgosangAppendAllHttpsClick
+ end
+ object MenuItemNgosangAppendAllWs: TMenuItem
+ Caption = 'Append all ws'
+ OnClick = MenuItemNgosangAppendAllWsClick
+ end
+ object MenuItemNgosangAppendAllBestIp: TMenuItem
+ Caption = 'Append best ip'
+ OnClick = MenuItemNgosangAppendAllBestIpClick
+ end
+ object MenuItemNgosangAppendAllIp: TMenuItem
+ Caption = 'Append all ip'
+ OnClick = MenuItemNgosangAppendAllIpClick
+ end
end
object MenuHelp: TMenuItem
Caption = '&Help'
object MenuHelpVisitWebsite: TMenuItem
- Caption = '&Visit website'
+ Caption = '&Visit website tracker editor'
OnClick = MenuHelpVisitWebsiteClick
end
object MenuHelpReportingIssue: TMenuItem
Caption = '&Reporting Issue'
OnClick = MenuHelpReportingIssueClick
end
- end
- end
- object PopupMenuTorrentFilesContent: TPopupMenu
- left = 632
- top = 152
- object MenuItemTorrentFilesTreeShowAll: TMenuItem
- Tag = -1
- Caption = 'Show Everything'
- OnClick = MenuItemTorrentFilesTreeShowAllClick
- end
- object MenuItemTorrentFilesTreeHideAll: TMenuItem
- Caption = 'Hide All'
- OnClick = MenuItemTorrentFilesTreeHideAllClick
- end
- object MenuItemTorrentFilesTreeShowFiles: TMenuItem
- AutoCheck = True
- Caption = 'Show All Files'
- Checked = True
- OnClick = MenuItemTorrentFilesTreeShowOrHideItemClick
- end
- object MenuItemTorrentFilesTreeShowTrackers: TMenuItem
- Tag = 1
- AutoCheck = True
- Caption = 'Show All Trackers'
- Checked = True
- OnClick = MenuItemTorrentFilesTreeShowOrHideItemClick
- end
- object MenuItemTorrentFilesTreeShowInfo: TMenuItem
- Tag = 2
- AutoCheck = True
- Caption = 'Show All Info'
- Checked = True
- OnClick = MenuItemTorrentFilesTreeShowOrHideItemClick
+ object MenuHelpSeperator1: TMenuItem
+ Caption = '-'
+ end
+ object MenuHelpVisitNewTrackon: TMenuItem
+ Caption = 'Visit website new&Trackon'
+ OnClick = MenuHelpVisitNewTrackonClick
+ end
+ object MenuHelpVisitNgosang: TMenuItem
+ Caption = 'Visit website &ngosang (github)'
+ OnClick = MenuHelpVisitNgosangClick
+ end
end
end
end
diff --git a/source/code/main.pas b/source/code/main.pas
index 509d4c3..1cb416a 100644
--- a/source/code/main.pas
+++ b/source/code/main.pas
@@ -1,27 +1,7 @@
-{ MIT licence
-Copyright (c) Gerry Ferdinandus
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of this software
-and associated documentation files (the "Software"), to deal in the Software without restriction,
-including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
-and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
-TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
-CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
-}
-
+// SPDX-License-Identifier: MIT
unit main;
{
-
-
Unicode:
variable 'Utf8string' is the same as 'string'
UTF8String = type ansistring;
@@ -35,68 +15,54 @@
interface
uses
- Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
+ Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls,
ExtCtrls, CheckLst, DecodeTorrent, LCLType, ActnList, Menus, ComCtrls,
- Grids, controlergridtorrentdata;
+ Grids, controlergridtorrentdata, torrent_miscellaneous,
+ controler_trackerlist_online, controler_treeview_torrent_data, ngosang_trackerslist;
type
- //Updated torrent file trackers list order.
- TTrackerListOrder = (
-
- // Console parameter: -U0
- // Insert new trackers list BEFORE, the original trackers list inside the torrent file.
- // And remove possible duplicated trackers from the ORIGINAL trackers list.
- tloInsertNewBeforeAndKeepNewIntact,
-
- // Console parameter: -U1
- // Insert new trackers list BEFORE, the original trackers list inside the torrent file.
- // And remove possible duplicated trackers from the NEW trackers list.
- tloInsertNewBeforeAndKeepOriginalIntact,
-
- // Console parameter: -U2
- // Append new trackers list AFTER, the original trackers list inside the torrent file.
- // And remove possible duplicated trackers from the ORIGINAL trackers list.
- tloAppendNewAfterAndKeepNewIntact,
-
- // Console parameter: -U3
- // Append new trackers list AFTER, the original trackers list inside the torrent file.
- // And remove possible duplicated trackers from the NEW trackers list.
- tloAppendNewAfterAndKeepOriginalIntact,
-
- // Console parameter: -U4
- // Sort the trackers list by name.
- tloSort,
-
- // Console parameter: -U5
- // Append new trackers list BEFORE, the original trackers list inside the torrent file.
- // Keep original tracker list unchanged and remove nothing.
- tloInsertNewBeforeAndKeepOriginalIntactAndRemoveNothing,
-
- // Console parameter: -U6
- // Append new trackers list AFTER, the original trackers list inside the torrent file.
- // Keep original tracker list unchanged and remove nothing.
- tloAppendNewAfterAndKeepOriginalIntactAndRemoveNothing
-
- );
-
-
{ TFormTrackerModify }
TFormTrackerModify = class(TForm)
+ CheckBoxRemoveAllSourceTag: TCheckBox;
+ CheckBoxSkipAnnounceCheck: TCheckBox;
CheckListBoxPublicPrivateTorrent: TCheckListBox;
- CheckListBoxTrackersList: TCheckListBox;
- GroupBoxTorrentContents: TGroupBox;
+ GroupBoxInfoSource: TGroupBox;
+ GroupBoxItemsForPrivateTrackers: TGroupBox;
GroupBoxPublicPrivateTorrent: TGroupBox;
GroupBoxNewTracker: TGroupBox;
GroupBoxPresentTracker: TGroupBox;
+ LabeledEditInfoSource: TLabeledEdit;
MainMenu: TMainMenu;
MemoNewTrackers: TMemo;
MenuFile: TMenuItem;
MenuFileTorrentFolder: TMenuItem;
MenuFileOpenTrackerList: TMenuItem;
MenuHelpReportingIssue: TMenuItem;
+ MenuHelpSeperator1: TMenuItem;
+ MenuHelpVisitNewTrackon: TMenuItem;
+ MenuItem1: TMenuItem;
+ MenuHelpVisitNgosang: TMenuItem;
+ MenuItemNgosangAppendAllIp: TMenuItem;
+ MenuItemNgosangAppendAllBestIp: TMenuItem;
+ MenuItemNgosangAppendAllWs: TMenuItem;
+ MenuItemNgosangAppendAllHttps: TMenuItem;
+ MenuItemNgosangAppendAllHttp: TMenuItem;
+ MenuItemNgosangAppendAllUdp: TMenuItem;
+ MenuItemNgosangAppendBest: TMenuItem;
+ MenuItemNgosangAppendAll: TMenuItem;
+ MenuItemOnlineCheckSubmitNewTrackon: TMenuItem;
+ MenuItemOnlineCheckAppendStableTrackers: TMenuItem;
+ MenuTrackersDeleteDeadTrackers: TMenuItem;
+ MenuTrackersDeleteUnstableTrackers: TMenuItem;
+ MenuTrackersDeleteUnknownTrackers: TMenuItem;
+ MenuTrackersSeperator2: TMenuItem;
+ MenuTrackersSeperator1: TMenuItem;
+ MenuItemOnlineCheckDownloadNewTrackon: TMenuItem;
+ MenuOnlineCheck: TMenuItem;
+ MenuUpdateRandomize: TMenuItem;
MenuUpdateTorrentAddBeforeKeepOriginalInstactAndRemoveNothing: TMenuItem;
MenuUpdateTorrentAddAfterKeepOriginalInstactAndRemoveNothing: TMenuItem;
MenuUpdateTorrentAddBeforeRemoveOriginal: TMenuItem;
@@ -106,11 +72,6 @@ TFormTrackerModify = class(TForm)
MenuUpdateTorrentSort: TMenuItem;
MenuUpdateTorrentAddAfter: TMenuItem;
MenuUpdateTorrentAddBefore: TMenuItem;
- MenuItemTorrentFilesTreeHideAll: TMenuItem;
- MenuItemTorrentFilesTreeShowTrackers: TMenuItem;
- MenuItemTorrentFilesTreeShowInfo: TMenuItem;
- MenuItemTorrentFilesTreeShowAll: TMenuItem;
- MenuItemTorrentFilesTreeShowFiles: TMenuItem;
MenuTrackersAllTorrentArePrivate: TMenuItem;
MenuTrackersAllTorrentArePublic: TMenuItem;
MenuUpdateTorrent: TMenuItem;
@@ -124,15 +85,17 @@ TFormTrackerModify = class(TForm)
PageControl: TPageControl;
PanelTopPublicTorrent: TPanel;
PanelTop: TPanel;
- PopupMenuTorrentFilesContent: TPopupMenu;
SelectDirectoryDialog1: TSelectDirectoryDialog;
Splitter1: TSplitter;
+ StringGridTrackerOnline: TStringGrid;
StringGridTorrentData: TStringGrid;
+ TabSheetPrivateTrackers: TTabSheet;
TabSheetTorrentsContents: TTabSheet;
TabSheetTorrentData: TTabSheet;
TabSheetTrackersList: TTabSheet;
TabSheetPublicPrivateTorrent: TTabSheet;
- TreeViewFileContents: TTreeView;
+ procedure CheckBoxRemoveAllSourceTagChange(Sender: TObject);
+ procedure CheckBoxSkipAnnounceCheckChange(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
@@ -141,102 +104,97 @@ TFormTrackerModify = class(TForm)
//At start of the program the form will be show/hide
procedure FormShow(Sender: TObject);
- procedure MenuFileOpenTrackerListClick(Sender: TObject);
+ procedure LabeledEditInfoSourceEditingDone(Sender: TObject);
procedure MenuHelpReportingIssueClick(Sender: TObject);
+ procedure MenuHelpVisitNewTrackonClick(Sender: TObject);
procedure MenuHelpVisitWebsiteClick(Sender: TObject);
-
- //Popup menu in treeview show all/hide all/ individual items selection.
- procedure MenuItemTorrentFilesTreeShowAllClick(Sender: TObject);
- procedure MenuItemTorrentFilesTreeHideAllClick(Sender: TObject);
- procedure MenuItemTorrentFilesTreeShowOrHideItemClick(Sender: TObject);
+ procedure MenuHelpVisitNgosangClick(Sender: TObject);
+ procedure MenuItemNgosangAppendAllBestIpClick(Sender: TObject);
+ procedure MenuItemNgosangAppendAllClick(Sender: TObject);
+ procedure MenuItemNgosangAppendAllHttpClick(Sender: TObject);
+ procedure MenuItemNgosangAppendAllHttpsClick(Sender: TObject);
+ procedure MenuItemNgosangAppendAllIpClick(Sender: TObject);
+ procedure MenuItemNgosangAppendAllUdpClick(Sender: TObject);
+ procedure MenuItemNgosangAppendAllWsClick(Sender: TObject);
+
+ procedure MenuItemNgosangAppendBestClick(Sender: TObject);
+ procedure MenuItemOnlineCheckSubmitNewTrackonClick(Sender: TObject);
//Select via menu torrent file or directory
procedure MenuOpenTorrentFileClick(Sender: TObject);
procedure MenuFileTorrentFolderClick(Sender: TObject);
+ procedure MenuFileOpenTrackerListClick(Sender: TObject);
//Menu trackers
procedure MenuTrackersAllTorrentArePublicPrivateClick(Sender: TObject);
procedure MenuTrackersKeepOrDeleteAllTrackersClick(Sender: TObject);
- procedure MenuUpdateTorrentAddAfterKeepOriginalInstactAndRemoveNothingClick(Sender: TObject
- );
+ procedure MenuTrackersDeleteTrackersWithStatusClick(Sender: TObject);
//Menu update torrent
procedure MenuUpdateTorrentAddAfterRemoveNewClick(Sender: TObject);
procedure MenuUpdateTorrentAddAfterRemoveOriginalClick(Sender: TObject);
- procedure MenuUpdateTorrentAddBeforeKeepOriginalInstactAndRemoveNothingClick(Sender: TObject
- );
+ procedure MenuUpdateTorrentAddBeforeKeepOriginalInstactAndRemoveNothingClick(
+ Sender: TObject);
procedure MenuUpdateTorrentAddBeforeRemoveNewClick(Sender: TObject);
procedure MenuUpdateTorrentAddBeforeRemoveOriginalClick(Sender: TObject);
procedure MenuUpdateTorrentSortClick(Sender: TObject);
+ procedure MenuUpdateTorrentAddAfterKeepOriginalInstactAndRemoveNothingClick(
+ Sender: TObject);
+ procedure MenuUpdateRandomizeClick(Sender: TObject);
+ //Menu online check
+ procedure MenuItemOnlineCheckAppendStableTrackersClick(Sender: TObject);
+ procedure MenuItemOnlineCheckDownloadNewTrackonClick(Sender: TObject);
private
{ private declarations }
- //Trackers that must be put inside the torrent.
- FTrackerFinalList,
- //Trackers that we want too add.
- FTrackerAddedByUserList,
- //trackers that must not be present inside torrent.
- FTrackerBanByUserList,
- //Trackers that are already inside the torrent.
- FTrackerFromInsideTorrentFilesList,
- //trackers that must not be present inside torrent.
- FTrackerManualyDeselectedByUserList,
- // All the torrent files that must be updated
- FTorrentFileNameList,
- //Log string text output
- FLogStringList: TStringList;
+
+ FTrackerList: TTrackerList;
+ FControlerTrackerListOnline: TControlerTrackerListOnline;
+ Fcontroler_treeview_torrent_data: Tcontroler_treeview_torrent_data;
+ FDownloadStatus: boolean;
+
+ FngosangTrackerList: TngosangTrackerList;
// is the present torrent file being process
FDecodePresentTorrent: TDecodeTorrent;
- FConcoleMode, //user have start the program in console mode
+
+ FDragAndDropStartUp, // user have start the program via Drag And Drop
+ FConsoleMode, //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;
-
+ FFolderForTrackerListLoadAndSave: string;
FLogFile, FTrackerFile: TextFile;
- FTotalFileInsideTorrent: integer;
- FTotalFileSizeInsideTorrent: int64;
FProcessTimeStart, FProcessTimeTotal: TDateTime;
- FTreeNodeRoot: TTreeNode;
FControlerGridTorrentData: TControlerGridTorrentData;
-
- procedure RemoveTrackersFromList(RemoveList, UpdatedList: TStringList);
+ function CheckForAnnounce(const TrackerURL: UTF8String): boolean;
+ procedure AppendTrackersToMemoNewTrackers(TrackerList: TStringList);
+ procedure ShowUserErrorMessage(const ErrorText: string; const FormText: string = '');
+ function TrackerWithURLAndAnnounce(const TrackerURL: UTF8String): boolean;
procedure UpdateTorrent;
- procedure AddButIngnoreDuplicates(StringList: TStringList; const Str: UTF8String);
-
- function ByteSizeToBiggerSizeFormatStr(ByteSize: int64): string;
-
procedure ShowHourGlassCursor(HourGlass: boolean);
- procedure ViewUpdateBegin(ClearView: boolean = True);
+ procedure ViewUpdateBegin;
procedure ViewUpdateOneTorrentFileDecoded;
procedure ViewUpdateEnd;
procedure ViewUpdateFormCaption;
procedure ClearAllTorrentFilesNameAndTrackerInside;
-
- procedure MenuItemTorrentFilesTreeSyncWithPopupMenu;
procedure SaveTrackerFinalListToFile;
- procedure ConsoleMode;
- function ConsoleModeDecodeParameter(out FileNameOrDirStr: UTF8String): boolean;
- function DecodeConsoleUpdateParameter(ConsoleUpdateParameter: UTF8String): boolean;
+ procedure ConsoleModeOrDragAndDropStartupMode;
procedure UpdateViewRemoveTracker;
-
-
- procedure ReloadAllTorrentAndRefreshView;
+ function ReloadAllTorrentAndRefreshView: boolean;
function AddTorrentFileList(TorrentFileNameStringList: TStringList): boolean;
function ReadAddTrackerFileFromUser(const FileName: UTF8String): boolean;
function LoadTorrentViaDir(const Dir: UTF8String): boolean;
function DecodeTorrentFile(const FileName: UTF8String): boolean;
procedure UpdateTrackerInsideFileList;
procedure UpdateTorrentTrackerList;
- procedure CombineFiveTrackerListToOne(TrackerListOrder: TTrackerListOrder);
procedure ShowTrackerInsideFileList;
+ function TestConnectionSSL: Boolean;
procedure CheckedOnOffAllTrackers(Value: boolean);
- function CopyUserInputNewTrackersToList: boolean;
- procedure LoadTrackersTextFileAddTrackers;
+ function CopyUserInputNewTrackersToList(Temporary_SkipAnnounceCheck: boolean =
+ False): boolean;
+ procedure LoadTrackersTextFileAddTrackers(Temporary_SkipAnnounceCheck: boolean);
procedure LoadTrackersTextFileRemoveTrackers;
- function ValidTrackerURL(const TrackerURL: UTF8String): boolean;
public
{ public declarations }
end;
@@ -246,37 +204,21 @@ TFormTrackerModify = class(TForm)
implementation
-uses LCLIntf, lazutf8;
+uses fphttpclient, LCLIntf, lazutf8, LazFileUtils, trackerlist_online;
const
RECOMENDED_TRACKERS: array[0..2] of UTF8String =
(
- 'udp://tracker.openbittorrent.com:80/announce',
- 'udp://tracker.publicbt.com:80/announce',
- 'udp://tracker.istole.it:80/announce'
- // 'udp://open.demonii.com:1337/announce'
+ 'udp://tracker.coppersurfer.tk:6969/announce',
+ 'udp://tracker.opentrackr.org:1337/announce',
+ 'wss://tracker.openwebtorrent.com'
);
+
//program name and version (http://semver.org/)
- FORM_CAPTION = 'Bittorrent tracker editor (1.32.0-RC.4)';
- TORRENT_FILES_CONTENTS_FORM_CAPTION =
- 'Show all the files inside the torrents. (Use right mouse for popup menu.)';
+ FORM_CAPTION = 'Bittorrent tracker editor (1.33.0.beta.6)';
GROUPBOX_PRESENT_TRACKERS_CAPTION =
- 'Present trackers in all torrent files. Select the one that you want to keep. And added to all torrent files.';
-
-
- //'add trackers' text file must be place in the same directory as the program.
- ADD_TRACKERS_FILE_NAME = 'add_trackers.txt';
-
- //'remove trackers' text file must be place in the same directory as the program.
- REMOVE_TRACKERS_FILE_NAME = 'remove_trackers.txt';
-
- //'export trackers' text file wil be created in the same directory as the program.
- EXPORT_TRACKERS_FILE_NAME = 'export_trackers.txt';
-
- //'log' text file will be saved in the same directory as the program
- // only in the console mode.
- LOG_FILE_NAME = 'console_log.txt';
+ 'Present trackers in all torrent files. Select the one that you want to keep. And added to all torrent files.';
{$R *.lfm}
@@ -284,85 +226,151 @@ implementation
procedure TFormTrackerModify.FormCreate(Sender: TObject);
begin
+ //Test the working for SSL connection
+ if TestConnectionSSL then
+ begin
+ // shutdown the GUI program
+ Application.terminate;
+ Exit;
+ end;
+
+ {$IFDEF LINUX}
+ // if a ubuntu snap program then save it to other place
+ FFolderForTrackerListLoadAndSave := GetEnvironmentVariable('SNAP_USER_COMMON');
+ if FFolderForTrackerListLoadAndSave = '' then
+ begin
+ // NOT a snap program
+ FFolderForTrackerListLoadAndSave := ExtractFilePath(Application.ExeName);
+ end
+ else
+ begin
+ // A snap program
+ FFolderForTrackerListLoadAndSave := AppendPathDelim(FFolderForTrackerListLoadAndSave);
+ end;
+ {$ELSE}
+ // Save at the same place as the application file
+ FFolderForTrackerListLoadAndSave := ExtractFilePath(Application.ExeName);
+ {$ENDIF}
//Create controler for StringGridTorrentData
FControlerGridTorrentData := TControlerGridTorrentData.Create(StringGridTorrentData);
+ // Default there is an announce check
+ FTrackerList.SkipAnnounceCheck := False;
+
+ // Default do not add source tag to the info.
+ FTrackerList.SourceTag := '';
+
//Log file output string List.
- FLogStringList := TStringList.Create;
+ FTrackerList.LogStringList := TStringList.Create;
//Create filename list for all the torrent files.
- FTorrentFileNameList := TStringList.Create;
- FTorrentFileNameList.Duplicates := dupIgnore;
+ FTrackerList.TorrentFileNameList := TStringList.Create;
+ FTrackerList.TorrentFileNameList.Duplicates := dupIgnore;
//Must NOT be sorted. Must in sync with CheckListBoxPublicPrivateTorrent.
- FTorrentFileNameList.Sorted := False;
+ FTrackerList.TorrentFileNameList.Sorted := False;
//Create ban tracker list where the user can manualy add items to it.
- FTrackerBanByUserList := TStringList.Create;
- FTrackerBanByUserList.Duplicates := dupIgnore;
- FTrackerBanByUserList.Sorted := False;
+ FTrackerList.TrackerBanByUserList := TStringList.Create;
+ FTrackerList.TrackerBanByUserList.Duplicates := dupIgnore;
+ FTrackerList.TrackerBanByUserList.Sorted := False;
- //Create deselect tracker list where the user select via user interface checkbox
- FTrackerManualyDeselectedByUserList := TStringList.Create;
- FTrackerManualyDeselectedByUserList.Duplicates := dupIgnore;
- FTrackerManualyDeselectedByUserList.Sorted := False;
+ //Create deselect tracker list where the user select via user interface CheckBoxRemoveAllSourceTag
+ FTrackerList.TrackerManualyDeselectedByUserList := TStringList.Create;
+ FTrackerList.TrackerManualyDeselectedByUserList.Duplicates := dupIgnore;
+ FTrackerList.TrackerManualyDeselectedByUserList.Sorted := False;
//Create tracker list where the user can manualy add items to it
- FTrackerAddedByUserList := TStringList.Create;
- FTrackerAddedByUserList.Duplicates := dupIgnore;
+ FTrackerList.TrackerAddedByUserList := TStringList.Create;
+ FTrackerList.TrackerAddedByUserList.Duplicates := dupIgnore;
//Trackers List added by user must keep in the same order.
- FTrackerAddedByUserList.Sorted := False;
+ FTrackerList.TrackerAddedByUserList.Sorted := False;
//drag and drop tracker list will accept duplicates in memo text, if false. Need to check out why.
//Create tracker list where all the trackers from all the torrent files are collected
- FTrackerFromInsideTorrentFilesList := TStringList.Create;
- FTrackerFromInsideTorrentFilesList.Duplicates := dupIgnore;
+ FTrackerList.TrackerFromInsideTorrentFilesList := TStringList.Create;
+ FTrackerList.TrackerFromInsideTorrentFilesList.Duplicates := dupIgnore;
//Must be sorted. is visible to user. In tracker list tab page.
- FTrackerFromInsideTorrentFilesList.Sorted := True;
+ FTrackerList.TrackerFromInsideTorrentFilesList.Sorted := True;
//Create tracker list that combine all other together.
- FTrackerFinalList := TStringList.Create;
- FTrackerFinalList.Duplicates := dupIgnore;
+ FTrackerList.TrackerFinalList := TStringList.Create;
+ FTrackerList.TrackerFinalList.Duplicates := dupIgnore;
//must NOT be sorted. Must keep the original order intact.
- FTrackerFinalList.Sorted := False;
-
+ FTrackerList.TrackerFinalList.Sorted := False;
//Decoding class for torrent.
FDecodePresentTorrent := TDecodeTorrent.Create;
+ //Create view for trackerURL with CheckBoxRemoveAllSourceTag
+ FControlerTrackerListOnline :=
+ TControlerTrackerListOnline.Create(StringGridTrackerOnline,
+ FTrackerList.TrackerFromInsideTorrentFilesList, @TrackerWithURLAndAnnounce);
+
+ //Create view for treeview data of all the torrent files
+ Fcontroler_treeview_torrent_data :=
+ Tcontroler_treeview_torrent_data.Create(TabSheetTorrentsContents);
+
//start the program at mimimum visual size. (this is optional)
Width := Constraints.MinWidth;
Height := Constraints.MinHeight;
+ //there must be two command line or more for a console mode.
+ //one is for drag and drop via shortcut in windows mode.
+ FConsoleMode := ParamCount >= 2;
+ FDragAndDropStartUp := ParamCount = 1;
+
//Show the default trackers
- LoadTrackersTextFileAddTrackers;
+ LoadTrackersTextFileAddTrackers(True);
//Load the unwanted trackers list.
LoadTrackersTextFileRemoveTrackers;
- //Check is program is started as console
- ConsoleMode;
+ //Create download for ngosang tracker list
+ FngosangTrackerList := TngosangTrackerList.Create;
+
+ //Start program in console mode ( >= 2)
+ //or in windows mode via shortcut with drag/drop ( = 1)
+ if ParamCount > 0 then
+ begin
+ ConsoleModeOrDragAndDropStartupMode;
+ end;
+
+ //There should be no more exception made for the drag and drop
+ FDragAndDropStartUp := False;
//Update some captions
- Caption := FORM_CAPTION;
- GroupBoxTorrentContents.Caption := TORRENT_FILES_CONTENTS_FORM_CAPTION;
- GroupBoxPresentTracker.Caption := GROUPBOX_PRESENT_TRACKERS_CAPTION
+ ViewUpdateFormCaption;
+ GroupBoxPresentTracker.Caption := GROUPBOX_PRESENT_TRACKERS_CAPTION;
+end;
+procedure TFormTrackerModify.CheckBoxSkipAnnounceCheckChange(Sender: TObject);
+begin
+ FTrackerList.SkipAnnounceCheck := CheckBoxSkipAnnounceCheck.Checked;
+ ViewUpdateFormCaption;
+end;
+
+procedure TFormTrackerModify.CheckBoxRemoveAllSourceTagChange(Sender: TObject);
+begin
+ FTrackerList.RemoveAllSourceTag := TCheckBox(Sender).Checked;
+ LabeledEditInfoSource.Enabled := not FTrackerList.RemoveAllSourceTag;
end;
procedure TFormTrackerModify.FormDestroy(Sender: TObject);
begin
//The program is being closed. Free all the memory.
- FLogStringList.Free;
- FTrackerFinalList.Free;
+ FngosangTrackerList.Free;
+ FTrackerList.LogStringList.Free;
+ FTrackerList.TrackerFinalList.Free;
FDecodePresentTorrent.Free;
- FTrackerAddedByUserList.Free;
- FTrackerBanByUserList.Free;
- FTrackerFromInsideTorrentFilesList.Free;
- FTorrentFileNameList.Free;
+ FTrackerList.TrackerAddedByUserList.Free;
+ FTrackerList.TrackerBanByUserList.Free;
+ FTrackerList.TrackerFromInsideTorrentFilesList.Free;
+ FTrackerList.TorrentFileNameList.Free;
FControlerGridTorrentData.Free;
- FTrackerManualyDeselectedByUserList.Free;
+ FTrackerList.TrackerManualyDeselectedByUserList.Free;
+ FControlerTrackerListOnline.Free;
end;
procedure TFormTrackerModify.MenuFileTorrentFolderClick(Sender: TObject);
@@ -386,100 +394,228 @@ procedure TFormTrackerModify.MenuHelpVisitWebsiteClick(Sender: TObject);
OpenURL('https://github.com/GerryFerdinandus/bittorrent-tracker-editor');
end;
-procedure TFormTrackerModify.MenuItemTorrentFilesTreeHideAllClick(Sender: TObject);
-var
- i, CountTorrents: integer;
+procedure TFormTrackerModify.MenuHelpVisitNgosangClick(Sender: TObject);
begin
- //Show only torrent file names
+ //newTrackon trackers is being used in this program.
+ OpenURL('https://github.com/ngosang/trackerslist');
+end;
- //user what to hide all the items.
- //All the popup menu item must first be unchecked.
- MenuItemTorrentFilesTreeShowInfo.Checked := False;
- MenuItemTorrentFilesTreeShowFiles.Checked := False;
- MenuItemTorrentFilesTreeShowTrackers.Checked := False;
- //Update the TorrentFilesTree
- // MenuItemTorrentFilesTreeSyncWithPopupMenu;
+procedure TFormTrackerModify.MenuItemNgosangAppendAllBestIpClick(Sender: TObject);
+begin
+ AppendTrackersToMemoNewTrackers(FngosangTrackerList.TrackerList_Best_IP);
+end;
- if not assigned(FTreeNodeRoot) then
- exit;
+procedure TFormTrackerModify.MenuItemNgosangAppendAllClick(Sender: TObject);
+begin
+ AppendTrackersToMemoNewTrackers(FngosangTrackerList.TrackerList_All);
+end;
- //how many torrent files are there.
- CountTorrents := FTreeNodeRoot.Count;
- if CountTorrents = 0 then
- exit;
+procedure TFormTrackerModify.MenuItemNgosangAppendAllHttpClick(Sender: TObject);
+begin
+ AppendTrackersToMemoNewTrackers(FngosangTrackerList.TrackerList_All_HTTP);
+end;
- //Show the torrent files names only.
- for i := 0 to CountTorrents - 1 do
- begin
- FTreeNodeRoot.Items[i].Collapse(True);
+procedure TFormTrackerModify.MenuItemNgosangAppendAllHttpsClick(Sender: TObject);
+begin
+ AppendTrackersToMemoNewTrackers(FngosangTrackerList.TrackerList_All_HTTPS);
+end;
+
+procedure TFormTrackerModify.MenuItemNgosangAppendAllIpClick(Sender: TObject);
+begin
+ AppendTrackersToMemoNewTrackers(FngosangTrackerList.TrackerList_All_IP);
+end;
+
+procedure TFormTrackerModify.MenuItemNgosangAppendAllUdpClick(Sender: TObject);
+begin
+ AppendTrackersToMemoNewTrackers(FngosangTrackerList.TrackerList_All_UDP);
+end;
+
+procedure TFormTrackerModify.MenuItemNgosangAppendAllWsClick(Sender: TObject);
+begin
+ AppendTrackersToMemoNewTrackers(FngosangTrackerList.TrackerList_All_WS);
+end;
+
+procedure TFormTrackerModify.MenuItemNgosangAppendBestClick(Sender: TObject);
+begin
+ AppendTrackersToMemoNewTrackers(FngosangTrackerList.TrackerList_Best);
+end;
+
+procedure TFormTrackerModify.MenuItemOnlineCheckSubmitNewTrackonClick(Sender: TObject);
+var
+ SendStatus: boolean;
+ TrackerSendCount: integer;
+ PopupStr: string;
+begin
+ try
+ screen.Cursor := crHourGlass;
+ SendStatus := FControlerTrackerListOnline.SubmitTrackers(
+ FTrackerList.TrackerFromInsideTorrentFilesList, TrackerSendCount);
+ finally
+ screen.Cursor := crDefault;
end;
+ if SendStatus then
+ begin
+ //Succesful upload
+ PopupStr := format('Successful upload of %d unique tracker URL', [TrackerSendCount]);
+ Application.MessageBox(
+ PChar(@PopupStr[1]),
+ '', MB_ICONINFORMATION + MB_OK);
+ end
+ else
+ begin
+ //something is wrong with uploading
+ ShowUserErrorMessage('Can not uploading the tracker list');
+ end;
end;
-procedure TFormTrackerModify.MenuItemTorrentFilesTreeShowAllClick(Sender: TObject);
+procedure TFormTrackerModify.AppendTrackersToMemoNewTrackers(TrackerList: TStringList);
+var
+ tracker: UTF8String;
begin
- //show everything
- if assigned(FTreeNodeRoot) then
- FTreeNodeRoot.Expand(True);
-
- //user what to see all the items.
- //All the popup menu item must first be checked.
- MenuItemTorrentFilesTreeShowInfo.Checked := True;
- MenuItemTorrentFilesTreeShowFiles.Checked := True;
- MenuItemTorrentFilesTreeShowTrackers.Checked := True;
- //Update the TorrentFilesTree
- // MenuItemTorrentFilesTreeSyncWithPopupMenu;
+ //Append all the trackers to MemoNewTrackers
+ MemoNewTrackers.Lines.BeginUpdate;
+ for Tracker in TrackerList do
+ begin
+ MemoNewTrackers.Lines.Add(tracker);
+ end;
+ MemoNewTrackers.Lines.EndUpdate;
+
+ //Check for error in tracker list
+ if not CopyUserInputNewTrackersToList then
+ begin
+ MemoNewTrackers.Lines.Clear;
+ end;
end;
-procedure TFormTrackerModify.MenuItemTorrentFilesTreeShowOrHideItemClick(
+procedure TFormTrackerModify.MenuItemOnlineCheckAppendStableTrackersClick(
Sender: TObject);
-var
- i, CountTorrents, itemsNr: integer;
- ShowNode: boolean;
begin
- //Show or hide all the items below the torrent files.
+ //User want to use the downloaded tracker list.
- //Get the top node.
- if not assigned(FTreeNodeRoot) then
- exit;
+ //check if tracker is already downloaded
+ if not FDownloadStatus then
+ begin
+ //Download it now.
+ MenuItemOnlineCheckDownloadNewTrackonClick(nil);
+ end;
- //how many torrent files are there.
- CountTorrents := FTreeNodeRoot.Count;
- if CountTorrents = 0 then
- exit;
+ //Append all the trackers to MemoNewTrackers
+ AppendTrackersToMemoNewTrackers(FControlerTrackerListOnline.StableTrackers);
+end;
- //The tag number define if it is for files, trackers or info items
- itemsNr := TMenuItem(Sender).tag;
+procedure TFormTrackerModify.MenuItemOnlineCheckDownloadNewTrackonClick(
+ Sender: TObject);
+begin
+ try
+ screen.Cursor := crHourGlass;
+ FDownloadStatus := FControlerTrackerListOnline.DownloadTrackers_All_Live_Stable;
+ finally
+ screen.Cursor := crDefault;
+ end;
- //Must show or hide the items
- ShowNode := TMenuItem(Sender).Checked;
+ if not FDownloadStatus then
+ begin
+ //something is wrong with downloading
+ ShowUserErrorMessage('Can not downloading the trackers from internet');
+ end;
+end;
- //process all the torrent files one by one.
- for i := 0 to CountTorrents - 1 do
+function TFormTrackerModify.CheckForAnnounce(const TrackerURL: UTF8String): boolean;
+begin
+ Result := (not FTrackerList.SkipAnnounceCheck) and
+ (not WebTorrentTrackerURL(TrackerURL)) and (not FDragAndDropStartUp);
+end;
+
+procedure TFormTrackerModify.ShowUserErrorMessage(const ErrorText: string;
+ const FormText: string);
+begin
+ if FConsoleMode then
begin
- if ShowNode then
- begin
- FTreeNodeRoot.Items[i].Expand(False); //Show the torrent name + child
- FTreeNodeRoot.Items[i].Items[itemsNr].Expand(False); //expand child
- end
+ if FormText = '' then
+ FTrackerList.LogStringList.Add(ErrorText)
+ else
+ FTrackerList.LogStringList.Add(FormText + ' : ' + ErrorText);
+ end
+ else
+ begin
+ if FormText = '' then
+ Application.MessageBox(PChar(@ErrorText[1]), '', MB_ICONERROR)
else
+ Application.MessageBox(PChar(@ErrorText[1]), PChar(@FormText[1]), MB_ICONERROR);
+ end;
+end;
+
+function TFormTrackerModify.TrackerWithURLAndAnnounce(
+ const TrackerURL: UTF8String): boolean;
+begin
+ //Validate the begin of the URL
+ Result := ValidTrackerURL(TrackerURL);
+ if Result then
+ begin
+ if CheckForAnnounce(TrackerURL) then
begin
- FTreeNodeRoot.Items[i].Items[itemsNr].Collapse(False);
+ Result := TrackerURLWithAnnounce(TrackerURL);
end;
end;
end;
+procedure TFormTrackerModify.MenuTrackersDeleteTrackersWithStatusClick(
+ Sender: TObject);
+
+ procedure UncheckTrackers(Value: TTrackerListOnlineStatus);
+ var
+ i: integer;
+ begin
+ if FControlerTrackerListOnline.Count > 0 then
+ begin
+ for i := 0 to FControlerTrackerListOnline.Count - 1 do
+ begin
+ if FControlerTrackerListOnline.TrackerStatus(i) = Value then
+ begin
+ FControlerTrackerListOnline.Checked[i] := False;
+ end;
+ end;
+ end;
+ end;
+
+begin
+ //check if tracker is already downloaded
+ if not FDownloadStatus then
+ begin
+ MenuItemOnlineCheckDownloadNewTrackonClick(nil);
+ end;
+
+ //0 = Unstable
+ //1 = Dead
+ //2 = Unknown
+ case TMenuItem(Sender).Tag of
+ 0: UncheckTrackers(tos_live_but_unstable);
+ 1: UncheckTrackers(tos_dead);
+ 2: UncheckTrackers(tos_unknown);
+ else
+ Assert(True, 'Unknown Menu item selection')
+ end;
+end;
+
+procedure TFormTrackerModify.MenuUpdateRandomizeClick(Sender: TObject);
+begin
+ //User can select to randomize the tracker list
+ FTrackerList.TrackerListOrderForUpdatedTorrent := tloRandomize;
+ UpdateTorrent;
+end;
+
procedure TFormTrackerModify.UpdateTorrent;
var
Reply, BoxStyle, i, CountTrackers: integer;
PopUpMenuStr: string;
- SomeFilesCannotBeWriten, SomeFilesAreReadOnly: boolean;
+ SomeFilesCannotBeWriten, SomeFilesAreReadOnly, AllFilesAreReadBackCorrectly: boolean;
begin
//Update all the torrent files.
//The StringGridTorrentData where the comment are place by user
- // must be in sync again with FTorrentFileNameList.
+ // must be in sync again with FTrackerList.TorrentFileNameList.
//Undo all posible sort column used by the user. Sort it back to 'begin state'
FControlerGridTorrentData.ReorderGrid;
@@ -488,7 +624,7 @@ procedure TFormTrackerModify.UpdateTorrent;
try
- if not FConcoleMode then
+ if not FConsoleMode then
begin
//Warn user before updating the torrent
BoxStyle := MB_ICONWARNING + MB_OKCANCEL;
@@ -503,17 +639,9 @@ procedure TFormTrackerModify.UpdateTorrent;
//Must have some torrent selected
- if (FTorrentFileNameList.Count = 0) then
+ if (FTrackerList.TorrentFileNameList.Count = 0) then
begin
- if FConcoleMode then
- begin
- FLogStringList.Add('ERROR: No torrent file selected');
- end
- else
- begin
- Application.MessageBox('No torrent file selected',
- '', MB_ICONERROR);
- end;
+ ShowUserErrorMessage('ERROR: No torrent file selected');
ShowHourGlassCursor(True);
exit;
end;
@@ -521,22 +649,23 @@ procedure TFormTrackerModify.UpdateTorrent;
//User must wait for a while.
ShowHourGlassCursor(True);
- //Copy the tracker list inside torrent -> FTrackerFromInsideTorrentFilesList
+ //Copy the tracker list inside torrent -> FTrackerList.TrackerFromInsideTorrentFilesList
UpdateTrackerInsideFileList;
- //Check for error in user tracker list -> FTrackerAddedByUserList
+ //Check for error in user tracker list -> FTrackerList.TrackerAddedByUserList
if not CopyUserInputNewTrackersToList then
Exit;
//There are 5 list that must be combine.
//Must use 'sort' for correct FTrackerFinalList.Count
- CombineFiveTrackerListToOne(tloSort);
+ CombineFiveTrackerListToOne(tloSort, FTrackerList,
+ FDecodePresentTorrent.TrackerList);
//How many trackers must be put inside each torrent file.
- CountTrackers := FTrackerFinalList.Count;
+ CountTrackers := FTrackerList.TrackerFinalList.Count;
//In console mode we can ignore this warning
- if not FConcoleMode and (CountTrackers = 0) then
+ if not FConsoleMode 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(
@@ -554,32 +683,39 @@ procedure TFormTrackerModify.UpdateTorrent;
//initial value is false, will be set to true if read only files are found
SomeFilesAreReadOnly := False;
+ if FTrackerList.TrackerListOrderForUpdatedTorrent = tloRandomize then
+ begin
+ Randomize;
+ end;
+
//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
+ //FTrackerList.TorrentFileNameList is not sorted it is still in sync with CheckListBoxPublicPrivateTorrent
+ for i := 0 to FTrackerList.TorrentFileNameList.Count - 1 do
begin //read the torrent file in FDecodePresentTorrent and modify it.
//check for read only files. It can not be updated by tracker editor
- if (FileGetAttr(FTorrentFileNameList[i]) and faReadOnly) <> 0 then
+ if (FileGetAttr(FTrackerList.TorrentFileNameList[i]) and faReadOnly) <> 0 then
begin
SomeFilesAreReadOnly := True;
Continue;
end;
//read one torrent file. If error then skip it. (continue)
- if not FDecodePresentTorrent.DecodeTorrent(FTorrentFileNameList[i]) then
+ if not FDecodePresentTorrent.DecodeTorrent(
+ FTrackerList.TorrentFileNameList[i]) then
begin
Continue;
end;
//tloSort it is already process. But if not tloSort then process it.
- if FTrackerListOrderForUpdatedTorrent <> tloSort then
+ if FTrackerList.TrackerListOrderForUpdatedTorrent <> tloSort then
begin
//Add the new tracker before of after the original trackers inside the torrent.
- CombineFiveTrackerListToOne(FTrackerListOrderForUpdatedTorrent);
+ CombineFiveTrackerListToOne(FTrackerList.TrackerListOrderForUpdatedTorrent,
+ FTrackerList, FDecodePresentTorrent.TrackerList);
//How many trackers must be put inside each torrent file
- CountTrackers := FTrackerFinalList.Count;
+ CountTrackers := FTrackerList.TrackerFinalList.Count;
end;
case CountTrackers of
@@ -591,45 +727,66 @@ procedure TFormTrackerModify.UpdateTorrent;
1://if one tracker selected then delete 'announce-list'
begin
//Announce use the only tracker present in the FTrackerFinalList. index 0
- FDecodePresentTorrent.ChangeAnnounce(FTrackerFinalList[0]);
+ FDecodePresentTorrent.ChangeAnnounce(FTrackerList.TrackerFinalList[0]);
FDecodePresentTorrent.RemoveAnnounceList;
end;
else//More than 1 trackers selected. Create 'announce-list'
begin
//Announce use the first tracker from the list. index 0
- FDecodePresentTorrent.ChangeAnnounce(FTrackerFinalList[0]);
- FDecodePresentTorrent.ChangeAnnounceList(FTrackerFinalList);
+ FDecodePresentTorrent.ChangeAnnounce(FTrackerList.TrackerFinalList[0]);
+ FDecodePresentTorrent.ChangeAnnounceList(FTrackerList.TrackerFinalList);
end;
end;
//update the torrent public/private flag
if CheckListBoxPublicPrivateTorrent.Checked[i] then
begin
+ //Create a public torrent
//if private torrent then make it public torrent by removing the private flag.
if FDecodePresentTorrent.PrivateTorrent then
FDecodePresentTorrent.RemovePrivateTorrentFlag;
end
else
begin
+ //Create a private torrent
FDecodePresentTorrent.AddPrivateTorrentFlag;
end;
//update the comment item
FDecodePresentTorrent.Comment := FControlerGridTorrentData.ReadComment(i + 1);
+ //Update the source tag for private trackers
+ if FTrackerList.RemoveAllSourceTag then
+ begin
+ // This will delete info:source item
+ FDecodePresentTorrent.InfoSourceRemove;
+ end
+ else
+ begin
+ // Copy the new source tag, but it must not be empty.
+ // Empty FTrackerList.SourceTag is the same as do not change anything.
+ if FTrackerList.SourceTag <> '' then
+ begin
+ FDecodePresentTorrent.InfoSourceAdd(FTrackerList.SourceTag);
+ end;
+ end;
+
//save the torrent file.
- if not FDecodePresentTorrent.SaveTorrent(FTorrentFileNameList[i]) then
+ if not FDecodePresentTorrent.SaveTorrent(FTrackerList.TorrentFileNameList[i]) then
begin
SomeFilesCannotBeWriten := True;
end;
end;//for
+ // Can not create a file inside the app
+ {$IFNDEF DARWIN}
//Create tracker.txt file
SaveTrackerFinalListToFile;
+ {$ENDIF}
//Show/reload the just updated torrent files.
- ReloadAllTorrentAndRefreshView;
+ AllFilesAreReadBackCorrectly := ReloadAllTorrentAndRefreshView;
//make sure cursor is default again
finally
@@ -638,23 +795,30 @@ procedure TFormTrackerModify.UpdateTorrent;
end;
- if FConcoleMode then
+ if FConsoleMode then
begin
//When succesfull the log file shows, 3 lines,
// OK + Count torrent files + Count Trackers
- FLogStringList.Add('OK');
- FLogStringList.Add(IntToStr(FTorrentFileNameList.Count));
- FLogStringList.Add(IntToStr(CountTrackers));
+
+ //if there is already a items inside there there must be something wrong.
+ //Do not add 'OK'
+ if FTrackerList.LogStringList.Count = 0 then
+ begin
+ FTrackerList.LogStringList.Add(CONSOLE_SUCCESS_STATUS);
+ FTrackerList.LogStringList.Add(IntToStr(FTrackerList.TorrentFileNameList.Count));
+ FTrackerList.LogStringList.Add(IntToStr(CountTrackers));
+ end;
end
else
begin
- case FTrackerListOrderForUpdatedTorrent of
+ case FTrackerList.TrackerListOrderForUpdatedTorrent of
tloInsertNewBeforeAndKeepNewIntact,
tloInsertNewBeforeAndKeepOriginalIntact,
tloAppendNewAfterAndKeepNewIntact,
tloAppendNewAfterAndKeepOriginalIntact,
- tloSort:
+ tloSort,
+ tloRandomize:
begin
//Via popup show user how many trackers are inside the torrent after update.
PopUpMenuStr := 'All torrent file(s) have now ' + IntToStr(CountTrackers) +
@@ -674,6 +838,16 @@ procedure TFormTrackerModify.UpdateTorrent;
end;//case
+
+ //Check if there are some error that need to be notify to the end user.
+
+ if not AllFilesAreReadBackCorrectly then
+ begin
+ //add warning if torrent files can not be read back again
+ PopUpMenuStr := PopUpMenuStr +
+ ' WARNING: Some torrent files can not be read back again after updating.';
+ end;
+
if SomeFilesAreReadOnly then
begin
//add warning if read only files are detected.
@@ -697,60 +871,15 @@ procedure TFormTrackerModify.UpdateTorrent;
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
- //not sorted version
- if StringList.IndexOf(Str) < 0 then
- begin
- StringList.add(Str);
- end;
- end
- else
- begin
- //sorted version
- StringList.add(Str);
- end;
-
-end;
-
-
-function TFormTrackerModify.ByteSizeToBiggerSizeFormatStr(ByteSize: int64): string;
-begin
- if ByteSize >= (1024 * 1024 * 1024) then
- Result := Format('%0.2f GiB', [ByteSize / (1024 * 1024 * 1024)])
- else
- if ByteSize >= (1024 * 1024) then
- Result := Format('%0.2f MiB', [ByteSize / (1024 * 1024)])
- else
- if ByteSize >= (1024) then
- Result := Format('%0.2f KiB', [ByteSize / 1024]);
- Result := Result + Format(' (%d Bytes)', [ByteSize]);
-
-end;
-
-
-
-procedure TFormTrackerModify.MenuItemTorrentFilesTreeSyncWithPopupMenu;
-begin
- MenuItemTorrentFilesTreeShowOrHideItemClick(MenuItemTorrentFilesTreeShowTrackers);
- MenuItemTorrentFilesTreeShowOrHideItemClick(MenuItemTorrentFilesTreeShowInfo);
- MenuItemTorrentFilesTreeShowOrHideItemClick(MenuItemTorrentFilesTreeShowFiles);
-end;
-
procedure TFormTrackerModify.SaveTrackerFinalListToFile;
var
TrackerStr: UTF8String;
begin
//Create the tracker text file. The old one will be overwritten
- AssignFile(FTrackerFile, ExtractFilePath(Application.ExeName) +
- EXPORT_TRACKERS_FILE_NAME);
+ AssignFile(FTrackerFile, FFolderForTrackerListLoadAndSave + FILE_NAME_EXPORT_TRACKERS);
ReWrite(FTrackerFile);
- for TrackerStr in FTrackerFinalList do
+ for TrackerStr in FTrackerList.TrackerFinalList do
begin
WriteLn(FTrackerFile, TrackerStr);
@@ -763,28 +892,35 @@ procedure TFormTrackerModify.SaveTrackerFinalListToFile;
CloseFile(FTrackerFile);
end;
-procedure TFormTrackerModify.ConsoleMode;
+procedure TFormTrackerModify.ConsoleModeOrDragAndDropStartupMode;
var
FileNameOrDirStr: UTF8String;
StringList: TStringList;
+ MustExitWithErrorCode: boolean;
begin
- //if program is started with one parameter then in must be stated console mode.
- //This parameter is path to file or dir.
+ // There are two options
+ //-
+ // One parameter only. Program startup via DragAndDrop
+ // The first parameter[1] is path to file or dir.
- //update the torrent via console mode if there is a parameter detected.
- if ParamCount > 0 then
- begin
- FConcoleMode := True;
+ //-
+ // Two parameter version. Always console mode.
+ // This is later version where there is more selection about the tracker list.
- //Create the log file. The old one will be overwritten
- AssignFile(FLogFile, ExtractFilePath(Application.ExeName) + LOG_FILE_NAME);
- ReWrite(FLogFile);
+ //Will be set to True when error occure.
+ MustExitWithErrorCode := False;
+ ViewUpdateBegin;
- //Get the console parameters.
- ConsoleModeDecodeParameter(FileNameOrDirStr);
+ try
+ if FConsoleMode then
+ begin
+ //Create the log file. The old one will be overwritten
+ AssignFile(FLogFile, FFolderForTrackerListLoadAndSave + FILE_NAME_CONSOLE_LOG);
+ ReWrite(FLogFile);
+ end;
- //If FLogStringList empty then there is no error.
- if FLogStringList.Text = '' then
+ //Get the startup command lime parameters.
+ if ConsoleModeDecodeParameter(FileNameOrDirStr, FTrackerList) then
begin
//There is no error. Proceed with reading the torrent files
@@ -794,15 +930,24 @@ procedure TFormTrackerModify.ConsoleMode;
begin
//Show all the tracker inside the torrent files.
ShowTrackerInsideFileList;
- //Mark all trackers as selected
- CheckedOnOffAllTrackers(True);
//Some tracker must be removed. Console and windows mode.
UpdateViewRemoveTracker;
- //update torrent
- UpdateTorrent;
+
+ if FConsoleMode then
+ begin
+ //update torrent
+ UpdateTorrent;
+ end;
+
+ end
+ else
+ begin
+ //failed to load the torrent via folders
+ ShowUserErrorMessage('Can not load torrent via folder');
end;
+
end
- else //a torrent file is selected?
+ else //a single torrent file is selected?
begin
if ExtractFileExt(FileNameOrDirStr) = '.torrent' then
begin
@@ -810,138 +955,79 @@ procedure TFormTrackerModify.ConsoleMode;
try
//Convert Filenames to stringlist format.
StringList.Add(FileNameOrDirStr);
- AddTorrentFileList(StringList);
-
- //Show all the tracker inside the torrent files.
- ShowTrackerInsideFileList;
- //Mark all trackers as selected
- CheckedOnOffAllTrackers(True);
- //Some tracker must be removed. Console and windows mode.
- UpdateViewRemoveTracker;
- //update torrent
- UpdateTorrent;
+
+ //Extract all the trackers inside the torrent file
+ if AddTorrentFileList(StringList) then
+ begin
+ //Show all the tracker inside the torrent files.
+ ShowTrackerInsideFileList;
+ //Some tracker must be removed. Console and windows mode.
+ UpdateViewRemoveTracker;
+
+ if FConsoleMode then
+ begin
+ //update torrent
+ UpdateTorrent;
+ end;
+
+ end
+ else
+ begin
+ //failed to load one torrent
+ ShowUserErrorMessage('Can not load torrent file.');
+ end;
+
finally
StringList.Free;
end;
end
else
begin //Error. this is not a torrent file
- FLogStringList.Add('ERROR: No torrent file selected.');
+ ShowUserErrorMessage('ERROR: No torrent file selected.');
end;
end;
end;
- //Write to log file. And close the file.
- WriteLn(FLogFile, FLogStringList.Text);
- CloseFile(FLogFile);
-
- //Shutdown the console program
- Application.terminate;
- end
- else
- begin //the program
- FConcoleMode := False;
- end;
-
-end;
-
-
-function TFormTrackerModify.ConsoleModeDecodeParameter(
- out FileNameOrDirStr: UTF8String): boolean;
-begin
- {
- Console mode can be started with 2 parameter
- Update methode: -U0 , -U1, -U2, -U3, -U4
- String with a link to folder or to torrent file. 'C:\dir'
-
- }
-
- case Paramcount of
- 0:
+ if FConsoleMode then
begin
- FLogStringList.Add('ERROR: There are no parameter detected.');
- Result := False;
- exit;
- end;
- 1:
- begin
- //one parameter. Must be a link.
- FileNameOrDirStr := UTF8Trim(ParamStr(1));
- //Keep the same behaviour as the previeus software version.
- FTrackerListOrderForUpdatedTorrent := tloSort;
- Result := True;
- end;
- 2:
- begin
- //Two parameters. The user can select the update methode.
- //Check for '-U' contruction as first parameter
- if (Pos('-U', ParamStr(1)) = 1) then
- begin
- //Update parameter is the first parameter
- Result := DecodeConsoleUpdateParameter(ParamStr(1));
- FileNameOrDirStr := UTF8Trim(ParamStr(2));
- end
- else
+ //Write to log file. And close the file.
+ WriteLn(FLogFile, FTrackerList.LogStringList.Text);
+ CloseFile(FLogFile);
+
+ //check if log data is success full
+ //if (no data) or (not CONSOLE_SUCCESS_STATUS) then error
+ MustExitWithErrorCode := FTrackerList.LogStringList.Count = 0;
+ if not MustExitWithErrorCode then
begin
- //Update parameter is the second parameter
- Result := DecodeConsoleUpdateParameter(ParamStr(2));
- FileNameOrDirStr := UTF8Trim(ParamStr(1));
+ MustExitWithErrorCode := FTrackerList.LogStringList[0] <> CONSOLE_SUCCESS_STATUS;
end;
-
- end;
- else
- begin
- FLogStringList.Add('ERROR: There can only be maximum of 2 parameter. Not: ' +
- IntToStr(ParamCount));
- Result := False;
- exit;
end;
- end;
-end;
-function TFormTrackerModify.DecodeConsoleUpdateParameter(
- ConsoleUpdateParameter: UTF8String): boolean;
-var
- i: integer;
-begin
- //Decode the '-Ux' x is number [0..4]
+ except
+ //Shutdown the console program.
+ //This is needed or else the program will keep running forever.
+ //exit with error code
+ MustExitWithErrorCode := True;
+ end;
- //verify string content.
- Result := (Pos('-U', ConsoleUpdateParameter) = 1) and
- (length(ConsoleUpdateParameter) = 3);
+ ViewUpdateEnd;
- if Result then
+ if MustExitWithErrorCode then
begin
- //get the number
- Result := TryStrToInt(ConsoleUpdateParameter[3], i);
- if Result then
- begin
- //decode number [0..4]
- case i of
- 0: FTrackerListOrderForUpdatedTorrent := tloInsertNewBeforeAndKeepNewIntact;
- 1: FTrackerListOrderForUpdatedTorrent := tloInsertNewBeforeAndKeepOriginalIntact;
- 2: FTrackerListOrderForUpdatedTorrent := tloAppendNewAfterAndKeepNewIntact;
- 3: FTrackerListOrderForUpdatedTorrent := tloAppendNewAfterAndKeepOriginalIntact;
- 4: FTrackerListOrderForUpdatedTorrent := tloSort;
- 5: FTrackerListOrderForUpdatedTorrent := tloInsertNewBeforeAndKeepOriginalIntactAndRemoveNothing;
- 6: FTrackerListOrderForUpdatedTorrent := tloAppendNewAfterAndKeepOriginalIntactAndRemoveNothing;
- else
- begin
- //the number is out of range.
- Result := False;
- end;
- end;
- end;
+ //exit with error code
+ System.ExitCode := 1;
end;
- if not Result then
+ if FConsoleMode then
begin
- FLogStringList.Add('ERROR: can not decode update parameter -U : ' +
- ConsoleUpdateParameter);
+ //Always shutdown the program when in console mode.
+ Application.terminate;
end;
end;
+
+
procedure TFormTrackerModify.UpdateViewRemoveTracker;
var
TrackerStr: UTF8String;
@@ -955,7 +1041,8 @@ procedure TFormTrackerModify.UpdateViewRemoveTracker;
}
//If file remove_trackers.txt is present but empty then remove all tracker inside torrent.
- if FFilePresentBanByUserList and (UTF8Trim(FTrackerBanByUserList.Text) = '') then
+ if FFilePresentBanByUserList and
+ (UTF8Trim(FTrackerList.TrackerBanByUserList.Text) = '') then
begin
CheckedOnOffAllTrackers(False);
end;
@@ -967,17 +1054,18 @@ procedure TFormTrackerModify.UpdateViewRemoveTracker;
//remove all the trackers that are ban.
MemoNewTrackers.Lines.BeginUpdate;
- for TrackerStr in FTrackerBanByUserList do
+ for TrackerStr in FTrackerList.TrackerBanByUserList do
begin
- //uncheck tracker that are listed in FTrackerBanByUserList
- i := CheckListBoxTrackersList.Items.IndexOf(UTF8Trim(TrackerStr));
+ //uncheck tracker that are listed in FTrackerList.TrackerBanByUserList
+ //the FTrackerList.TrackerFromInsideTorrentFilesList is use in the view
+ i := FTrackerList.TrackerFromInsideTorrentFilesList.IndexOf(UTF8Trim(TrackerStr));
if i >= 0 then //Found it.
begin
- CheckListBoxTrackersList.Checked[i] := False;
+ FControlerTrackerListOnline.Checked[i] := False;
end;
- //remove tracker from user memo text that are listed in FTrackerBanByUserList
+ //remove tracker from user memo text that are listed in FTrackerList.TrackerBanByUserList
//Find TrackerStr in MemoNewTrackers.Lines and remove it.
i := MemoNewTrackers.Lines.IndexOf(UTF8Trim(TrackerStr));
if i >= 0 then //Found it.
@@ -1000,35 +1088,28 @@ function TFormTrackerModify.DecodeTorrentFile(const FileName: UTF8String): boole
//Called when user add torrent files
//False if something is wrong with decoding torrent.
Result := FDecodePresentTorrent.DecodeTorrent(FileName);
- ViewUpdateOneTorrentFileDecoded;
+ if Result then
+ begin
+ //visual update this one torrent file.
+ ViewUpdateOneTorrentFileDecoded;
+ end;
end;
procedure TFormTrackerModify.UpdateTorrentTrackerList;
var
TrackerStr: UTF8String;
begin
- //Copy the trackers found in one torrent file to FTrackerFromInsideTorrentFilesList
+ //Copy the trackers found in one torrent file to FTrackerList.TrackerFromInsideTorrentFilesList
for TrackerStr in FDecodePresentTorrent.TrackerList do
begin
- AddButIngnoreDuplicates(FTrackerFromInsideTorrentFilesList, TrackerStr);
+ AddButIngnoreDuplicates(FTrackerList.TrackerFromInsideTorrentFilesList, TrackerStr);
end;
end;
procedure TFormTrackerModify.ShowTrackerInsideFileList;
-var
- TrackerStr: UTF8String;
begin
//Called after torrent is being loaded.
-
- CheckListBoxTrackersList.Items.BeginUpdate;
- //remove the previeus list
- CheckListBoxTrackersList.Clear;
- //Add new items to the list.
- for TrackerStr in FTrackerFromInsideTorrentFilesList do
- begin
- CheckListBoxTrackersList.Items.Add(TrackerStr);
- end;
- CheckListBoxTrackersList.Items.EndUpdate;
+ FControlerTrackerListOnline.UpdateView;
end;
@@ -1036,306 +1117,127 @@ procedure TFormTrackerModify.CheckedOnOffAllTrackers(Value: boolean);
var
i: integer;
begin
- //Set all the trackers checkbox ON or OFF
- if CheckListBoxTrackersList.Count > 0 then
+ //Set all the trackers CheckBoxRemoveAllSourceTag ON or OFF
+ if FControlerTrackerListOnline.Count > 0 then
+ begin
+ for i := 0 to FControlerTrackerListOnline.Count - 1 do
begin
- for i := 0 to CheckListBoxTrackersList.Count - 1 do
- begin
- CheckListBoxTrackersList.Checked[i] := Value;
- end;
+ FControlerTrackerListOnline.Checked[i] := Value;
end;
+ end;
end;
-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);
-end;
-function TFormTrackerModify.CopyUserInputNewTrackersToList: boolean;
+function TFormTrackerModify.CopyUserInputNewTrackersToList(
+ Temporary_SkipAnnounceCheck: boolean): boolean;
var
- TrackerStr: UTF8String;
+ TrackerStrLoop, TrackerStr, ErrorStr: UTF8String;
begin
{
Called after 'update torrent' is selected.
- All the user entery from Memo text field will be add to FTrackerAddedByUserList.
+ All the user entery from Memo text field will be add to FTrackerList.TrackerAddedByUserList.
}
- FTrackerAddedByUserList.Clear;
+ FTrackerList.TrackerAddedByUserList.Clear;
+
+ //Will set to false when error is detected
+ Result := True;
- for TrackerStr in MemoNewTrackers.Lines do
+ for TrackerStrLoop in MemoNewTrackers.Lines do
begin
- TrackerStr := UTF8trim(TrackerStr);
+ TrackerStr := UTF8trim(TrackerStrLoop);
//Skip empty line
if TrackerStr = '' then
continue;
- //All the tracker must begin with 'http(s)://' or 'udp://'
- if ValidTrackerURL(TrackerStr) then
+ Result := ValidTrackerURL(TrackerStr);
+ if Result then
begin
- AddButIngnoreDuplicates(FTrackerAddedByUserList, TrackerStr);
+ if CheckForAnnounce(TrackerStr) and (not Temporary_SkipAnnounceCheck) then
+ begin
+ Result := TrackerURLWithAnnounce(TrackerStr);
+ if not Result then
+ begin
+ ErrorStr := 'ERROR: Tracker URL must end with /announce or /announce.php';
+ end;
+ end;
end
else
begin
- //There is error. Show the error and do not continue.
- if FConcoleMode then
- begin
- FLogStringList.Add('ERROR: Tracker URL must begin with http:// or udp://');
- end
- else
- begin
- //Show error
- Application.MessageBox(PChar(@TrackerStr[1]),
- 'Error: Tracker URL must begin with http(s):// or udp://', MB_ICONERROR);
- end;
- //do not continue with error.
- Result := False;
- exit;
+ ErrorStr := 'ERROR: Tracker URL must begin with http://, http:// or udp://';
end;
- end;
-
- Result := True; //no error
-
- //Show the torrent list we have just created.
- MemoNewTrackers.Text := FTrackerAddedByUserList.Text;
-
-end;
-
-
-procedure TFormTrackerModify.CombineFiveTrackerListToOne(
- TrackerListOrder: TTrackerListOrder);
-var
- TrackerStr: UTF8String;
- TrackerDeselectTempList, TrackerFromInsideOneTorrentFile: TStringList;
-
-begin
- //The new trackers can be added at the begin or at the end of the list.
-
- // FTrackerFinalList =
- // (TrackerFromInsideOneTorrentFile
- // + FTrackerAddedByUserList
- // + FTrackerFromInsideTorrentFilesList)
- // - FTrackerBanByUserList
- // - FTrackerManualyDeselectedByUserList
-
-
- TrackerFromInsideOneTorrentFile := TStringList.Create;
-
- try
- //Begin with an empty list
- FTrackerFinalList.Clear;
-
- if TrackerListOrder <> tloSort then
+ if Result then
begin
-
- //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;
-
- end;
-
- //Add the new tracker list before of after the original trackers list inside the torrent file.
- case TrackerListOrder of
-
- tloInsertNewBeforeAndKeepOriginalIntact:
- begin
- //Before
-
- //Must be place as first FTrackerAddedByUserList (Not instact when duplicated)
- for TrackerStr in FTrackerAddedByUserList do
- AddButIngnoreDuplicates(FTrackerFinalList, TrackerStr);
-
- //original tracker list is second place (Keep original intact)
- RemoveTrackersFromList(TrackerFromInsideOneTorrentFile, FTrackerFinalList);
- for TrackerStr in TrackerFromInsideOneTorrentFile do
- AddButIngnoreDuplicates(FTrackerFinalList, TrackerStr);
-
- //'Others' trackers added as last. (Not instact when duplicated)
- for TrackerStr in FTrackerFromInsideTorrentFilesList do
- AddButIngnoreDuplicates(FTrackerFinalList, TrackerStr);
- end;
-
-
- tloInsertNewBeforeAndKeepNewIntact:
- begin
- //Before
-
- //Must be place as first FTrackerAddedByUserList (keep new instact)
- for TrackerStr in FTrackerAddedByUserList do
- AddButIngnoreDuplicates(FTrackerFinalList, TrackerStr);
-
- //original tracker list is second place (Not instact when duplicated)
- for TrackerStr in TrackerFromInsideOneTorrentFile do
- AddButIngnoreDuplicates(FTrackerFinalList, TrackerStr);
-
- //'Others' trackers added as last. (Not instact when duplicated)
- for TrackerStr in FTrackerFromInsideTorrentFilesList do
- AddButIngnoreDuplicates(FTrackerFinalList, TrackerStr);
- end;
-
-
- tloAppendNewAfterAndKeepOriginalIntact:
- begin
- //After
-
- //original tracker list must be place first. (keep original instact)
- for TrackerStr in TrackerFromInsideOneTorrentFile do
- AddButIngnoreDuplicates(FTrackerFinalList, TrackerStr);
-
- //Must be place after TrackerFromInsideOneTorrentFile (Not instact when duplicated)
- for TrackerStr in FTrackerAddedByUserList do
- AddButIngnoreDuplicates(FTrackerFinalList, TrackerStr);
-
- //'Others' trackers added as last. (Not instact when duplicated)
- for TrackerStr in FTrackerFromInsideTorrentFilesList do
- AddButIngnoreDuplicates(FTrackerFinalList, TrackerStr);
-
- end;
-
- tloAppendNewAfterAndKeepNewIntact:
- begin
- //After
-
- //original tracker list must be place first. (Not instact when duplicated)
- for TrackerStr in TrackerFromInsideOneTorrentFile do
- AddButIngnoreDuplicates(FTrackerFinalList, TrackerStr);
-
- //Must be place after TrackerFromInsideOneTorrentFile (keep new instact)
- RemoveTrackersFromList(FTrackerAddedByUserList, FTrackerFinalList);
- for TrackerStr in FTrackerAddedByUserList do
- AddButIngnoreDuplicates(FTrackerFinalList, TrackerStr);
-
- //'Others' trackers added as last. (Not instact when duplicated)
- for TrackerStr in FTrackerFromInsideTorrentFilesList do
- AddButIngnoreDuplicates(FTrackerFinalList, TrackerStr);
-
- end;
-
- tloSort:
- begin
- //Sort
-
- for TrackerStr in FTrackerAddedByUserList do
- AddButIngnoreDuplicates(FTrackerFinalList, TrackerStr);
-
- for TrackerStr in FTrackerFromInsideTorrentFilesList do
- AddButIngnoreDuplicates(FTrackerFinalList, TrackerStr);
-
- FTrackerFinalList.Sort;
- end;
-
- tloInsertNewBeforeAndKeepOriginalIntactAndRemoveNothing:
- begin
- //Before
-
- //Must be place as first FTrackerAddedByUserList.
- for TrackerStr in FTrackerAddedByUserList do
- AddButIngnoreDuplicates(FTrackerFinalList, TrackerStr);
-
- //remove duplicate from the list.
- RemoveTrackersFromList(TrackerFromInsideOneTorrentFile, FTrackerFinalList);
-
- //original tracker list is second place (Keep original intact)
- for TrackerStr in TrackerFromInsideOneTorrentFile do
- AddButIngnoreDuplicates(FTrackerFinalList, TrackerStr);
-
- //Nothing should be removed
- FTrackerManualyDeselectedByUserList.Clear;
- end;
-
-
- tloAppendNewAfterAndKeepOriginalIntactAndRemoveNothing:
- begin
- //After
-
- //original tracker list is first place (Keep original intact)
- for TrackerStr in TrackerFromInsideOneTorrentFile do
- AddButIngnoreDuplicates(FTrackerFinalList, TrackerStr);
-
- //Must be place as second FTrackerAddedByUserList.
- for TrackerStr in FTrackerAddedByUserList do
- AddButIngnoreDuplicates(FTrackerFinalList, TrackerStr);
-
- //Nothing should be removed
- FTrackerManualyDeselectedByUserList.Clear;
- end;
-
-
- else
- begin
- Assert(True, 'case else: Should never been called. CombineFiveTrackerListToOne');
- end;
+ AddButIngnoreDuplicates(FTrackerList.TrackerAddedByUserList, TrackerStr);
+ end
+ else
+ begin
+ //do not continue the for loop
+ break;
end;
- //Trackers from FTrackerAddedByUserList overrule the one from FTrackerManualyDeselectedByUserList
- //This is when there is a conflict betwean 'add' and 'remove manual selection'
-
- //Must keep FTrackerManualyDeselectedByUserList intact. Copy it to TrackerDeselectTempList
- TrackerDeselectTempList := TStringList.Create;
- TrackerDeselectTempList.Text := FTrackerManualyDeselectedByUserList.Text;
- RemoveTrackersFromList(FTrackerAddedByUserList, TrackerDeselectTempList);
+ end;//for loop
- //Remove the trackers that we do not want in FTrackerFinalList must be the last step.
- RemoveTrackersFromList(FTrackerBanByUserList, FTrackerFinalList);
- RemoveTrackersFromList(TrackerDeselectTempList, FTrackerFinalList);
-
- //No longer needed
- TrackerDeselectTempList.Free;
-
- finally
- //No longer needed
- TrackerFromInsideOneTorrentFile.Free;
+ if Result then
+ begin
+ //Show the torrent list we have just created.
+ MemoNewTrackers.Text := FTrackerList.TrackerAddedByUserList.Text;
+ end
+ else
+ begin
+ //There is error. Show the error.
+ ShowUserErrorMessage(ErrorStr, TrackerStr);
end;
end;
-
procedure TFormTrackerModify.UpdateTrackerInsideFileList;
var
i: integer;
begin
//Collect data what the user want to keep
- //Copy items from CheckListBoxTrackersList to FTrackerFromInsideTorrentFilesList
- //Copy items from CheckListBoxTrackersList to FTrackerManualyDeselectedByUserList
+ //Copy items from FControlerTrackerListOnline to FTrackerList.TrackerFromInsideTorrentFilesList
+ //Copy items from FControlerTrackerListOnline to FTrackerList.TrackerManualyDeselectedByUserList
- FTrackerFromInsideTorrentFilesList.Clear;
- FTrackerManualyDeselectedByUserList.Clear;
+ FTrackerList.TrackerFromInsideTorrentFilesList.Clear;
+ FTrackerList.TrackerManualyDeselectedByUserList.Clear;
- if CheckListBoxTrackersList.Count > 0 then
+ if FControlerTrackerListOnline.Count > 0 then
begin
- for i := 0 to CheckListBoxTrackersList.Count - 1 do
+ for i := 0 to FControlerTrackerListOnline.Count - 1 do
begin
- if CheckListBoxTrackersList.Checked[i] then
+ if FControlerTrackerListOnline.Checked[i] then
begin
//Selected by user
- AddButIngnoreDuplicates(FTrackerFromInsideTorrentFilesList,
- CheckListBoxTrackersList.Items[i]);
+ AddButIngnoreDuplicates(FTrackerList.TrackerFromInsideTorrentFilesList,
+ FControlerTrackerListOnline.TrackerURL(i)
+ );
end
else
begin
//Delected by user
AddButIngnoreDuplicates(
- FTrackerManualyDeselectedByUserList, CheckListBoxTrackersList.Items[i]);
+ FTrackerList.TrackerManualyDeselectedByUserList,
+ FControlerTrackerListOnline.TrackerURL(i)
+ );
end;
end;
end;
+
end;
-procedure TFormTrackerModify.LoadTrackersTextFileAddTrackers;
+procedure TFormTrackerModify.LoadTrackersTextFileAddTrackers(
+ Temporary_SkipAnnounceCheck: boolean);
var
i: integer;
begin
//Called at the start of the program. Load a trackers list from file
//if no file is found the use the default tracker list.
- if not ReadAddTrackerFileFromUser(ExtractFilePath(Application.ExeName) +
- ADD_TRACKERS_FILE_NAME) then
+ if not ReadAddTrackerFileFromUser(FFolderForTrackerListLoadAndSave +
+ FILE_NAME_ADD_TRACKERS) then
begin
MemoNewTrackers.Lines.BeginUpdate;
for i := low(RECOMENDED_TRACKERS) to high(RECOMENDED_TRACKERS) do
@@ -1346,7 +1248,7 @@ procedure TFormTrackerModify.LoadTrackersTextFileAddTrackers;
end;
//Check for error in tracker list
- if not CopyUserInputNewTrackersToList then
+ if not CopyUserInputNewTrackersToList(Temporary_SkipAnnounceCheck) then
begin
MemoNewTrackers.Lines.Clear;
end;
@@ -1356,16 +1258,19 @@ procedure TFormTrackerModify.LoadTrackersTextFileRemoveTrackers;
var
filename: UTF8String;
begin
- filename := ExtractFilePath(Application.ExeName) + REMOVE_TRACKERS_FILE_NAME;
+ filename := FFolderForTrackerListLoadAndSave + FILE_NAME_REMOVE_TRACKERS;
try
FFilePresentBanByUserList := FileExistsUTF8(fileName);
if FFilePresentBanByUserList then
begin
- FTrackerBanByUserList.LoadFromFile(fileName);
+ FTrackerList.TrackerBanByUserList.LoadFromFile(fileName);
end;
except
FFilePresentBanByUserList := False;
end;
+
+ SanatizeTrackerList(FTrackerList.TrackerBanByUserList);
+
end;
@@ -1406,14 +1311,14 @@ procedure TFormTrackerModify.MenuTrackersAllTorrentArePublicPrivateClick(
'Are you sure!', MB_ICONWARNING + MB_OKCANCEL) <> idOk then
exit;
- //Set all the trackers publick/private checkbox ON or OFF
- if CheckListBoxPublicPrivateTorrent.Count > 0 then
+ //Set all the trackers publick/private CheckBoxRemoveAllSourceTag ON or OFF
+ if CheckListBoxPublicPrivateTorrent.Count > 0 then
+ begin
+ for i := 0 to CheckListBoxPublicPrivateTorrent.Count - 1 do
begin
- for i := 0 to CheckListBoxPublicPrivateTorrent.Count - 1 do
- begin
- CheckListBoxPublicPrivateTorrent.Checked[i] := TMenuItem(Sender).Tag = 1;
- end;
+ CheckListBoxPublicPrivateTorrent.Checked[i] := TMenuItem(Sender).Tag = 1;
end;
+ end;
end;
@@ -1436,6 +1341,13 @@ procedure TFormTrackerModify.MenuHelpReportingIssueClick(Sender: TObject);
OpenURL('https://github.com/GerryFerdinandus/bittorrent-tracker-editor/issues');
end;
+procedure TFormTrackerModify.MenuHelpVisitNewTrackonClick(Sender: TObject);
+begin
+ //newTrackon trackers is being used in this program.
+ //User should have direct link to the website for the status of the trackers.
+ OpenURL('https://newtrackon.com/');
+end;
+
function TFormTrackerModify.ReadAddTrackerFileFromUser(
const FileName: UTF8String): boolean;
@@ -1446,6 +1358,7 @@ function TFormTrackerModify.ReadAddTrackerFileFromUser(
TrackerFileList := TStringList.Create;
try
TrackerFileList.LoadFromFile(FileName);
+ SanatizeTrackerList(TrackerFileList);
MemoNewTrackers.Text := UTF8Trim(TrackerFileList.Text);
Result := True;
except
@@ -1463,18 +1376,20 @@ procedure TFormTrackerModify.MenuTrackersKeepOrDeleteAllTrackersClick(Sender: TO
CheckedOnOffAllTrackers(TMenuItem(Sender).Tag = 1);
end;
-procedure TFormTrackerModify.MenuUpdateTorrentAddAfterKeepOriginalInstactAndRemoveNothingClick(
- Sender: TObject);
+procedure TFormTrackerModify.
+MenuUpdateTorrentAddAfterKeepOriginalInstactAndRemoveNothingClick(Sender: TObject);
begin
//User have selected to add new tracker.
- FTrackerListOrderForUpdatedTorrent := tloAppendNewAfterAndKeepOriginalIntactAndRemoveNothing;
+ FTrackerList.TrackerListOrderForUpdatedTorrent :=
+ tloAppendNewAfterAndKeepOriginalIntactAndRemoveNothing;
UpdateTorrent;
end;
procedure TFormTrackerModify.MenuUpdateTorrentAddAfterRemoveNewClick(Sender: TObject);
begin
//User have selected to add new tracker.
- FTrackerListOrderForUpdatedTorrent := tloAppendNewAfterAndKeepOriginalIntact;
+ FTrackerList.TrackerListOrderForUpdatedTorrent :=
+ tloAppendNewAfterAndKeepOriginalIntact;
UpdateTorrent;
end;
@@ -1482,15 +1397,16 @@ procedure TFormTrackerModify.MenuUpdateTorrentAddAfterRemoveOriginalClick(
Sender: TObject);
begin
//User have selected to add new tracker.
- FTrackerListOrderForUpdatedTorrent := tloAppendNewAfterAndKeepNewIntact;
+ FTrackerList.TrackerListOrderForUpdatedTorrent := tloAppendNewAfterAndKeepNewIntact;
UpdateTorrent;
end;
-procedure TFormTrackerModify.MenuUpdateTorrentAddBeforeKeepOriginalInstactAndRemoveNothingClick(
- Sender: TObject);
+procedure TFormTrackerModify.
+MenuUpdateTorrentAddBeforeKeepOriginalInstactAndRemoveNothingClick(Sender: TObject);
begin
//User have selected to add new tracker.
- FTrackerListOrderForUpdatedTorrent := tloInsertNewBeforeAndKeepOriginalIntactAndRemoveNothing;
+ FTrackerList.TrackerListOrderForUpdatedTorrent :=
+ tloInsertNewBeforeAndKeepOriginalIntactAndRemoveNothing;
UpdateTorrent;
end;
@@ -1498,7 +1414,8 @@ procedure TFormTrackerModify.MenuUpdateTorrentAddBeforeRemoveNewClick(Sender: TO
begin
//User have selected to add new tracker.
- FTrackerListOrderForUpdatedTorrent := tloInsertNewBeforeAndKeepOriginalIntact;
+ FTrackerList.TrackerListOrderForUpdatedTorrent :=
+ tloInsertNewBeforeAndKeepOriginalIntact;
UpdateTorrent;
end;
@@ -1506,54 +1423,29 @@ procedure TFormTrackerModify.MenuUpdateTorrentAddBeforeRemoveOriginalClick(
Sender: TObject);
begin
//User have selected to add new tracker.
- FTrackerListOrderForUpdatedTorrent := tloInsertNewBeforeAndKeepNewIntact;
+ FTrackerList.TrackerListOrderForUpdatedTorrent := tloInsertNewBeforeAndKeepNewIntact;
UpdateTorrent;
end;
procedure TFormTrackerModify.MenuUpdateTorrentSortClick(Sender: TObject);
begin
//User can select to add new tracker as sorted.
- FTrackerListOrderForUpdatedTorrent := tloSort;
+ FTrackerList.TrackerListOrderForUpdatedTorrent := 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
- Info: TSearchRec;
TorrentFilesNameStringList: TStringList;
begin
//place all the torrent file name in TorrentFilesNameStringList
TorrentFilesNameStringList := TStringList.Create;
try
- if FindFirstUTF8(dir + PathDelim + '*.torrent', faAnyFile, Info) = 0 then
- begin
- //Read all the torrent files inside this dir.
- repeat
- TorrentFilesNameStringList.Add(UTF8Trim(dir + PathDelim + Info.Name));
- until FindNextUTF8(info) <> 0;
- end;
- FindCloseUTF8(Info);
-
+ torrent_miscellaneous.LoadTorrentViaDir(Dir, TorrentFilesNameStringList);
//add the torrent file name to AddTorrentFileList()
Result := AddTorrentFileList(TorrentFilesNameStringList);
-
finally
//Free all the list we temporary created.
TorrentFilesNameStringList.Free;
@@ -1691,10 +1583,15 @@ procedure TFormTrackerModify.FormDropFiles(Sender: TObject;
procedure TFormTrackerModify.FormShow(Sender: TObject);
begin
//In console mode do not show the program.
- if FConcoleMode then
+ if FConsoleMode then
Visible := False;
end;
+procedure TFormTrackerModify.LabeledEditInfoSourceEditingDone(Sender: TObject);
+begin
+ FTrackerList.SourceTag := TLabeledEdit(Sender).Text;
+end;
+
function TFormTrackerModify.AddTorrentFileList(TorrentFileNameStringList:
TStringList): boolean;
@@ -1704,8 +1601,8 @@ function TFormTrackerModify.AddTorrentFileList(TorrentFileNameStringList:
TorrentFileNameStr: UTF8String;
begin
{ Every torrent file must be decoded for the tracker list inside.
- This torrent tracker list is add to FTrackerFromInsideTorrentFilesList.
- All the torrent files name are added to FTorrentFileNameList.
+ This torrent tracker list is add to FTrackerList.TrackerFromInsideTorrentFilesList.
+ All the torrent files name are added to FTrackerList.TorrentFileNameList.
Called when user do drag and drop, File open torrent file/dir
}
@@ -1722,23 +1619,15 @@ function TFormTrackerModify.AddTorrentFileList(TorrentFileNameStringList:
//Now add all this torrent trackers to the 'general' list of trackers.
UpdateTorrentTrackerList;
//Add this torrent file to the 'general' list of torrent file names
- FTorrentFileNameList.Add(TorrentFileNameStr);
+ FTrackerList.TorrentFileNameList.Add(TorrentFileNameStr);
end
else
begin
//Someting is wrong. Can not decode torrent tracker item.
//Cancel everything.
- FTorrentFileNameList.Clear;
- FTrackerFromInsideTorrentFilesList.Clear;
- if FConcoleMode then
- begin
- FLogStringList.Add('Error: Can not read torrent. ' + TorrentFileNameStr);
- end
- else
- begin
- Application.MessageBox(PChar(@TorrentFileNameStr[1]),
- 'Error: Can not read torrent.', MB_ICONERROR);
- end;
+ FTrackerList.TorrentFileNameList.Clear;
+ FTrackerList.TrackerFromInsideTorrentFilesList.Clear;
+ ShowUserErrorMessage('Error: Can not read torrent.', TorrentFileNameStr);
Result := False;
exit;
end;
@@ -1748,7 +1637,7 @@ function TFormTrackerModify.AddTorrentFileList(TorrentFileNameStringList:
end;
-procedure TFormTrackerModify.ReloadAllTorrentAndRefreshView;
+function TFormTrackerModify.ReloadAllTorrentAndRefreshView: boolean;
var
TorrentFileStr: UTF8String;
begin
@@ -1758,14 +1647,22 @@ procedure TFormTrackerModify.ReloadAllTorrentAndRefreshView;
And show that everything is updated and OK
}
+ //will be set to False if error occure
+ Result := True;
+
ViewUpdateBegin;
- //Copy all the trackers in inside the torrent files to FTrackerFromInsideTorrentFilesList
- FTrackerFromInsideTorrentFilesList.Clear;
- for TorrentFileStr in FTorrentFileNameList do
+ //Copy all the trackers in inside the torrent files to FTrackerList.TrackerFromInsideTorrentFilesList
+ FTrackerList.TrackerFromInsideTorrentFilesList.Clear;
+ for TorrentFileStr in FTrackerList.TorrentFileNameList do
begin
if DecodeTorrentFile(TorrentFileStr) then
begin
UpdateTorrentTrackerList;
+ end
+ else
+ begin
+ //some files can not be read/decoded
+ Result := False;
end;
end;
@@ -1776,60 +1673,54 @@ procedure TFormTrackerModify.ReloadAllTorrentAndRefreshView;
procedure TFormTrackerModify.ClearAllTorrentFilesNameAndTrackerInside;
begin
- FTorrentFileNameList.Clear;
- FTrackerFromInsideTorrentFilesList.Clear;
+ FTrackerList.TorrentFileNameList.Clear;
+ FTrackerList.TrackerFromInsideTorrentFilesList.Clear;
// Caption := FORM_CAPTION;
// ShowTorrentFilesAfterBeingLoaded;
end;
-procedure TFormTrackerModify.ViewUpdateBegin(ClearView: boolean);
+procedure TFormTrackerModify.ViewUpdateBegin;
begin
//Called before loading torrent file.
- FTotalFileInsideTorrent := 0;
- FTotalFileSizeInsideTorrent := 0;
+
+ Fcontroler_treeview_torrent_data.BeginUpdate;
//Do not show being updating till finish updating data.
StringGridTorrentData.BeginUpdate;
- TreeViewFileContents.BeginUpdate;
CheckListBoxPublicPrivateTorrent.Items.BeginUpdate;
- if ClearView then
- begin
- //Clear all the user data 'View' elements. This will be filled with new data.
- TreeViewFileContents.Items.Clear;
- CheckListBoxPublicPrivateTorrent.Clear; //Use in update torrent!
- StringGridTorrentData.Clear;
- FControlerGridTorrentData.ClearAllImageIndex;
- //RowCount is 0 after Clear. But must be 1 to make it work.
- StringGridTorrentData.RowCount := 1;
- end;
- //root is 'Torrent Files'
- FTreeNodeRoot := TreeViewFileContents.Items.Add(nil, 'Torrent Files');
+ //Clear all the user data 'View' elements. This will be filled with new data.
+ CheckListBoxPublicPrivateTorrent.Clear; //Use in update torrent!
+ StringGridTorrentData.Clear;
+ FControlerGridTorrentData.ClearAllImageIndex;
+ //RowCount is 0 after Clear. But must be 1 to make it work.
+ StringGridTorrentData.RowCount := 1;
end;
procedure TFormTrackerModify.ViewUpdateOneTorrentFileDecoded;
var
- RowIndex, CountFiles: integer;
- TorrentFileNameStr, TrackerStr, DateTimeStr, PrivateStr: UTF8String;
- TreeNodeTorrent, TreeNodeFiles, TreeNodeTrackers, TreeNodeInfo: TTreeNode;
+ RowIndex: integer;
+ TorrentFileNameStr, PrivateStr: UTF8String;
+ DateTimeStr: string;
begin
//Called after loading torrent file.
-
+ //There are 3 tab pages that need to be filled with new one torrent file data.
TorrentFileNameStr := ExtractFileName(FDecodePresentTorrent.FilenameTorrent);
+ //--------------------- Fill the Tree view with new torrent data
+ Fcontroler_treeview_torrent_data.AddOneTorrentFileDecoded(FDecodePresentTorrent);
+
//--------------------- Add it to the checklist box Public/private torrent
RowIndex := CheckListBoxPublicPrivateTorrent.Items.Add(TorrentFileNameStr);
//Check it for public/private flag
CheckListBoxPublicPrivateTorrent.Checked[RowIndex] :=
not FDecodePresentTorrent.PrivateTorrent;
-
//--------------------- Fill the Grid Torrent Data/Info
-
//date time in iso format
if FDecodePresentTorrent.CreatedDate <> 0 then
DateTimeToString(DateTimeStr, 'yyyy-MM-dd hh:nn:ss',
@@ -1851,6 +1742,7 @@ procedure TFormTrackerModify.ViewUpdateOneTorrentFileDecoded;
FControlerGridTorrentData.CreatedBy := FDecodePresentTorrent.CreatedBy;
FControlerGridTorrentData.Comment := FDecodePresentTorrent.Comment;
FControlerGridTorrentData.PrivateTorrent := PrivateStr;
+ FControlerGridTorrentData.InfoSource := FDecodePresentTorrent.InfoSource;
FControlerGridTorrentData.PieceLength :=
format('%6d', [FDecodePresentTorrent.PieceLenght div 1024]); //Show as KiBytes
FControlerGridTorrentData.TotaSize :=
@@ -1862,117 +1754,29 @@ procedure TFormTrackerModify.ViewUpdateOneTorrentFileDecoded;
//All the string data are filed. Copy it now to the grid
FControlerGridTorrentData.AppendRow;
- //--------------------- Fill the treeview with torrent files
-
- //Add the torrent file name + size of all the files combined.
- TorrentFileNameStr := TorrentFileNameStr + ' SIZE: ' +
- ByteSizeToBiggerSizeFormatStr(FDecodePresentTorrent.TotalFileSize)
- + ' Files: ' + IntToStr(FDecodePresentTorrent.InfoFilesCount) + ''
- + ' Tracker: ' + IntToStr(FDecodePresentTorrent.TrackerList.Count) + '';
-
-
- TreeNodeTorrent := TreeViewFileContents.Items.AddChild(FTreeNodeRoot,
- //FTorrentFileNameList[RowIndex]); //With directory path
- TorrentFileNameStr); //Without directory path
-
- TreeNodeFiles := TreeViewFileContents.Items.AddChild(TreeNodeTorrent, 'Files');
- TreeNodeTrackers := TreeViewFileContents.Items.AddChild(TreeNodeTorrent,
- 'Trackers');
- TreeNodeInfo := TreeViewFileContents.Items.AddChild(TreeNodeTorrent, 'Info');
-
- //Show all the files inside the torrent
- if FDecodePresentTorrent.InfoFilesCount > 0 then
- begin
- for CountFiles := 0 to FDecodePresentTorrent.InfoFilesCount - 1 do
- begin
- TreeViewFileContents.Items.AddChild(TreeNodeFiles,
- FDecodePresentTorrent.InfoFilesNameIndex(CountFiles) +
- ' SIZE: ' + ByteSizeToBiggerSizeFormatStr(
- FDecodePresentTorrent.InfoFilesLengthIndex(CountFiles)));
- end;
- end;
-
- //Show a how many files are there
- TreeNodeFiles.Text := TreeNodeFiles.Text + ' (' + IntToStr(TreeNodeFiles.Count) + ')';
-
- //Show all the trackers inside the torrent
- for TrackerStr in FDecodePresentTorrent.TrackerList do
- begin
- TreeViewFileContents.Items.AddChild(TreeNodeTrackers, TrackerStr);
- end;
-
- //Show a how many trackers are there
- TreeNodeTrackers.Text := TreeNodeTrackers.Text + ' (' +
- IntToStr(TreeNodeTrackers.Count) + ')';
-
-
- //Show all the info of torrent
- TreeViewFileContents.Items.AddChild(TreeNodeInfo, 'Name: ' +
- FDecodePresentTorrent.Name);
- TreeViewFileContents.Items.AddChild(TreeNodeInfo, 'Comment: ' +
- FDecodePresentTorrent.Comment);
- TreeViewFileContents.Items.AddChild(TreeNodeInfo, 'Info Hash: ' +
- FDecodePresentTorrent.InfoHash);
- TreeViewFileContents.Items.AddChild(TreeNodeInfo, 'Created On: ' + DateTimeStr);
- TreeViewFileContents.Items.AddChild(TreeNodeInfo, 'Created By: ' +
- FDecodePresentTorrent.CreatedBy);
- TreeViewFileContents.Items.AddChild(TreeNodeInfo, 'Piece Lenght: ' +
- IntToStr(FDecodePresentTorrent.PieceLenght div 1024) + ' KiB');
- if FDecodePresentTorrent.PrivateTorrent then
- begin
- TreeViewFileContents.Items.AddChild(TreeNodeInfo, 'Private: yes');
- end
- else
- begin
- TreeViewFileContents.Items.AddChild(TreeNodeInfo, 'Private: no');
- end;
-
- //All the files count inside the torrent must be added to FTotalFileInsideTorrent
- Inc(FTotalFileInsideTorrent, FDecodePresentTorrent.InfoFilesCount);
-
- //The file size of all files inside the torrent must be added to FTotalFileSizeInsideTorrent
- Inc(FTotalFileSizeInsideTorrent, FDecodePresentTorrent.TotalFileSize);
-
end;
procedure TFormTrackerModify.ViewUpdateEnd;
begin
-
- //Called after loading torrent file
- //Sync the popup menu with show/hide items.
- MenuItemTorrentFilesTreeSyncWithPopupMenu;
-
+ //Called after finish all torrent file loading.
//Show what we have updated.
- TreeViewFileContents.EndUpdate;
+ Fcontroler_treeview_torrent_data.EndUpdate;
StringGridTorrentData.EndUpdate;
CheckListBoxPublicPrivateTorrent.Items.EndUpdate;
- //Show the size of all the files inside the torrent
- //http://en.wikipedia.org/wiki/Gigabyte
- GroupBoxTorrentContents.Caption :=
- TORRENT_FILES_CONTENTS_FORM_CAPTION + ' (Files count: ' +
- IntToStr(FTotalFileInsideTorrent) + ') Files sizes: ' +
- ByteSizeToBiggerSizeFormatStr(FTotalFileSizeInsideTorrent) + '';
-
-
- GroupBoxPresentTracker.Caption := GROUPBOX_PRESENT_TRACKERS_CAPTION +
- ' (List count: ' +
- IntToStr(FTrackerFromInsideTorrentFilesList.Count) + ' )';
-
-
+ GroupBoxPresentTracker.Caption :=
+ GROUPBOX_PRESENT_TRACKERS_CAPTION + ' (List count: ' +
+ IntToStr(FTrackerList.TrackerFromInsideTorrentFilesList.Count) + ' )';
//Show all the tracker inside the torrent files.
ShowTrackerInsideFileList;
- //Mark all trackers as selected
- CheckedOnOffAllTrackers(True);
//Some tracker must be removed. Console and windows mode.
UpdateViewRemoveTracker;
-
//Show user how many files are loaded
ViewUpdateFormCaption;
@@ -1989,10 +1793,16 @@ procedure TFormTrackerModify.ViewUpdateFormCaption;
DecodeTime(FProcessTimeTotal, Hour, Minute, Second, MilliSecond);
ProcessTimeStr := IntToStr((Second * 1000) + MilliSecond) + ' mSec';
}
-
//Show user how many files are loaded
Caption := FORM_CAPTION + '( Torrent files: ' +
- IntToStr(FTorrentFileNameList.Count) + ' )';
+ IntToStr(FTrackerList.TorrentFileNameList.Count) + ' )';
+
+ if CheckBoxSkipAnnounceCheck.Checked then
+ begin
+ Caption := Caption + '(-SAC)';
+ end;
+
+
// + ' (Process Time: ' + ProcessTimeStr + ' )'; //for debug purpose.
end;
@@ -2011,6 +1821,23 @@ procedure TFormTrackerModify.ShowHourGlassCursor(HourGlass: boolean);
end;
-
-
+function TFormTrackerModify.TestConnectionSSL: Boolean;
+begin
+ Result := ParamCount = 1;
+ if Result then
+ begin
+ // Check for the correct parameter.
+ Result := UTF8Trim(ParamStr(1)) = '-TEST_SSL';
+ if Result then
+ begin
+ // Check if there is SLL connection
+ try
+ TFPCustomHTTPClient.SimpleGet('https://raw.githubusercontent.com/gerryferdinandus/bittorrent-tracker-editor/master/.travis.yml');
+ except
+ //No SLL or no internet connection.
+ System.ExitCode := 1;
+ end;
+ end;
+ end;
+end;
end.
diff --git a/source/code/newtrackon.pas b/source/code/newtrackon.pas
new file mode 100644
index 0000000..affcf68
--- /dev/null
+++ b/source/code/newtrackon.pas
@@ -0,0 +1,240 @@
+// SPDX-License-Identifier: MIT
+unit newtrackon;
+
+{
+Use api from newtrackon to get tracker list that are working or not.
+see: https://newtrackon.com/
+}
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils;
+
+type
+
+
+ { TNewTrackon }
+
+ //All the type of tracker list.
+ TNewTrackon_List = (
+ ntl_URL_All,//< Download from internet
+ ntl_URL_Live,//< Download from internet
+ ntl_URL_Stable,//< Download from internet
+ ntl_URL_UDP,//< Download from internet
+ ntl_URL_HTTP,//< Download from internet
+ ntl_CREATE_DEAD//< ntl_CREATE_DEAD is NOT download but created by comparing betwean tracker list
+ );
+
+ TNewTrackon = class
+ private
+ FTRackerList: array [TNewTrackon_List] of TStringList;
+
+ function DownloadTracker(NewTrackon_List: TNewTrackon_List): boolean;
+ procedure CreateTrackerList_Dead;
+ public
+ // all known trackers, dead or alive
+ property TrackerList_All: TStringList read FTRackerList[ntl_URL_All];
+
+ // currently active and responding trackers.
+ property TrackerList_Live: TStringList read FTrackerList[ntl_URL_Live];
+
+ // trackers that have an uptime of equal or more than 95%.
+ property TrackerList_Stable: TStringList read FTrackerList[ntl_URL_Stable];
+
+ // stable UDP trackers.
+ property TrackerList_Udp: TStringList read FTrackerList[ntl_URL_UDP];
+
+ // stable HTTP/HTTPS trackers.
+ property TrackerList_Http: TStringList read FTrackerList[ntl_URL_UDP];
+
+ // trackers that no longer present in 'live' list
+ property TrackerList_Dead: TStringList read FTrackerList[ntl_CREATE_DEAD];
+
+ //Download all the types the trackers via API
+ function DownloadEverything: boolean;
+
+ //Download only three types of the trackers via API
+ function Download_All_Live_Stable: boolean;
+
+ //Submit tracker to newTrackon via http POST
+ function SubmitTrackers(TrackerList: TStringList;
+ out TrackersSendCount: integer): boolean;
+
+ //create/destroy class object
+ constructor Create;
+ destructor Destroy; override;
+ end;
+
+
+
+implementation
+
+uses fphttpclient, LazUTF8, torrent_miscellaneous, httpdefs;
+
+const
+ URL: array [TNewTrackon_List] of string =
+ (//Warning: the URL strings must be in the same order as TNewTrackon_List
+ 'https://newtrackon.com/api/all',
+ 'https://newtrackon.com/api/live',
+ 'https://newtrackon.com/api/stable',
+ 'https://newtrackon.com/api/udp',
+ 'https://newtrackon.com/api/http',
+ ''//there is no dead tracker list api
+ );
+
+{ TNewTrackon }
+
+
+procedure TNewTrackon.CreateTrackerList_Dead;
+begin
+ //FTrackerList_Dead = FTrackerList_All - FTrackerList_Live;
+ TrackerList_Dead.Assign(TrackerList_All);
+ RemoveTrackersFromList(TrackerList_Live, TrackerList_Dead);
+end;
+
+function TNewTrackon.DownloadTracker(NewTrackon_List: TNewTrackon_List): boolean;
+begin
+
+ try
+ //there is no Dead tracker list to be downloaded. so it can be skip
+ if NewTrackon_List <> ntl_CREATE_DEAD then
+ begin
+ //download via URL and put the data in the TrackerList
+ //will create exception if something is wrong
+ FTRackerList[NewTrackon_List].DelimitedText :=
+ TFPCustomHTTPClient.SimpleGet(URL[NewTrackon_List]);
+ end;
+
+ Result := True;
+ except
+ //No OpenSSL or web server is down
+ Result := False;
+ end;
+
+ //Clean up the tracker list just downloaded
+ SanatizeTrackerList(FTRackerList[NewTrackon_List]);
+end;
+
+function TNewTrackon.DownloadEverything: boolean;
+var
+ i: TNewTrackon_List;
+begin
+ //download all the list one by one
+ for i in TNewTrackon_List do
+ begin
+ Result := DownloadTracker(i);
+ if not Result then
+ Exit;
+ end;
+
+ CreateTrackerList_Dead;
+end;
+
+function TNewTrackon.Download_All_Live_Stable: boolean;
+begin
+ Result := DownloadTracker(ntl_URL_All);
+ if Result then
+ begin
+ Result := DownloadTracker(ntl_URL_Stable);
+ if Result then
+ begin
+ Result := DownloadTracker(ntl_URL_Live);
+ end;
+ end;
+
+ CreateTrackerList_Dead;
+end;
+
+function TNewTrackon.SubmitTrackers(TrackerList: TStringList;
+ out TrackersSendCount: integer): boolean;
+var
+ TrackerListToBeSend: TStringList;
+ FormData: string;
+ Trackers: string;
+ HTTPS: TFPHTTPClient;
+ Seperator: string;
+
+const
+ URL_POST = 'https://newtrackon.com/api/add';
+begin
+ TrackersSendCount := 0;
+
+ //Must always first download the ALL tracker list if not already downloaded.
+ //To make sure it is always checking agains the most recent list
+ Result := DownloadTracker(ntl_URL_All);
+
+ if Result then
+ begin
+ try
+ HTTPS := TFPHTTPClient.Create(nil);
+ TrackerListToBeSend := TStringList.Create;
+ TrackerListToBeSend.Assign(TrackerList);
+
+ //remove all duplicate trackers before sending,
+ RemoveTrackersFromList(TrackerList_All, TrackerListToBeSend);
+
+ //Give information back about how many unique tracker URL is send.
+ TrackersSendCount := TrackerListToBeSend.Count;
+
+ if TrackersSendCount > 0 then
+ begin
+
+ //this is the 'key'
+ FormData := 'new_trackers=';
+
+ //This is the 'values' all seperated with one space '+'
+ Seperator := '';
+ for Trackers in TrackerListToBeSend do
+ begin
+ FormData := FormData + Seperator + HTTPEncode(Trackers);
+ if Seperator = '' then
+ Seperator := '+';
+ end;
+
+ try
+ HTTPS.FormPost(URL_POST, FormData);
+
+ //Check the response must be 204
+ Result := HTTPS.ResponseStatusCode = 204;
+ except
+ //No OpenSSL or web server is down
+ Result := False;
+ end;
+ end;
+
+ finally
+ TrackerListToBeSend.Free;
+ HTTPS.Free;
+ end;
+ end;
+end;
+
+constructor TNewTrackon.Create;
+var
+ i: TNewTrackon_List;
+begin
+ //Create all the TStringList
+ for i in TNewTrackon_List do
+ begin
+ FTrackerList[i] := TStringList.Create;
+ FTrackerList[i].Duplicates := dupIgnore;
+ end;
+end;
+
+destructor TNewTrackon.Destroy;
+var
+ i: TNewTrackon_List;
+begin
+ //Release all the TStringList
+ for i in TNewTrackon_List do
+ begin
+ FTrackerList[i].Free;
+ end;
+
+ inherited Destroy;
+end;
+
+
+end.
diff --git a/source/code/ngosang_trackerslist.pas b/source/code/ngosang_trackerslist.pas
new file mode 100644
index 0000000..21168b5
--- /dev/null
+++ b/source/code/ngosang_trackerslist.pas
@@ -0,0 +1,128 @@
+// SPDX-License-Identifier: MIT
+unit ngosang_trackerslist;
+
+{
+Use api from ngosang to get tracker list that are working or not.
+see: https://github.com/ngosang/trackerslist
+}
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils;
+
+type
+
+
+ { TNewTrackon }
+
+ //All the type of tracker list.
+ Tngosang_List = (
+ ntl_URL_Blacklist,//< Download from internet
+ ntl_URL_All,//< Download from internet
+ ntl_URL_All_HTTP,//< Download from internet
+ ntl_URL_All_HTTPS,//< Download from internet
+ ntl_URL_All_IP,//< Download from internet
+ ntl_URL_All_UDP,//< Download from internet
+ ntl_URL_All_WS,//< Download from internet
+ ntl_URL_Best,//< Download from internet
+ ntl_URL_Best_IP//< Download from internet
+ );
+
+ { TngosangTrackerList }
+
+ TngosangTrackerList = class
+ private
+ FTRackerList: array [Tngosang_List] of TStringList;
+ function DownloadTracker(ngosang_List: Tngosang_List): TStringList;
+ public
+
+ property TrackerList_Blacklist: TStringList index ntl_URL_Blacklist
+ read DownloadTracker;
+
+ property TrackerList_All: TStringList index ntl_URL_All read DownloadTracker;
+
+ property TrackerList_All_HTTP: TStringList index ntl_URL_All_HTTP
+ read DownloadTracker;
+
+ property TrackerList_All_HTTPS: TStringList index ntl_URL_All_HTTPS
+ read DownloadTracker;
+
+ property TrackerList_All_IP: TStringList index ntl_URL_All_IP read DownloadTracker;
+
+ property TrackerList_All_UDP: TStringList index ntl_URL_All_UDP read DownloadTracker;
+
+ property TrackerList_All_WS: TStringList index ntl_URL_All_WS read DownloadTracker;
+
+ property TrackerList_Best: TStringList index ntl_URL_Best read DownloadTracker;
+
+ property TrackerList_Best_IP: TStringList index ntl_URL_Best_IP read DownloadTracker;
+
+ //create/destroy class object
+ constructor Create;
+ destructor Destroy; override;
+ end;
+
+implementation
+
+uses fphttpclient, LazUTF8, torrent_miscellaneous;
+
+const
+ URL: array [Tngosang_List] of string =
+ (//Warning: the URL strings must be in the same order as Tngosang_List
+ 'https://raw.githubusercontent.com/ngosang/trackerslist/master/blacklist.txt',
+ 'https://raw.githubusercontent.com/ngosang/trackerslist/master/trackers_all.txt',
+ 'https://raw.githubusercontent.com/ngosang/trackerslist/master/trackers_all_http.txt',
+ 'https://raw.githubusercontent.com/ngosang/trackerslist/master/trackers_all_https.txt',
+ 'https://raw.githubusercontent.com/ngosang/trackerslist/master/trackers_all_ip.txt',
+ 'https://raw.githubusercontent.com/ngosang/trackerslist/master/trackers_all_udp.txt',
+ 'https://raw.githubusercontent.com/ngosang/trackerslist/master/trackers_all_ws.txt',
+ 'https://raw.githubusercontent.com/ngosang/trackerslist/master/trackers_best.txt',
+ 'https://raw.githubusercontent.com/ngosang/trackerslist/master/trackers_best_ip.txt'
+ );
+
+{ TngosangTrackerList }
+function TngosangTrackerList.DownloadTracker(ngosang_List: Tngosang_List): TStringList;
+begin
+ try
+ //download via URL and put the data in the TrackerList
+ FTRackerList[ngosang_List].DelimitedText :=
+ TFPCustomHTTPClient.SimpleGet(URL[ngosang_List]);
+
+ //Clean up the tracker list
+ SanatizeTrackerList(FTRackerList[ngosang_List]);
+
+ except
+ //No OpenSSL or web server is down
+ end;
+
+ Result := FTrackerList[ngosang_List];
+end;
+
+constructor TngosangTrackerList.Create;
+var
+ i: Tngosang_List;
+begin
+ //Create all the TStringList
+ for i in Tngosang_List do
+ begin
+ FTrackerList[i] := TStringList.Create;
+ FTrackerList[i].Duplicates := dupIgnore;
+ end;
+end;
+
+destructor TngosangTrackerList.Destroy;
+var
+ i: Tngosang_List;
+begin
+ //Release all the TStringList
+ for i in Tngosang_List do
+ begin
+ FTrackerList[i].Free;
+ end;
+
+ inherited Destroy;
+end;
+
+end.
diff --git a/source/code/torrent_miscellaneous.pas b/source/code/torrent_miscellaneous.pas
new file mode 100644
index 0000000..a2abc47
--- /dev/null
+++ b/source/code/torrent_miscellaneous.pas
@@ -0,0 +1,772 @@
+// SPDX-License-Identifier: MIT
+unit torrent_miscellaneous;
+
+{
+ Some generic routine
+
+}
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils;
+
+type
+ //Updated torrent file trackers list order.
+ //Do not change the order of TTrackerListOrder.
+ TTrackerListOrder = (
+
+ // Console parameter: -U0
+ // Insert new trackers list BEFORE, the original trackers list inside the torrent file.
+ // And remove possible duplicated trackers from the ORIGINAL trackers list.
+ tloInsertNewBeforeAndKeepNewIntact = 0,
+
+ // Console parameter: -U1
+ // Insert new trackers list BEFORE, the original trackers list inside the torrent file.
+ // And remove possible duplicated trackers from the NEW trackers list.
+ tloInsertNewBeforeAndKeepOriginalIntact,
+
+ // Console parameter: -U2
+ // Append new trackers list AFTER, the original trackers list inside the torrent file.
+ // And remove possible duplicated trackers from the ORIGINAL trackers list.
+ tloAppendNewAfterAndKeepNewIntact,
+
+ // Console parameter: -U3
+ // Append new trackers list AFTER, the original trackers list inside the torrent file.
+ // And remove possible duplicated trackers from the NEW trackers list.
+ tloAppendNewAfterAndKeepOriginalIntact,
+
+ // Console parameter: -U4
+ // Sort the trackers list by name.
+ tloSort,
+
+ // Console parameter: -U5
+ // Append new trackers list BEFORE, the original trackers list inside the torrent file.
+ // Keep original tracker list 'of each individual torrent' unchanged and remove nothing.
+ // Every torent may have diferent tracker list!
+ tloInsertNewBeforeAndKeepOriginalIntactAndRemoveNothing,
+
+ // Console parameter: -U6
+ // Append new trackers list AFTER, the original trackers list inside the torrent file.
+ // Keep original tracker list 'of each individual torrent' unchanged and remove nothing.
+ // Every torent may have diferent tracker list!
+ tloAppendNewAfterAndKeepOriginalIntactAndRemoveNothing,
+
+ // Console parameter: -U7
+ // Randomize the trackers list.
+ tloRandomize
+
+ );
+
+
+ TTrackerList = record
+ //The new trackers list order
+ TrackerListOrderForUpdatedTorrent: TTrackerListOrder;
+
+ //Trackers that must be put inside the torrent.
+ TrackerFinalList,
+
+ //Trackers that we want too add.
+ TrackerAddedByUserList,
+
+ //trackers that must not be present inside torrent.
+ TrackerBanByUserList,
+
+ //Trackers that are already inside the torrent.
+ TrackerFromInsideTorrentFilesList,
+
+ //trackers that must not be present inside torrent.
+ TrackerManualyDeselectedByUserList,
+
+ // All the torrent files that must be updated
+ TorrentFileNameList,
+
+ //Log string text output
+ LogStringList: TStringList;
+
+ // No announce check needed for some private trackers
+ SkipAnnounceCheck: boolean;
+
+ // Private tracker may need extra 'info:source' variable
+ SourceTag: UTF8String;
+
+ // This is needed if someone want to convert private torrent to public torrent
+ // Source tag is not used in public tracker.
+ RemoveAllSourceTag: Boolean;
+
+ end;
+
+
+procedure RemoveTrackersFromList(RemoveList, UpdatedList: TStringList);
+
+procedure SanatizeTrackerList(StringList: TStringList);
+
+procedure RandomizeTrackerList(StringList: TStringList);
+
+procedure AddButIngnoreDuplicates(StringList: TStringList; const Str: UTF8String);
+
+function ByteSizeToBiggerSizeFormatStr(ByteSize: int64): string;
+
+function LoadTorrentViaDir(const Dir: UTF8String;
+ TorrentFilesNameStringList: TStringList): boolean;
+
+function ValidTrackerURL(const TrackerURL: UTF8String): boolean;
+
+function WebTorrentTrackerURL(const TrackerURL: UTF8String): boolean;
+
+procedure CombineFiveTrackerListToOne(TrackerListOrder: TTrackerListOrder;
+ var TrackerList: TTrackerList; PresentTorrentTrackerList: TStringList);
+
+function ConsoleModeDecodeParameter(out FileNameOrDirStr: UTF8String;
+ var TrackerList: TTrackerList): boolean;
+
+function DecodeConsoleUpdateParameter(const ConsoleUpdateParameter: UTF8String;
+ var TrackerList: TTrackerList): boolean;
+
+function TrackerURLWithAnnounce(const TrackerURL: UTF8String): boolean;
+
+const
+ VALID_TRACKERS_URL: array[0..4] of UTF8String =
+ (
+ 'udp://',
+ 'http://',
+ 'https://',
+ 'ws://',
+ 'wss://'
+ );
+
+
+ //'add trackers' text file must be place in the same directory as the program.
+ FILE_NAME_ADD_TRACKERS: string = 'add_trackers.txt';
+
+ //'remove trackers' text file must be place in the same directory as the program.
+ FILE_NAME_REMOVE_TRACKERS: string = 'remove_trackers.txt';
+
+ //'export trackers' text file wil be created in the same directory as the program.
+ FILE_NAME_EXPORT_TRACKERS: string = 'export_trackers.txt';
+
+ //'log' text file will be saved in the same directory as the program
+ // only in the console mode.
+ FILE_NAME_CONSOLE_LOG: string = 'console_log.txt';
+
+ CONSOLE_SUCCESS_STATUS: string = 'OK';
+
+implementation
+
+uses LazUTF8, LazFileUtils;
+
+procedure 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;
+
+procedure SanatizeTrackerList(StringList: TStringList);
+var
+ TrackerStr: UTF8String;
+ i: integer;
+ PositionSpace: PtrInt;
+begin
+ //remove all empty space and comment after the URL
+
+ if StringList.Count > 0 then
+ begin
+ for i := 0 to StringList.Count - 1 do
+ begin
+ //process every line one by one
+ TrackerStr := StringList[i];
+
+ //remove empty spaces at the begin/end of line
+ TrackerStr := UTF8Trim(TrackerStr);
+
+ //find the first 'space' found in line
+ PositionSpace := UTF8Pos(' ', TrackerStr);
+ if PositionSpace > 0 then
+ begin
+ // There is a 'space' found
+ // Remove everything after this 'space'
+ TrackerStr := UTF8LeftStr(TrackerStr, PositionSpace - 1);
+ end;
+
+ //write the modified string back
+ StringList[i] := TrackerStr;
+ end;
+ end;
+end;
+
+procedure RandomizeTrackerList(StringList: TStringList);
+var
+ i: integer;
+begin
+ //The order of the string list must be randomize
+ if StringList.Count > 1 then
+ begin
+ for i := 0 to StringList.Count - 1 do
+ begin
+ StringList.Exchange(i, Random(StringList.Count));
+ end;
+ end;
+end;
+
+procedure AddButIngnoreDuplicates(StringList: TStringList; const Str: UTF8String);
+begin
+ //Stringlist that are not sorted must use IndexOf to ignore Duplicates.
+ if not StringList.Sorted then
+ begin
+ //not sorted version
+ if StringList.IndexOf(Str) < 0 then
+ begin
+ StringList.add(Str);
+ end;
+ end
+ else
+ begin
+ //sorted version
+ StringList.add(Str);
+ end;
+
+end;
+
+function ByteSizeToBiggerSizeFormatStr(ByteSize: int64): string;
+begin
+ if ByteSize >= (1024 * 1024 * 1024) then
+ Result := Format('%0.2f GiB', [ByteSize / (1024 * 1024 * 1024)])
+ else
+ if ByteSize >= (1024 * 1024) then
+ Result := Format('%0.2f MiB', [ByteSize / (1024 * 1024)])
+ else
+ if ByteSize >= (1024) then
+ Result := Format('%0.2f KiB', [ByteSize / 1024]);
+ Result := Result + Format(' (%d Bytes)', [ByteSize]);
+end;
+
+
+function LoadTorrentViaDir(const Dir: UTF8String;
+ TorrentFilesNameStringList: TStringList): boolean;
+var
+ Info: TSearchRec;
+begin
+ //place all the torrent file name in TorrentFilesNameStringList
+ // TorrentFilesNameStringList := TStringList.Create;
+
+ if FindFirstUTF8(dir + PathDelim + '*.torrent', faAnyFile, Info) = 0 then
+ begin
+ //Read all the torrent files inside this dir.
+ repeat
+ TorrentFilesNameStringList.Add(UTF8Trim(dir + PathDelim + Info.Name));
+ until FindNextUTF8(info) <> 0;
+ end;
+ FindCloseUTF8(Info);
+
+ Result := TorrentFilesNameStringList.Count > 0;
+
+end;
+
+
+
+function DecodeConsoleUpdateParameter(ConsoleUpdateParameter: UTF8String;
+ var TrackerListOrder: TTrackerListOrder; LogStringList: TStringList = nil): boolean;
+var
+ i: integer;
+begin
+ //Decode the '-Ux' x is number [0..4]
+
+ //verify string content.
+ Result := (Pos('-U', ConsoleUpdateParameter) = 1) and
+ (length(ConsoleUpdateParameter) = 3);
+
+ if Result then
+ begin
+ //get the number
+ Result := TryStrToInt(ConsoleUpdateParameter[3], i);
+ if Result then
+ begin
+ //decode number [0..7]
+ case i of
+ 0: TrackerListOrder := tloInsertNewBeforeAndKeepNewIntact;
+ 1: TrackerListOrder := tloInsertNewBeforeAndKeepOriginalIntact;
+ 2: TrackerListOrder := tloAppendNewAfterAndKeepNewIntact;
+ 3: TrackerListOrder := tloAppendNewAfterAndKeepOriginalIntact;
+ 4: TrackerListOrder := tloSort;
+ 5: TrackerListOrder := tloInsertNewBeforeAndKeepOriginalIntactAndRemoveNothing;
+ 6: TrackerListOrder := tloAppendNewAfterAndKeepOriginalIntactAndRemoveNothing;
+ 7: TrackerListOrder := tloRandomize;
+ else
+ begin
+ //the number is out of range.
+ Result := False;
+ end;
+ end;
+ end;
+ end;
+
+ if not Result then
+ begin
+ if assigned(LogStringList) then
+ begin
+ LogStringList.Add('ERROR: can not decode update parameter -U : ' +
+ ConsoleUpdateParameter);
+ end;
+
+ end;
+end;
+
+
+
+
+function ConsoleModeDecodeParameter(out FileNameOrDirStr: UTF8String;
+ out CountParameter: integer; var TrackerListOrder: TTrackerListOrder;
+ LogStringList: TStringList = nil): boolean;
+begin
+
+ // Console mode can be started with 2 parameter
+ // Update methode: -U0 , -U1, -U2, -U3, -U4
+ // String with a link to folder or to torrent file. 'C:\dir'
+
+ CountParameter := Paramcount;
+ case CountParameter of
+ 0:
+ begin
+ if assigned(LogStringList) then
+ begin
+ LogStringList.Add('ERROR: There are no parameter detected.');
+ end;
+ Result := False;
+ exit;
+ end;
+ 1:
+ begin
+ //one parameter. Must be a link.
+ FileNameOrDirStr := UTF8Trim(ParamStr(1));
+ //Keep the same behaviour as the previeus software version.
+ // FTrackerListOrderForUpdatedTorrent := tloSort;
+ TrackerListOrder := tloSort;
+ Result := True;
+ end;
+ 2:
+ begin
+ //Two parameters. The user can select the update methode.
+ //Check for '-U' contruction as first parameter
+ if (Pos('-U', ParamStr(1)) = 1) then
+ begin
+ //Update parameter is the first parameter
+ Result := DecodeConsoleUpdateParameter(ParamStr(1), TrackerListOrder,
+ LogStringList);
+ FileNameOrDirStr := UTF8Trim(ParamStr(2));
+ end
+ else
+ begin
+ //Update parameter is the second parameter
+ Result := DecodeConsoleUpdateParameter(ParamStr(2), TrackerListOrder,
+ LogStringList);
+ FileNameOrDirStr := UTF8Trim(ParamStr(1));
+ end;
+
+ end;
+ else
+ begin
+ if assigned(LogStringList) then
+ begin
+ LogStringList.Add('ERROR: There can only be maximum of 2 parameter. Not: ' +
+ IntToStr(ParamCount));
+ end;
+ end;
+ Result := False;
+ exit;
+ end;
+
+end;
+
+function ValidTrackerURL(const TrackerURL: UTF8String): boolean;
+begin
+ //TrackerURL should be cleanup with UTF8trim()
+ Result := (Pos('udp://', TrackerURL) = 1) or (Pos('http://', TrackerURL) = 1) or
+ (Pos('https://', TrackerURL) = 1) or WebTorrentTrackerURL(TrackerURL);
+end;
+
+function WebTorrentTrackerURL(const TrackerURL: UTF8String): boolean;
+begin
+ Result := (Pos('ws://', TrackerURL) = 1) or (Pos('wss://', TrackerURL) = 1);
+end;
+
+procedure CombineFiveTrackerListToOne(TrackerListOrder: TTrackerListOrder;
+ var TrackerList: TTrackerList; PresentTorrentTrackerList: TStringList);
+var
+ TrackerStr: UTF8String;
+ TrackerDeselectTempList, TrackerFromInsideOneTorrentFile: TStringList;
+
+begin
+ //The new trackers can be added at the begin or at the end of the list.
+
+ // FTrackerFinalList =
+ // (TrackerFromInsideOneTorrentFile
+ // + TrackerList.TrackerAddedByUserList
+ // + TrackerList.TrackerFromInsideTorrentFilesList)
+ // - TrackerList.TrackerBanByUserList
+ // - TrackerList.TrackerManualyDeselectedByUserList
+
+
+ TrackerFromInsideOneTorrentFile := TStringList.Create;
+
+ try
+ //Begin with an empty list
+ TrackerList.TrackerFinalList.Clear;
+
+ if TrackerListOrder <> tloSort then
+ begin
+
+ //Read the trackers inside the torrent file
+ //Copy the trackers found in one torrent file to TrackerFromInsideOneTorrentFile
+ for TrackerStr in PresentTorrentTrackerList do //FDecodePresentTorrent.TrackerList
+ begin
+ AddButIngnoreDuplicates(TrackerFromInsideOneTorrentFile, TrackerStr);
+ end;
+
+ end;
+
+ //Add the new tracker list before of after the original trackers list inside the torrent file.
+ case TrackerListOrder of
+
+ tloInsertNewBeforeAndKeepOriginalIntact:
+ begin
+ //Before
+
+ //Must be place as first TrackerList.TrackerAddedByUserList (Not instact when duplicated)
+ for TrackerStr in TrackerList.TrackerAddedByUserList do
+ AddButIngnoreDuplicates(TrackerList.TrackerFinalList, TrackerStr);
+
+ //original tracker list is second place (Keep original intact)
+ RemoveTrackersFromList(TrackerFromInsideOneTorrentFile,
+ TrackerList.TrackerFinalList);
+ for TrackerStr in TrackerFromInsideOneTorrentFile do
+ AddButIngnoreDuplicates(TrackerList.TrackerFinalList, TrackerStr);
+
+ //'Others' trackers added as last. (Not instact when duplicated)
+ for TrackerStr in TrackerList.TrackerFromInsideTorrentFilesList do
+ AddButIngnoreDuplicates(TrackerList.TrackerFinalList, TrackerStr);
+ end;
+
+
+ tloInsertNewBeforeAndKeepNewIntact:
+ begin
+ //Before
+
+ //Must be place as first TrackerList.TrackerAddedByUserList (keep new instact)
+ for TrackerStr in TrackerList.TrackerAddedByUserList do
+ AddButIngnoreDuplicates(TrackerList.TrackerFinalList, TrackerStr);
+
+ //original tracker list is second place (Not instact when duplicated)
+ for TrackerStr in TrackerFromInsideOneTorrentFile do
+ AddButIngnoreDuplicates(TrackerList.TrackerFinalList, TrackerStr);
+
+ //'Others' trackers added as last. (Not instact when duplicated)
+ for TrackerStr in TrackerList.TrackerFromInsideTorrentFilesList do
+ AddButIngnoreDuplicates(TrackerList.TrackerFinalList, TrackerStr);
+ end;
+
+
+ tloAppendNewAfterAndKeepOriginalIntact:
+ begin
+ //After
+
+ //original tracker list must be place first. (keep original instact)
+ for TrackerStr in TrackerFromInsideOneTorrentFile do
+ AddButIngnoreDuplicates(TrackerList.TrackerFinalList, TrackerStr);
+
+ //Must be place after TrackerFromInsideOneTorrentFile (Not instact when duplicated)
+ for TrackerStr in TrackerList.TrackerAddedByUserList do
+ AddButIngnoreDuplicates(TrackerList.TrackerFinalList, TrackerStr);
+
+ //'Others' trackers added as last. (Not instact when duplicated)
+ for TrackerStr in TrackerList.TrackerFromInsideTorrentFilesList do
+ AddButIngnoreDuplicates(TrackerList.TrackerFinalList, TrackerStr);
+
+ end;
+
+ tloAppendNewAfterAndKeepNewIntact:
+ begin
+ //After
+
+ //original tracker list must be place first. (Not instact when duplicated)
+ for TrackerStr in TrackerFromInsideOneTorrentFile do
+ AddButIngnoreDuplicates(TrackerList.TrackerFinalList, TrackerStr);
+
+ //Must be place after TrackerFromInsideOneTorrentFile (keep new instact)
+ RemoveTrackersFromList(TrackerList.TrackerAddedByUserList,
+ TrackerList.TrackerFinalList);
+ for TrackerStr in TrackerList.TrackerAddedByUserList do
+ AddButIngnoreDuplicates(TrackerList.TrackerFinalList, TrackerStr);
+
+ //'Others' trackers added as last. (Not instact when duplicated)
+ for TrackerStr in TrackerList.TrackerFromInsideTorrentFilesList do
+ AddButIngnoreDuplicates(TrackerList.TrackerFinalList, TrackerStr);
+
+ end;
+
+ tloSort:
+ begin
+ //Sort
+
+ for TrackerStr in TrackerList.TrackerAddedByUserList do
+ AddButIngnoreDuplicates(TrackerList.TrackerFinalList, TrackerStr);
+
+ for TrackerStr in TrackerList.TrackerFromInsideTorrentFilesList do
+ AddButIngnoreDuplicates(TrackerList.TrackerFinalList, TrackerStr);
+
+ TrackerList.TrackerFinalList.Sort;
+ end;
+
+ tloInsertNewBeforeAndKeepOriginalIntactAndRemoveNothing:
+ begin
+ //Before
+
+ //Must be place as first TrackerList.TrackerAddedByUserList.
+ for TrackerStr in TrackerList.TrackerAddedByUserList do
+ AddButIngnoreDuplicates(TrackerList.TrackerFinalList, TrackerStr);
+
+ //remove duplicate from the list.
+ RemoveTrackersFromList(TrackerFromInsideOneTorrentFile,
+ TrackerList.TrackerFinalList);
+
+ //original tracker list is second place (Keep original intact)
+ for TrackerStr in TrackerFromInsideOneTorrentFile do
+ AddButIngnoreDuplicates(TrackerList.TrackerFinalList, TrackerStr);
+
+ //Nothing should be removed
+ TrackerList.TrackerManualyDeselectedByUserList.Clear;
+ end;
+
+
+ tloAppendNewAfterAndKeepOriginalIntactAndRemoveNothing:
+ begin
+ //After
+
+ //original tracker list is first place (Keep original intact)
+ for TrackerStr in TrackerFromInsideOneTorrentFile do
+ AddButIngnoreDuplicates(TrackerList.TrackerFinalList, TrackerStr);
+
+ //Must be place as second TrackerList.TrackerAddedByUserList.
+ for TrackerStr in TrackerList.TrackerAddedByUserList do
+ AddButIngnoreDuplicates(TrackerList.TrackerFinalList, TrackerStr);
+
+ //Nothing should be removed
+ TrackerList.TrackerManualyDeselectedByUserList.Clear;
+ end;
+
+ tloRandomize:
+ begin
+ //Randomize
+
+ for TrackerStr in TrackerList.TrackerAddedByUserList do
+ AddButIngnoreDuplicates(TrackerList.TrackerFinalList, TrackerStr);
+
+ for TrackerStr in TrackerList.TrackerFromInsideTorrentFilesList do
+ AddButIngnoreDuplicates(TrackerList.TrackerFinalList, TrackerStr);
+
+ RandomizeTrackerList(TrackerList.TrackerFinalList);
+ end;
+
+
+ else
+ begin
+ Assert(True, 'case else: Should never been called. CombineFiveTrackerListToOne');
+ end;
+ end;
+
+ //Trackers from TrackerList.TrackerAddedByUserList overrule the one from TrackerList.TrackerManualyDeselectedByUserList
+ //This is when there is a conflict betwean 'add' and 'remove manual selection'
+
+ //Must keep TrackerList.TrackerManualyDeselectedByUserList intact. Copy it to TrackerDeselectTempList
+ TrackerDeselectTempList := TStringList.Create;
+ TrackerDeselectTempList.Text :=
+ TrackerList.TrackerManualyDeselectedByUserList.Text;
+ RemoveTrackersFromList(TrackerList.TrackerAddedByUserList,
+ TrackerDeselectTempList);
+
+ //Remove the trackers that we do not want in FTrackerFinalList must be the last step.
+ RemoveTrackersFromList(TrackerList.TrackerBanByUserList,
+ TrackerList.TrackerFinalList);
+ RemoveTrackersFromList(TrackerDeselectTempList, TrackerList.TrackerFinalList);
+
+ //No longer needed
+ TrackerDeselectTempList.Free;
+
+ finally
+ //No longer needed
+ TrackerFromInsideOneTorrentFile.Free;
+ end;
+end;
+
+
+
+function ConsoleModeDecodeParameter(out FileNameOrDirStr: UTF8String;
+ var TrackerList: TTrackerList): boolean;
+var
+ i: integer;
+begin
+ {
+ Console mode can be started with example 2 parameter
+ Update methode: -U0 , -U1, -U2, -U3, -U4 etc.
+ String with a link to folder or to torrent file. 'C:\dir'
+
+ Must keep backward compatible with the first and previeus release.
+ First or seccond parameter must be related to -Ux
+
+ other parameter after are optional -SOC and -SOURCE
+
+ example:
+ "path_to_folder" -U3 -SAC -SOURCE "ABC"
+ -U3 "path_to_folder" -SAC -SOURCE "ABC"
+ }
+
+ case Paramcount of
+ 0:
+ begin
+ TrackerList.LogStringList.Add('ERROR: There are no parameter detected.');
+ Result := False;
+ exit;
+ end;
+ 1:
+ begin
+ //one parameter. Must be a link.
+ FileNameOrDirStr := UTF8Trim(ParamStr(1));
+ //Keep the same behaviour as the previeus software version.
+ TrackerList.TrackerListOrderForUpdatedTorrent := tloSort;
+ Result := True;
+ end;
+ else
+ begin
+ //Two parameters. The user can select the update methode.
+ //Check for '-U' contruction as first parameter
+ if (Pos('-U', ParamStr(1)) = 1) then
+ begin
+ //Update parameter is the first parameter
+ Result := DecodeConsoleUpdateParameter(ParamStr(1), TrackerList);
+ // second parameter is the file/folder
+ FileNameOrDirStr := UTF8Trim(ParamStr(2));
+ Exit;
+ end;
+
+ //Check for '-U' contruction as second parameter
+ if (Pos('-U', ParamStr(2)) = 1) then
+ begin
+ // Update parameter is the second parameter
+ Result := DecodeConsoleUpdateParameter(ParamStr(2), TrackerList);
+ // first parameter MUST be the file/folder
+ FileNameOrDirStr := UTF8Trim(ParamStr(1));
+ end;
+
+ //Check for parameter -SAC and -SOURCE
+ for i := 2 to ParamCount do
+ begin
+ if ParamStr(i) = '-SAC' then
+ begin
+ TrackerList.SkipAnnounceCheck := True;
+ Continue;
+ end;
+
+ if ParamStr(i) = '-SOURCE' then
+ begin
+ if ParamCount < i + 1 then
+ begin
+ TrackerList.LogStringList.Add(
+ 'ERROR: There is no value after -SOURCE');
+ Result := False;
+ exit;
+ end;
+
+ // parameter after -SOURCE must be the value.
+ TrackerList.SourceTag := ParamStr(i + 1);
+ // Empty '' -> remove all source tag
+ TrackerList.RemoveAllSourceTag := TrackerList.SourceTag = '';
+ end;
+ end;
+
+ end;
+ //else
+ //begin
+ // TrackerList.LogStringList.Add(
+ // 'ERROR: There can only be maximum of 2 parameter. Not: ' + IntToStr(ParamCount));
+ // Result := False;
+ // exit;
+ //end;
+
+ end;
+end;
+
+function DecodeConsoleUpdateParameter(const ConsoleUpdateParameter: UTF8String;
+ var TrackerList: TTrackerList): boolean;
+var
+ i: integer;
+begin
+ //Decode the '-Ux' x is number [0..4]
+
+ //verify string content.
+ Result := (Pos('-U', ConsoleUpdateParameter) = 1) and
+ (length(ConsoleUpdateParameter) = 3);
+
+ if Result then
+ begin
+ //get the number
+ Result := TryStrToInt(ConsoleUpdateParameter[3], i);
+ if Result then
+ begin
+
+ //check if it is within range
+ Result := (i >= Ord(low(TTrackerListOrder))) and
+ (i <= Ord(high(TTrackerListOrder)));
+
+ if Result then
+ TrackerList.TrackerListOrderForUpdatedTorrent := TTrackerListOrder(i);
+
+{
+ //decode number [0..7]
+ case i of
+ 0: TrackerList.TrackerListOrderForUpdatedTorrent := tloInsertNewBeforeAndKeepNewIntact; //tloInsertNewBeforeAndKeepNewIntact
+ 1: TrackerList.TrackerListOrderForUpdatedTorrent := tloInsertNewBeforeAndKeepOriginalIntact; //tloInsertNewBeforeAndKeepOriginalIntact
+ 2: TrackerList.TrackerListOrderForUpdatedTorrent := tloAppendNewAfterAndKeepNewIntact; //tloAppendNewAfterAndKeepNewIntact
+ 3: TrackerList.TrackerListOrderForUpdatedTorrent := tloAppendNewAfterAndKeepOriginalIntact; //tloAppendNewAfterAndKeepOriginalIntact
+ 4: TrackerList.TrackerListOrderForUpdatedTorrent := tloSort;
+ 5: TrackerList.TrackerListOrderForUpdatedTorrent := tloInsertNewBeforeAndKeepOriginalIntactAndRemoveNothing;
+ 6: TrackerList.TrackerListOrderForUpdatedTorrent := tloAppendNewAfterAndKeepOriginalIntactAndRemoveNothing;
+ 7: TrackerList.TrackerListOrderForUpdatedTorrent := tloRandomize;
+ else
+ begin
+ //the number is out of range.
+ Result := False;
+ end;
+ end;
+}
+
+ end;
+ end;
+
+ if not Result then
+ begin
+ TrackerList.LogStringList.Add('ERROR: can not decode update parameter -U : ' +
+ ConsoleUpdateParameter);
+ end;
+end;
+
+function TrackerURLWithAnnounce(const TrackerURL: UTF8String): boolean;
+const
+ ANNOUNCE_STRING: string = '/announce';
+ ANNOUNCE_PHP_STRING: string = '/announce.php';
+begin
+ //TrackerURL must end with ANNOUNCE_STRING
+ Result := (RightStr(TrackerURL, length(ANNOUNCE_STRING)) = ANNOUNCE_STRING) or
+ (RightStr(TrackerURL, length(ANNOUNCE_PHP_STRING)) = ANNOUNCE_PHP_STRING);
+
+end;
+
+end.
diff --git a/source/code/trackerlist_online.pas b/source/code/trackerlist_online.pas
new file mode 100644
index 0000000..5eb00ac
--- /dev/null
+++ b/source/code/trackerlist_online.pas
@@ -0,0 +1,97 @@
+// SPDX-License-Identifier: MIT
+unit trackerlist_online;
+
+{
+ Get the status of the TrackerURL by comparing with the 'online trackers database'
+ These data are comming from https://newtrackon.com/
+}
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils;
+
+type
+ //What is the status of this tracker
+ TTrackerListOnlineStatus = (
+ tos_stable, //< Most of the time present online
+ tos_live_but_unstable, //< Is present online but unstable
+ tos_dead, //< Was alive but now is dead
+ tos_unknown //< not in the database present
+ );
+
+ { TTrackerListOnline }
+
+ TTrackerListOnline = class
+ private
+ public
+ // currently active and responding trackers.
+ TrackerList_Live: TStringList;
+
+ // trackers that have an uptime of equal or more than 95%.
+ TrackerList_Stable: TStringList;
+
+ // trackers that no longer present in 'live' list
+ TrackerList_Dead: TStringList;
+
+ //return the status of the TrackerURL
+ function TrackerStatus(const TrackerURL: UTF8String): TTrackerListOnlineStatus;
+ function TrackerListOnlineStatusToString(Value: TTrackerListOnlineStatus): string;
+ end;
+
+
+implementation
+
+
+{ TTrackerListOnline }
+
+function TTrackerListOnline.TrackerStatus(
+ const TrackerURL: UTF8String): TTrackerListOnlineStatus;
+ //var
+ // index: integer;
+begin
+ //look for this tracker in all the posible string list
+
+ //TrackerList_Stable
+ if Assigned(TrackerList_Stable) and (TrackerList_Stable.IndexOf(TrackerURL) >= 0) then
+ begin
+ Result := tos_stable;
+ exit;
+ end;
+
+ //TrackerList_Dead
+ if Assigned(TrackerList_Dead) and (TrackerList_Dead.IndexOf(TrackerURL) >= 0) then
+ begin
+ Result := tos_dead;
+ exit;
+ end;
+
+ //TrackerList_Live
+ if Assigned(TrackerList_Live) and (TrackerList_Live.IndexOf(TrackerURL) >= 0) then
+ begin
+ //This tracker is online but not in present in the stable list.
+ //It is then mark as unstable
+ Result := tos_live_but_unstable;
+ exit;
+ end;
+
+ Result := tos_unknown;
+
+end;
+
+function TTrackerListOnline.TrackerListOnlineStatusToString(
+ Value: TTrackerListOnlineStatus): string;
+begin
+ case Value of
+ tos_stable: Result := 'Stable';
+ tos_live_but_unstable: Result := 'Unstable';
+ tos_dead: Result := 'Dead';
+ tos_unknown: Result := 'Unknown';
+ else
+ assert(True, 'Unknown TTrackerListOnlineStatus')
+ end;
+end;
+
+end.
diff --git a/source/project/.gitignore b/source/project/.gitignore
new file mode 100644
index 0000000..9f09d1d
--- /dev/null
+++ b/source/project/.gitignore
@@ -0,0 +1,6 @@
+# ignore link resource file
+link.res
+
+# ignore windows bat file
+*.bat
+
diff --git a/source/project/tracker_editor/link.res b/source/project/tracker_editor/link.res
deleted file mode 100644
index cd9f6b7..0000000
--- a/source/project/tracker_editor/link.res
+++ /dev/null
@@ -1,452 +0,0 @@
-SEARCH_DIR(C:\lazarus\lcl\units\i386-win32\win32\)
-SEARCH_DIR(C:\lazarus\lcl\units\i386-win32\)
-SEARCH_DIR(C:\lazarus\components\lazutils\lib\i386-win32\)
-SEARCH_DIR(C:\lazarus\packager\units\i386-win32\)
-SEARCH_DIR(.\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\httpd22\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\rtl\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\zorba\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\zlib\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\winunits-jedi\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\winunits-base\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\winceunits\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\unzip\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\tcl\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\symbolic\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\sqlite\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\sdl\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\rsvg\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\regexpr\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\pxlib\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\ptc\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\postgres\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\pcap\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\paszlib\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\pasjpeg\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\oracle\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\openssl\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\opengl\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\opencl\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\openal\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\oggvorbis\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\odbc\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\nvapi\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\numlib\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\mysql\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\mad\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\lua\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\libxml2\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\libsee\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\libpng\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\libgd\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\lexyacc\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\imagemagick\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\ibase\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\hermes\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\hash\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\gtk2\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\gtk1\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\graph\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\gmp\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\gdbint\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\fv\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\fppkg\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\fpmkunit\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\fpindexer\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\fpgtk\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\fftw\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\fcl-xml\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\fcl-web\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\fcl-res\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\fcl-registry\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\fcl-process\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\fcl-passrc\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\fcl-net\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\fcl-json\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\fcl-js\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\fcl-image\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\fcl-fpcunit\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\fcl-extra\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\fcl-db\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\fcl-base\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\fastcgi\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\dblib\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\chm\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\cdrom\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\cairo\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\bzip2\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\aspell\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\a52\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\units\i386-win32\)
-SEARCH_DIR(C:\lazarus\fpc\2.6.2\bin\i386-win32\)
-INPUT(
-D:\lazarus\source\trackereditor\src\lib\i386-win32\trackereditor.o
-D:\lazarus\source\trackereditor\src\lib\i386-win32\trackereditor.or
-C:\lazarus\fpc\2.6.2\units\i386-win32\rtl\system.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\rtl\fpintres.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\rtl\objpas.o
-C:\lazarus\lcl\units\i386-win32\win32\interfaces.o
-C:\lazarus\lcl\units\i386-win32\forms.o
-D:\lazarus\source\trackereditor\src\lib\i386-win32\main.o
-D:\lazarus\source\trackereditor\src\lib\i386-win32\bencode.o
-D:\lazarus\source\trackereditor\src\lib\i386-win32\decodetorrent.o
-C:\lazarus\lcl\units\i386-win32\interfacebase.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\rtl\types.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\rtl\classes.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\rtl\sysutils.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\rtl\math.o
-C:\lazarus\lcl\units\i386-win32\lclstrconsts.o
-C:\lazarus\lcl\units\i386-win32\lcltype.o
-C:\lazarus\lcl\units\i386-win32\lclproc.o
-C:\lazarus\lcl\units\i386-win32\lmessages.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\fcl-image\fpimage.o
-C:\lazarus\lcl\units\i386-win32\graphtype.o
-C:\lazarus\lcl\units\i386-win32\graphmath.o
-C:\lazarus\lcl\units\i386-win32\intfgraphics.o
-C:\lazarus\lcl\units\i386-win32\themes.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\rtl\windows.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\rtl\rtlconsts.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\rtl\typinfo.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\rtl\sysconst.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\rtl\windirs.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\winunits-base\win9xwsmanager.o
-C:\lazarus\components\lazutils\lib\i386-win32\lazlogger.o
-C:\lazarus\lcl\units\i386-win32\fpcadds.o
-C:\lazarus\components\lazutils\lib\i386-win32\avglvltree.o
-C:\lazarus\components\lazutils\lib\i386-win32\fileutil.o
-C:\lazarus\lcl\units\i386-win32\wsreferences.o
-C:\lazarus\components\lazutils\lib\i386-win32\lazmethodlist.o
-C:\lazarus\components\lazutils\lib\i386-win32\lazutf8.o
-C:\lazarus\components\lazutils\lib\i386-win32\lazloggerbase.o
-C:\lazarus\components\lazutils\lib\i386-win32\lazclasses.o
-C:\lazarus\components\lazutils\lib\i386-win32\masks.o
-C:\lazarus\components\lazutils\lib\i386-win32\lazutilsstrconsts.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\fcl-base\contnrs.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\fcl-base\gettext.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\rtl\messages.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\fcl-image\fpreadbmp.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\fcl-image\fpwritebmp.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\fcl-image\bmpcomn.o
-C:\lazarus\lcl\units\i386-win32\lclversion.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\fcl-image\fpreadpng.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\fcl-image\fpwritepng.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\fcl-image\fpreadtiff.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\fcl-image\fpwritetiff.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\fcl-image\fptiffcmn.o
-C:\lazarus\lcl\units\i386-win32\icnstypes.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\fcl-image\fpimgcmn.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\fcl-image\pngcomn.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\paszlib\zstream.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\paszlib\zbase.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\paszlib\gzio.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\rtl\dos.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\hash\crc.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\paszlib\zdeflate.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\paszlib\zinflate.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\rtl\strings.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\paszlib\trees.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\paszlib\adler.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\paszlib\infblock.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\paszlib\infutil.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\paszlib\infcodes.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\paszlib\inftrees.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\paszlib\inffast.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\rtl\ctypes.o
-C:\lazarus\lcl\units\i386-win32\graphics.o
-C:\lazarus\lcl\units\i386-win32\lclintf.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\fcl-image\fpcanvas.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\fcl-image\fpreadpnm.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\fcl-image\fpwritepnm.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\fcl-image\fpreadjpeg.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\fcl-image\fpwritejpeg.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\fcl-image\fpreadgif.o
-C:\lazarus\lcl\units\i386-win32\lresources.o
-C:\lazarus\lcl\units\i386-win32\lclrescache.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\fcl-image\clipping.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\pasjpeg\jpeglib.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\pasjpeg\jdapimin.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\pasjpeg\jdatasrc.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\pasjpeg\jdapistd.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\pasjpeg\jmorecfg.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\pasjpeg\jdeferr.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\pasjpeg\jinclude.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\pasjpeg\jerror.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\pasjpeg\jmemmgr.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\pasjpeg\jdmarker.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\pasjpeg\jdinput.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\pasjpeg\jcomapi.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\pasjpeg\jutils.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\pasjpeg\jmemnobs.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\pasjpeg\jdmaster.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\pasjpeg\jdcolor.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\pasjpeg\jdsample.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\pasjpeg\jdpostct.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\pasjpeg\jddctmgr.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\pasjpeg\jdphuff.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\pasjpeg\jdhuff.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\pasjpeg\jdcoefct.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\pasjpeg\jdmainct.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\pasjpeg\jquant1.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\pasjpeg\jquant2.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\pasjpeg\jdmerge.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\pasjpeg\jdct.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\pasjpeg\jidctfst.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\pasjpeg\jidctint.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\pasjpeg\jidctflt.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\pasjpeg\jidctred.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\pasjpeg\jcapistd.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\pasjpeg\jcapimin.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\pasjpeg\jdatadst.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\pasjpeg\jcparam.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\pasjpeg\jcinit.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\pasjpeg\jcmarker.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\pasjpeg\jcphuff.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\pasjpeg\jchuff.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\pasjpeg\jcmaster.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\pasjpeg\jccolor.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\pasjpeg\jcsample.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\pasjpeg\jcprepct.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\pasjpeg\jcdctmgr.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\pasjpeg\jccoefct.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\pasjpeg\jcmainct.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\pasjpeg\jfdctint.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\pasjpeg\jfdctfst.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\pasjpeg\jfdctflt.o
-C:\lazarus\lcl\units\i386-win32\dynqueue.o
-C:\lazarus\lcl\units\i386-win32\lazconfigstorage.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\fcl-base\syncobjs.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\winunits-base\shellapi.o
-C:\lazarus\lcl\units\i386-win32\utf8process.o
-C:\lazarus\lcl\units\i386-win32\maps.o
-C:\lazarus\components\lazutils\lib\i386-win32\lazutf8sysutils.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\winunits-base\activex.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\rtl\variants.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\rtl\varutils.o
-C:\lazarus\lcl\units\i386-win32\tmschema.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\fcl-process\process.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\fcl-process\pipes.o
-C:\lazarus\lcl\units\i386-win32\win32\win32int.o
-C:\lazarus\lcl\units\i386-win32\translations.o
-C:\lazarus\lcl\units\i386-win32\comctrls.o
-C:\lazarus\lcl\units\i386-win32\controls.o
-C:\lazarus\lcl\units\i386-win32\buttons.o
-C:\lazarus\lcl\units\i386-win32\dialogs.o
-C:\lazarus\lcl\units\i386-win32\stdctrls.o
-C:\lazarus\lcl\units\i386-win32\win32\win32def.o
-C:\lazarus\lcl\units\i386-win32\menus.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\winunits-base\commctrl.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\winunits-base\multimon.o
-C:\lazarus\lcl\units\i386-win32\stringhashlist.o
-C:\lazarus\components\lazutils\lib\i386-win32\lconvencoding.o
-C:\lazarus\lcl\units\i386-win32\imglist.o
-C:\lazarus\lcl\units\i386-win32\actnlist.o
-C:\lazarus\lcl\units\i386-win32\extctrls.o
-C:\lazarus\lcl\units\i386-win32\toolwin.o
-C:\lazarus\lcl\units\i386-win32\wslclclasses.o
-C:\lazarus\lcl\units\i386-win32\lclclasses.o
-C:\lazarus\lcl\units\i386-win32\wsimglist.o
-C:\lazarus\lcl\units\i386-win32\wsproc.o
-C:\lazarus\lcl\units\i386-win32\wsfactory.o
-C:\lazarus\lcl\units\i386-win32\propertystorage.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\fcl-base\rttiutils.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\rtl\strutils.o
-C:\lazarus\lcl\units\i386-win32\wsmenus.o
-C:\lazarus\lcl\units\i386-win32\customtimer.o
-C:\lazarus\lcl\units\i386-win32\clipbrd.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\fcl-base\custapp.o
-C:\lazarus\lcl\units\i386-win32\helpintfs.o
-C:\lazarus\lcl\units\i386-win32\wscontrols.o
-C:\lazarus\lcl\units\i386-win32\wsforms.o
-C:\lazarus\lcl\units\i386-win32\extendedstrings.o
-C:\lazarus\lcl\units\i386-win32\textstrings.o
-C:\lazarus\lcl\units\i386-win32\wsstdctrls.o
-C:\lazarus\lcl\units\i386-win32\popupnotifier.o
-C:\lazarus\lcl\units\i386-win32\wsextctrls.o
-C:\lazarus\lcl\units\i386-win32\imagelistcache.o
-C:\lazarus\lcl\units\i386-win32\wsbuttons.o
-C:\lazarus\lcl\units\i386-win32\wscomctrls.o
-C:\lazarus\lcl\units\i386-win32\wstoolwin.o
-C:\lazarus\lcl\units\i386-win32\buttonpanel.o
-C:\lazarus\lcl\units\i386-win32\wsdialogs.o
-C:\lazarus\lcl\units\i386-win32\win32\win32proc.o
-C:\lazarus\lcl\units\i386-win32\win32\win32wsfactory.o
-C:\lazarus\lcl\units\i386-win32\win32\win32wsbuttons.o
-C:\lazarus\lcl\units\i386-win32\win32\win32wsmenus.o
-C:\lazarus\lcl\units\i386-win32\win32\win32wsstdctrls.o
-C:\lazarus\lcl\units\i386-win32\win32\win32wsdialogs.o
-C:\lazarus\lcl\units\i386-win32\win32\win32themes.o
-C:\lazarus\lcl\units\i386-win32\win32\win32extra.o
-C:\lazarus\lcl\units\i386-win32\lclmessageglue.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\winunits-base\shlobj.o
-C:\lazarus\lcl\units\i386-win32\calendar.o
-C:\lazarus\lcl\units\i386-win32\arrow.o
-C:\lazarus\lcl\units\i386-win32\spin.o
-C:\lazarus\lcl\units\i386-win32\extdlgs.o
-C:\lazarus\lcl\units\i386-win32\checklst.o
-C:\lazarus\lcl\units\i386-win32\grids.o
-C:\lazarus\lcl\units\i386-win32\wscalendar.o
-C:\lazarus\lcl\units\i386-win32\wsarrow.o
-C:\lazarus\lcl\units\i386-win32\wsspin.o
-C:\lazarus\lcl\units\i386-win32\wsextdlgs.o
-C:\lazarus\lcl\units\i386-win32\wschecklst.o
-C:\lazarus\lcl\units\i386-win32\dynamicarray.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\fcl-xml\xmlconf.o
-C:\lazarus\lcl\units\i386-win32\maskedit.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\fcl-xml\dom.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\fcl-xml\xmlread.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\fcl-xml\xmlwrite.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\fcl-xml\xmlutils.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\fcl-xml\dtdmodel.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\fcl-base\uriparser.o
-C:\lazarus\lcl\units\i386-win32\wsgrids.o
-C:\lazarus\lcl\units\i386-win32\win32\win32wsarrow.o
-C:\lazarus\lcl\units\i386-win32\win32\win32wscalendar.o
-C:\lazarus\lcl\units\i386-win32\win32\win32wschecklst.o
-C:\lazarus\lcl\units\i386-win32\win32\win32wscomctrls.o
-C:\lazarus\lcl\units\i386-win32\win32\win32wscontrols.o
-C:\lazarus\lcl\units\i386-win32\win32\win32wsextctrls.o
-C:\lazarus\lcl\units\i386-win32\win32\win32wsextdlgs.o
-C:\lazarus\lcl\units\i386-win32\win32\win32wsforms.o
-C:\lazarus\lcl\units\i386-win32\win32\win32wsgrids.o
-C:\lazarus\lcl\units\i386-win32\win32\win32wsimglist.o
-C:\lazarus\lcl\units\i386-win32\win32\win32wsspin.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\winunits-base\uxtheme.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\winunits-base\commdlg.o
-C:\lazarus\fpc\2.6.2\units\i386-win32\rtl\sysinitpas.o
-)
-GROUP(
-C:\lazarus\fpc\2.6.2\units\i386-win32\rtl\libimpsystem.a
-C:\lazarus\fpc\2.6.2\units\i386-win32\rtl\libimpfpintres.a
-C:\lazarus\fpc\2.6.2\units\i386-win32\rtl\libimpsysutils.a
-C:\lazarus\fpc\2.6.2\units\i386-win32\rtl\libimpwindows.a
-C:\lazarus\fpc\2.6.2\units\i386-win32\rtl\libimpdos.a
-C:\lazarus\fpc\2.6.2\units\i386-win32\winunits-base\libimpshellapi.a
-C:\lazarus\fpc\2.6.2\units\i386-win32\winunits-base\libimpactivex.a
-C:\lazarus\fpc\2.6.2\units\i386-win32\rtl\libimpvarutils.a
-C:\lazarus\fpc\2.6.2\units\i386-win32\winunits-base\libimpcommctrl.a
-C:\lazarus\lcl\units\i386-win32\win32\libimpwin32extra.a
-C:\lazarus\fpc\2.6.2\units\i386-win32\winunits-base\libimpshlobj.a
-C:\lazarus\lcl\units\i386-win32\win32\libimpwin32wsforms.a
-C:\lazarus\fpc\2.6.2\units\i386-win32\winunits-base\libimpcommdlg.a
-C:\lazarus\fpc\2.6.2\units\i386-win32\rtl\libimpsysinitpas.a
-)
-SEARCH_DIR("/usr/i686-pc-cygwin/lib"); SEARCH_DIR("/usr/lib"); SEARCH_DIR("/usr/lib/w32api");
-OUTPUT_FORMAT(pei-i386)
-ENTRY(_mainCRTStartup)
-SECTIONS
-{
- . = SIZEOF_HEADERS;
- . = ALIGN(__section_alignment__);
- .text __image_base__ + ( __section_alignment__ < 0x1000 ? . : __section_alignment__ ) :
- {
- *(.init)
- *(.text .stub .text.* .gnu.linkonce.t.*)
- *(SORT(.text$*))
- *(.glue_7t)
- *(.glue_7)
- . = ALIGN(8);
- ___CTOR_LIST__ = .; __CTOR_LIST__ = . ;
- LONG (-1);
- *(.ctors); *(.ctor); *(SORT(.ctors.*)); LONG (0);
- ___DTOR_LIST__ = .; __DTOR_LIST__ = . ;
- LONG (-1);
- *(.dtors); *(.dtor); *(SORT(.dtors.*)); LONG (0);
- *(.fini)
- PROVIDE (etext = .);
- *(.gcc_except_table)
- }
- .data BLOCK(__section_alignment__) :
- {
- __data_start__ = . ;
- *(.data .data.* .gnu.linkonce.d.* .fpc*)
- *(.data2)
- *(SORT(.data$*))
- *(.jcr)
- PROVIDE (__tls_index = .);
- LONG (0);
- __data_end__ = . ;
- *(.data_cygwin_nocopy)
- }
- .rdata BLOCK(__section_alignment__) :
- {
- *(.rdata)
- *(.rodata .rodata.* .gnu.linkonce.r.*)
- *(SORT(.rdata$*))
- *(.eh_frame)
- ___RUNTIME_PSEUDO_RELOC_LIST__ = .;
- __RUNTIME_PSEUDO_RELOC_LIST__ = .;
- *(.rdata_runtime_pseudo_reloc)
- ___RUNTIME_PSEUDO_RELOC_LIST_END__ = .;
- __RUNTIME_PSEUDO_RELOC_LIST_END__ = .;
- }
- .pdata BLOCK(__section_alignment__) : { *(.pdata) }
- .bss BLOCK(__section_alignment__) :
- {
- __bss_start__ = . ;
- *(.bss .bss.* .gnu.linkonce.b.*)
- *(SORT(.bss$*))
- *(COMMON)
- __bss_end__ = . ;
- }
- .edata BLOCK(__section_alignment__) : { *(.edata) }
- .idata BLOCK(__section_alignment__) :
- {
- SORT(*)(.idata$2)
- SORT(*)(.idata$3)
- /* These zeroes mark the end of the import list. */
- LONG (0); LONG (0); LONG (0); LONG (0); LONG (0);
- SORT(*)(.idata$4)
- SORT(*)(.idata$5)
- SORT(*)(.idata$6)
- SORT(*)(.idata$7)
- }
- .CRT BLOCK(__section_alignment__) :
- {
- ___crt_xc_start__ = . ;
- *(SORT(.CRT$XC*)) /* C initialization */
- ___crt_xc_end__ = . ;
- ___crt_xi_start__ = . ;
- *(SORT(.CRT$XI*)) /* C++ initialization */
- ___crt_xi_end__ = . ;
- ___crt_xl_start__ = . ;
- *(SORT(.CRT$XL*)) /* TLS callbacks */
- /* ___crt_xl_end__ is defined in the TLS Directory support code */
- PROVIDE (___crt_xl_end__ = .);
- ___crt_xp_start__ = . ;
- *(SORT(.CRT$XP*)) /* Pre-termination */
- ___crt_xp_end__ = . ;
- ___crt_xt_start__ = . ;
- *(SORT(.CRT$XT*)) /* Termination */
- ___crt_xt_end__ = . ;
- }
- .tls BLOCK(__section_alignment__) :
- {
- ___tls_start__ = . ;
- *(.tls .tls.*)
- *(.tls$)
- *(SORT(.tls$*))
- ___tls_end__ = . ;
- }
- .rsrc BLOCK(__section_alignment__) :
- {
- *(.rsrc)
- *(SORT(.rsrc$*))
- }
- .reloc BLOCK(__section_alignment__) : { *(.reloc) }
- .stab BLOCK(__section_alignment__) (NOLOAD) : { *(.stab) }
- .stabstr BLOCK(__section_alignment__) (NOLOAD) : { *(.stabstr) }
- .debug_aranges BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_aranges) }
- .debug_pubnames BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_pubnames) }
- .debug_info BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_info) *(.gnu.linkonce.wi.*) }
- .debug_abbrev BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_abbrev) }
- .debug_line BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_line) }
- .debug_frame BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_frame) }
- .debug_str BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_str) }
- .debug_loc BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_loc) }
- .debug_macinfo BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_macinfo) }
- .debug_weaknames BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_weaknames) }
- .debug_funcnames BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_funcnames) }
- .debug_typenames BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_typenames) }
- .debug_varnames BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_varnames) }
- .debug_ranges BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_ranges) }
-}
diff --git a/source/project/tracker_editor/ppas.bat b/source/project/tracker_editor/ppas.bat
deleted file mode 100644
index a02c47b..0000000
--- a/source/project/tracker_editor/ppas.bat
+++ /dev/null
@@ -1,14 +0,0 @@
-@echo off
-SET THEFILE=trackereditor.exe
-echo Linking %THEFILE%
-C:\lazarus\fpc\2.6.2\bin\i386-win32\ld.exe -b pei-i386 -m i386pe --gc-sections -s --subsystem windows --entry=_WinMainCRTStartup -o trackereditor.exe link.res
-if errorlevel 1 goto linkend
-C:\lazarus\fpc\2.6.2\bin\i386-win32\postw32.exe --subsystem gui --input trackereditor.exe --stack 16777216
-if errorlevel 1 goto linkend
-goto end
-:asmend
-echo An error occured while assembling %THEFILE%
-goto end
-:linkend
-echo An error occured while linking %THEFILE%
-:end
diff --git a/source/project/tracker_editor/trackereditor.lpi b/source/project/tracker_editor/trackereditor.lpi
index 5601ff2..11ee463 100644
--- a/source/project/tracker_editor/trackereditor.lpi
+++ b/source/project/tracker_editor/trackereditor.lpi
@@ -1,12 +1,13 @@
-
+
+
@@ -16,459 +17,145 @@
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
-
-
-
+
+
-
-
-
-
+
+
+
-
-
+
+
+
+
+
-
-
-
-
-
-
+
+
-
-
-
-
-
-
+
+
-
-
-
-
+
+
-
-
-
-
+
+
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
@@ -487,7 +174,7 @@
-
+
diff --git a/source/project/tracker_editor/trackereditor.lpr b/source/project/tracker_editor/trackereditor.lpr
index d4a2242..808047a 100644
--- a/source/project/tracker_editor/trackereditor.lpr
+++ b/source/project/tracker_editor/trackereditor.lpr
@@ -7,7 +7,9 @@
cthreads,
{$ENDIF}{$ENDIF}
Interfaces, // this includes the LCL widgetset
- Forms, main, bencode, decodetorrent, controlergridtorrentdata;
+ Forms, main, bencode, decodetorrent, controlergridtorrentdata,
+controler_trackerlist_online, trackerlist_online,
+controler_treeview_torrent_data;
{$R *.res}
diff --git a/source/project/tracker_editor/trackereditor.res b/source/project/tracker_editor/trackereditor.res
index 7c6cf3e..f6e8499 100644
Binary files a/source/project/tracker_editor/trackereditor.res and b/source/project/tracker_editor/trackereditor.res differ
diff --git a/source/project/unit_test/tracker_editor_test.lpi b/source/project/unit_test/tracker_editor_test.lpi
new file mode 100644
index 0000000..e0d0afb
--- /dev/null
+++ b/source/project/unit_test/tracker_editor_test.lpi
@@ -0,0 +1,169 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/source/project/unit_test/tracker_editor_test.lpr b/source/project/unit_test/tracker_editor_test.lpr
new file mode 100644
index 0000000..5dc2c9f
--- /dev/null
+++ b/source/project/unit_test/tracker_editor_test.lpr
@@ -0,0 +1,57 @@
+program tracker_editor_test;
+
+{$mode objfpc}{$H+}
+
+uses
+ Classes, consoletestrunner, fpcunit,
+ fpcunitreport, test_newtrackon, test_ngosang_trackers_list, test_start_up_parameter,
+torrent_miscellaneous, test_miscellaneous, ngosang_trackerslist;
+
+type
+
+ { TLazTestRunner }
+
+ { TMyTestRunner }
+
+ TMyTestRunner = class(TTestRunner)
+ protected
+ // override the protected methods of TTestRunner to customize its behavior
+ procedure DoTestRun(ATest: TTest); override;
+ end;
+
+var
+ Application: TMyTestRunner;
+
+{ TMyTestRunner }
+
+procedure TMyTestRunner.DoTestRun(ATest: TTest);
+var
+ ResultsWriter: TCustomResultsWriter;
+ TestResult: TTestResult;
+begin
+ ResultsWriter := GetResultsWriter;
+ ResultsWriter.Filename := FileName;
+ TestResult := TTestResult.Create;
+ try
+ TestResult.AddListener(ResultsWriter);
+ ATest.Run(TestResult);
+ ResultsWriter.WriteResult(TestResult);
+
+ //if something failed then exit with error: 1
+ if (TestResult.NumberOfErrors > 0) or (TestResult.NumberOfFailures > 0) then
+ begin
+ System.ExitCode := 1;
+ end;
+
+ finally
+ TestResult.Free;
+ ResultsWriter.Free;
+ end;
+end;
+
+begin
+ Application := TMyTestRunner.Create(nil);
+ Application.Initialize;
+ Application.Run;
+ Application.Free;
+end.
diff --git a/source/test/bat/U0.bat b/source/test/bat/U0.bat
deleted file mode 100644
index a2c15b7..0000000
--- a/source/test/bat/U0.bat
+++ /dev/null
@@ -1,41 +0,0 @@
-echo off
-rem Test trackereditor.exe via command line.
-
-rem Console parameter: -U0
-rem Insert new trackers list BEFORE, the original trackers list inside the torrent file.
-rem And remove possible duplicated trackers from the ORIGINAL trackers list.
-
-SETLOCAL
-
-rem clean all torrent trackers
-call dht_torrent.bat
-
-rem default variables
-call variables.bat
-
-rem add some ORIGINAL trackers
-echo %t_d%> %add_trackers_txt%
-echo %t_a%>> %add_trackers_txt%
-echo %t_c%>> %add_trackers_txt%
-echo %t_b%>> %add_trackers_txt%
-
-rem remove_trackers_txt file.
-del %remove_trackers_txt%
-
-rem modify the torrent folder
-%path_to_enduser%trackereditor.exe %path_to_torrent% -U0
-
-rem add some NEW trackers
-echo %t_o%> %add_trackers_txt%
-echo %t_b%>> %add_trackers_txt%
-echo %t_p%>> %add_trackers_txt%
-echo %t_m%>> %add_trackers_txt%
-
-rem modify the torrent folder
-%path_to_enduser%trackereditor.exe %path_to_torrent% -U0
-
-rem torrent must filled with trackers in this order: new(o,b,p,m) + original(d,a,c,b)
-rem -> remove duplicated from original -> o,b,p,m,d,a,c,
-
-ENDLOCAL
-exit /b
diff --git a/source/test/bat/U1.bat b/source/test/bat/U1.bat
deleted file mode 100644
index 9c2f74f..0000000
--- a/source/test/bat/U1.bat
+++ /dev/null
@@ -1,41 +0,0 @@
-echo off
-rem Test trackereditor.exe via command line.
-
-rem Console parameter: -U1
-rem Insert new trackers list BEFORE, the original trackers list inside the torrent file.
-rem And remove possible duplicated trackers from the NEW trackers list.
-
-SETLOCAL
-
-rem clean all torrent trackers
-call dht_torrent.bat
-
-rem default variables
-call variables.bat
-
-rem add some ORIGINAL trackers
-echo %t_d%> %add_trackers_txt%
-echo %t_p%>> %add_trackers_txt%
-echo %t_c%>> %add_trackers_txt%
-echo %t_b%>> %add_trackers_txt%
-
-rem remove_trackers_txt file.
-del %remove_trackers_txt%
-
-rem modify the torrent folder
-%path_to_enduser%trackereditor.exe %path_to_torrent% -U1
-
-rem add some NEW trackers
-echo %t_o%> %add_trackers_txt%
-echo %t_n%>> %add_trackers_txt%
-echo %t_p%>> %add_trackers_txt%
-echo %t_m%>> %add_trackers_txt%
-
-rem modify the torrent folder
-%path_to_enduser%trackereditor.exe %path_to_torrent% -U1
-
-rem torrent must filled with trackers in this order: new(o,n,p,m) + original(d,p,c,b)
-rem -> remove duplicated from new -> o,n,m,d,p,c,b
-
-ENDLOCAL
-exit /b
diff --git a/source/test/bat/U2.bat b/source/test/bat/U2.bat
deleted file mode 100644
index 0be29ac..0000000
--- a/source/test/bat/U2.bat
+++ /dev/null
@@ -1,41 +0,0 @@
-echo off
-rem Test trackereditor.exe via command line.
-
-rem Console parameter: -U2
-rem Append new trackers list AFTER, the original trackers list inside the torrent file.
-rem And remove possible duplicated trackers from the ORIGINAL trackers list.
-
-SETLOCAL
-
-rem clean all torrent trackers
-call dht_torrent.bat
-
-rem default variables
-call variables.bat
-
-rem add some ORIGINAL trackers
-echo %t_d%> %add_trackers_txt%
-echo %t_a%>> %add_trackers_txt%
-echo %t_c%>> %add_trackers_txt%
-echo %t_b%>> %add_trackers_txt%
-
-rem remove_trackers_txt file.
-del %remove_trackers_txt%
-
-rem modify the torrent folder
-%path_to_enduser%trackereditor.exe %path_to_torrent% -U2
-
-rem add some NEW trackers
-echo %t_o%> %add_trackers_txt%
-echo %t_n%>> %add_trackers_txt%
-echo %t_a%>> %add_trackers_txt%
-echo %t_m%>> %add_trackers_txt%
-
-rem modify the torrent folder
-%path_to_enduser%trackereditor.exe %path_to_torrent% -U2
-
-rem torrent must filled with trackers in this order: original(d,a,c,b) + new(o,n,a,m)
-rem -> remove duplicated from original -> d,c,b,o,n,a,m
-
-ENDLOCAL
-exit /b
diff --git a/source/test/bat/U3.bat b/source/test/bat/U3.bat
deleted file mode 100644
index 540d7b4..0000000
--- a/source/test/bat/U3.bat
+++ /dev/null
@@ -1,41 +0,0 @@
-echo off
-rem Test trackereditor.exe via command line.
-
-rem Console parameter: -U3
-rem Append new trackers list AFTER, the original trackers list inside the torrent file.
-rem And remove possible duplicated trackers from the NEW trackers list.
-
-SETLOCAL
-
-rem clean all torrent trackers
-call dht_torrent.bat
-
-rem default variables
-call variables.bat
-
-rem add some ORIGINAL trackers
-echo %t_d%> %add_trackers_txt%
-echo %t_a%>> %add_trackers_txt%
-echo %t_c%>> %add_trackers_txt%
-echo %t_b%>> %add_trackers_txt%
-
-rem remove_trackers_txt file.
-del %remove_trackers_txt%
-
-rem modify the torrent folder
-%path_to_enduser%trackereditor.exe %path_to_torrent% -U3
-
-rem add some NEW trackers
-echo %t_d%> %add_trackers_txt%
-echo %t_n%>> %add_trackers_txt%
-echo %t_a%>> %add_trackers_txt%
-echo %t_m%>> %add_trackers_txt%
-
-rem modify the torrent folder
-%path_to_enduser%trackereditor.exe %path_to_torrent% -U3
-
-rem torrent must filled with trackers in this order: original(d,a,c,b) + new(d,n,a,m)
-rem -> remove duplicated from new -> d,a,c,b,n,m
-
-ENDLOCAL
-exit /b
diff --git a/source/test/bat/U4.bat b/source/test/bat/U4.bat
deleted file mode 100644
index 56a3820..0000000
--- a/source/test/bat/U4.bat
+++ /dev/null
@@ -1,40 +0,0 @@
-echo off
-rem Test trackereditor.exe via command line.
-
-rem Console parameter: -U4
-rem Sort the trackers list by name.
-
-SETLOCAL
-
-rem clean all torrent trackers
-call dht_torrent.bat
-
-rem default variables
-call variables.bat
-
-rem add some ORIGINAL trackers
-echo %t_d%> %add_trackers_txt%
-echo %t_a%>> %add_trackers_txt%
-echo %t_c%>> %add_trackers_txt%
-echo %t_b%>> %add_trackers_txt%
-
-rem remove_trackers_txt file.
-del %remove_trackers_txt%
-
-rem modify the torrent folder
-%path_to_enduser%trackereditor.exe %path_to_torrent% -U4
-
-rem add some NEW trackers
-echo %t_b%> %add_trackers_txt%
-echo %t_n%>> %add_trackers_txt%
-echo %t_p%>> %add_trackers_txt%
-echo %t_m%>> %add_trackers_txt%
-
-rem modify the torrent folder
-%path_to_enduser%trackereditor.exe %path_to_torrent% -U4
-
-rem torrent must filled with trackers in this order: original(d,a,c,b) + new(b,n,p,m)
-rem -> sort my name -> a,b,c,d,m,n,p
-
-ENDLOCAL
-exit /b
diff --git a/source/test/bat/dht_torrent.bat b/source/test/bat/dht_torrent.bat
deleted file mode 100644
index aa051cb..0000000
--- a/source/test/bat/dht_torrent.bat
+++ /dev/null
@@ -1,21 +0,0 @@
-echo off
-rem Test trackereditor.exe via command line.
-
-rem remove all the trackers inside the torrent files
-
-SETLOCAL
-
-rem default variables
-call variables.bat
-
-rem empty remove_trackers_txt
-echo.> %remove_trackers_txt%
-
-rem empty remove_trackers_txt
-echo.> %add_trackers_txt%
-
-rem modify the torrent folder
-%path_to_enduser%trackereditor.exe %path_to_torrent%
-
-ENDLOCAL
-exit /b
\ No newline at end of file
diff --git a/source/test/bat/variables.bat b/source/test/bat/variables.bat
deleted file mode 100644
index 9ed3028..0000000
--- a/source/test/bat/variables.bat
+++ /dev/null
@@ -1,23 +0,0 @@
-echo off
-rem Test trackereditor.exe via command line.
-
-rem create default variable for the test.
-
-set "path_to_enduser=..\..\..\enduser\"
-set "path_to_torrent=%cd%\..\torrent"
-set "add_trackers_txt=%path_to_enduser%add_trackers.txt"
-set "remove_trackers_txt=%path_to_enduser%remove_trackers.txt"
-
-rem trackers
-set "t_a=http://a.com/announce"
-set "t_b=https://b.com/announce"
-set "t_c=udp://c.com:80/announce"
-set "t_d=udp://d.com:80/announce"
-
-
-set "t_m=udp://m.com:80/announce"
-set "t_n=udp://n.com:80/announce"
-set "t_o=udp://o.com:80/announce"
-set "t_p=udp://p.com:80/announce"
-
-exit /b
diff --git a/source/test/test_miscellaneous.pas b/source/test/test_miscellaneous.pas
new file mode 100644
index 0000000..2d9548d
--- /dev/null
+++ b/source/test/test_miscellaneous.pas
@@ -0,0 +1,626 @@
+// SPDX-License-Identifier: MIT
+unit test_miscellaneous;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils, torrent_miscellaneous;
+
+type
+ TStartupParameter = record
+ TrackerListOrder: TTrackerListOrder;
+ SkipAnnounceCheck: boolean;
+ SourcePresent: boolean;
+ SourceText: UTF8String;
+ end;
+
+
+ TVerifyTrackerResult = record
+ StartupParameter: TStartupParameter;
+
+ TrackerOriginal,
+ TrackerAdded,
+ TrackerRemoved,
+ TrackerEndResult: TStringList;
+
+ ErrorString: string;
+ end;
+
+
+function LoadConsoleLog(const FileNameWithPath: string; out StatusOK: boolean;
+ out TorrentFilesCount: integer; out TrackersCount: integer): boolean;
+
+function GetProjectRootFolderWithPathDelimiter: string;
+
+function VerifyTrackerResult(var VerifyTracker: TVerifyTrackerResult): boolean;
+
+procedure RemoveLineSeperation(TrackerList: TStringList);
+
+implementation
+
+type
+ TTrackerFoundInList = (tf_NotFound, tf_Increamental, tf_Skip);
+
+
+function GetProjectRootFolderWithPathDelimiter: string;
+begin
+ //the present folder is /enduser where the executable file is run
+ Result := ExtractFilePath(ParamStr(0));
+ Result := ExcludeTrailingBackslash(Result);
+ Result := ExtractFilePath(Result);
+end;
+
+function FindTracker(const Tracker: string; TrackerEndResult: TStringList;
+ var OldIndex, NewIndex: integer): TTrackerFoundInList;
+begin
+ NewIndex := TrackerEndResult.IndexOf(tracker);
+
+ if NewIndex < 0 then
+ begin
+ Result := tf_NotFound;
+ end
+ else
+ begin
+ if (NewIndex = OldIndex + 1) then
+ Result := tf_Increamental
+ else
+ Result := tf_Skip;
+ end;
+end;
+
+procedure FindTrackerList(ListToBeFound, SearchInlist, TrackerRemoved: TStringList;
+ out FirstIndex, LastIndex, ItemsFound: integer;
+ out TrackerFoundInList: TTrackerFoundInList);
+var
+ trackerToBeFoundStr: string;
+ IndexFound: integer;
+ OldIndex: integer;
+
+begin
+ //All ListToBeFound should be present in SearchInlist except when present in TrackerRemoved
+
+ //FirstIndex, LastIndex give information if the list is place in begin or end of the list.
+
+ //ItemsFound -> how many of the ListToBeFound are present in the list.
+ // this is not realy helpfull because the items can be removed via TrackerRemoved
+
+ //TrackerFoundInList
+ // tf_NotFound -> if this items is also not present in TrackerRemoved
+ // This is a error condition
+ // tf_Increamental this is when ListToBeFound is intact
+ // tf_Skip this is when ListToBeFound is NOT intact
+
+ //start with not found index range
+ FirstIndex := -1;
+ LastIndex := -1;
+ OldIndex := -1;
+
+ //start with no items found
+ ItemsFound := 0;
+
+ //start with not found status
+ TrackerFoundInList := tf_NotFound;
+
+
+ //look for each string one by one
+ for trackerToBeFoundStr in ListToBeFound do
+ begin
+ IndexFound := SearchInlist.IndexOf(trackerToBeFoundStr);
+
+ //It is found or not?
+ if IndexFound < 0 then
+ begin
+ //not found, maybe it is in the TrackerRemoved?
+ if TrackerRemoved.IndexOf(trackerToBeFoundStr) < 0 then
+ begin
+ //not found in TrackerRemoved. This is an error.
+ TrackerFoundInList := tf_NotFound;
+ exit;
+ end;
+ //data is found in TrackerRemoved
+ //do the next item in the loop
+ //nothing to do when there is no data is found
+ end
+ else
+ begin
+ //new data is found
+
+ //data is found so increase ItemsFound
+ Inc(ItemsFound);
+
+ //keep updating LastIndex where data is found
+ LastIndex := IndexFound;
+
+ //update first index only one time in this for loop.
+ if FirstIndex < 0 then
+ begin
+ FirstIndex := IndexFound;
+
+ //Start with tf_Increamental. Will be change to tf_Skip if needed.
+ TrackerFoundInList := tf_Increamental;
+ end
+ else
+ begin
+ //comprare if this is one step index increase with one items or more.
+ if (IndexFound = OldIndex + 1) then
+ begin
+ //Must not be able to go from tf_Skip -> tf_Increamental
+ if TrackerFoundInList <> tf_Skip then
+ TrackerFoundInList := tf_Increamental;
+ end
+ else
+ TrackerFoundInList := tf_Skip;
+ end;
+
+ //keep updating the previeus index
+ OldIndex := IndexFound;
+ end;
+
+ end;//for loop
+
+end;
+
+procedure RemoveLineSeperation(TrackerList: TStringList);
+var
+ i: integer;
+begin
+ if TrackerList.Count = 0 then
+ exit;
+
+ //remove all the empty lines
+ for i := TrackerList.Count - 1 downto 0 do
+ begin
+ if Trim(TrackerList[i]) = '' then
+ TrackerList.Delete(i);
+ end;
+end;
+
+procedure CreateCopyTVerifyTrackerResult(
+ const VerifyTrackerResult_Original: TVerifyTrackerResult;
+ out VerifyTrackerResult_copy: TVerifyTrackerResult);
+begin
+ //create working copy
+ VerifyTrackerResult_copy.TrackerAdded := TStringList.Create;
+ VerifyTrackerResult_copy.TrackerEndResult := TStringList.Create;
+ VerifyTrackerResult_copy.TrackerOriginal := TStringList.Create;
+ VerifyTrackerResult_copy.TrackerRemoved := TStringList.Create;
+
+ //copy original to copyed version
+ VerifyTrackerResult_copy.TrackerAdded.Assign(
+ VerifyTrackerResult_Original.TrackerAdded);
+ VerifyTrackerResult_copy.TrackerEndResult.Assign(
+ VerifyTrackerResult_Original.TrackerEndResult);
+ VerifyTrackerResult_copy.TrackerOriginal.Assign(
+ VerifyTrackerResult_Original.TrackerOriginal);
+ VerifyTrackerResult_copy.TrackerRemoved.Assign(
+ VerifyTrackerResult_Original.TrackerRemoved);
+
+ //remove empty lines
+ RemoveLineSeperation(VerifyTrackerResult_copy.TrackerAdded);
+ RemoveLineSeperation(VerifyTrackerResult_copy.TrackerEndResult);
+ RemoveLineSeperation(VerifyTrackerResult_copy.TrackerOriginal);
+ RemoveLineSeperation(VerifyTrackerResult_copy.TrackerRemoved);
+end;
+
+procedure FreeTVerifyTrackerResult(var VerifyTrackerResult: TVerifyTrackerResult);
+begin
+ VerifyTrackerResult.TrackerAdded.Free;
+ VerifyTrackerResult.TrackerEndResult.Free;
+ VerifyTrackerResult.TrackerOriginal.Free;
+ VerifyTrackerResult.TrackerRemoved.Free;
+end;
+
+function CheckIfEverythingIsCompleat(var VerifyTracker: TVerifyTrackerResult): boolean;
+var
+ FirstIndex, LastIndex, ItemsFound: integer;
+ TrackerFoundInList: TTrackerFoundInList;
+ VerifyTrackerResult_copy: TVerifyTrackerResult;
+
+ procedure ListToBeFound(list: TStringList);
+ begin
+ FindTrackerList(list,
+ VerifyTrackerResult_copy.TrackerEndResult,
+ VerifyTrackerResult_copy.TrackerRemoved, FirstIndex, LastIndex,
+ ItemsFound, TrackerFoundInList);
+ end;
+
+begin
+ //This is for 'sort' and 'random' list URL order.
+ //Only need to check if nothing is missing
+
+ CreateCopyTVerifyTrackerResult(VerifyTracker, VerifyTrackerResult_copy);
+
+ try
+ //check if TrackerAdded is present in the end result
+ ListToBeFound(VerifyTrackerResult_copy.TrackerAdded);
+ if TrackerFoundInList = tf_NotFound then
+ begin
+ Result := False;
+ VerifyTracker.ErrorString := 'Error: TrackerAdded trackers are missing';
+ exit;
+ end;
+
+ //check if TrackerOriginal is present in the end result
+ ListToBeFound(VerifyTrackerResult_copy.TrackerOriginal);
+ if TrackerFoundInList = tf_NotFound then
+ begin
+ Result := False;
+ VerifyTracker.ErrorString := 'Error: TrackerAdded trackers are missing';
+ exit;
+ end;
+
+ //no error found;
+ Result := True;
+
+ finally
+ //free all the memory
+ FreeTVerifyTrackerResult(VerifyTrackerResult_copy);
+ end;
+
+end;
+
+function CheckIfStillIntack(var VerifyTracker: TVerifyTrackerResult;
+ atBegin_TrackerAdded, MustBeIntact_TrackerAdded: boolean): boolean;
+var
+ FirstIndex, LastIndex, ItemsFound: integer;
+ TrackerFoundInList: TTrackerFoundInList;
+ VerifyTrackerResult_copy: TVerifyTrackerResult;
+
+ procedure ListToBeFound(list: TStringList);
+ begin
+ FindTrackerList(list,
+ VerifyTrackerResult_copy.TrackerEndResult,
+ VerifyTrackerResult_copy.TrackerRemoved, FirstIndex, LastIndex,
+ ItemsFound, TrackerFoundInList);
+ end;
+
+begin
+ //the TrackerAdded can be place 'at the begin' or 'at the end' of the end result list.
+ //the TrackerAdded can be intack or not, if not intact then it must also present some where in the TrackerEndResult
+ // except when it is present in the TrackerRemoved
+
+ CreateCopyTVerifyTrackerResult(VerifyTracker, VerifyTrackerResult_copy);
+
+ try
+ //Must find 'the added' and 'the original' in the endresult
+
+ if atBegin_TrackerAdded then
+ begin
+
+ if MustBeIntact_TrackerAdded then
+ begin
+ //check for TrackerAdded, should be place at begin
+ ListToBeFound(VerifyTrackerResult_copy.TrackerAdded);
+ Result := FirstIndex = 0;
+ if not Result then
+ begin
+ VerifyTracker.ErrorString := 'Error: TrackerAdded should be place at begin';
+ exit;
+ end;
+ end
+ else
+ begin
+ //Problem here. if NOT intact then all the URL can be place every where.
+ //There is no check if this is correct or not
+
+ //The only valid check will be done later if the original tracker is place at the correct place.
+ ListToBeFound(VerifyTrackerResult_copy.TrackerAdded);
+
+ //do nothing here
+ end;
+
+ if TrackerFoundInList = tf_NotFound then
+ begin
+ Result := False;
+ VerifyTracker.ErrorString := 'Error: TrackerAdded trackers are missing';
+ exit;
+ end;
+
+ if MustBeIntact_TrackerAdded then
+ begin
+ Result := TrackerFoundInList = tf_Increamental;
+ if not Result then
+ begin
+ VerifyTracker.ErrorString := 'Error: TrackerAdded trackers are not intact';
+ exit;
+ end;
+ end;
+
+
+ //check for TrackerOriginal, should be place at end
+ ListToBeFound(VerifyTrackerResult_copy.TrackerOriginal);
+ Result := LastIndex = VerifyTrackerResult_copy.TrackerEndResult.Count - 1;
+ if not Result then
+ begin
+ VerifyTracker.ErrorString := 'Error: TrackerOriginal should be place at end';
+ exit;
+ end;
+
+ if TrackerFoundInList = tf_NotFound then
+ begin
+ Result := False;
+ VerifyTracker.ErrorString := 'Error: TrackerOriginal trackers are missing';
+ exit;
+ end;
+
+ end
+ else
+ begin
+ //place at end
+ //check for TrackerOriginal, should be place at begin
+ ListToBeFound(VerifyTrackerResult_copy.TrackerOriginal);
+ Result := FirstIndex = 0;
+ if not Result then
+ begin
+ VerifyTracker.ErrorString := 'Error: TrackerOriginal should be place at begin';
+ exit;
+ end;
+
+ if TrackerFoundInList = tf_NotFound then
+ begin
+ Result := False;
+ VerifyTracker.ErrorString := 'Error: TrackerOriginal trackers are missing';
+ exit;
+ end;
+
+ //check for TrackerAdded, should be place at end
+ ListToBeFound(VerifyTrackerResult_copy.TrackerAdded);
+ Result := LastIndex = VerifyTrackerResult_copy.TrackerEndResult.Count - 1;
+ if not Result then
+ begin
+ VerifyTracker.ErrorString := 'Error: TrackerAdded should be place at end';
+ exit;
+ end;
+
+ if MustBeIntact_TrackerAdded then
+ begin
+ Result := TrackerFoundInList = tf_Increamental;
+ if not Result then
+ begin
+ VerifyTracker.ErrorString := 'Error: TrackerAdded trackers are not intact';
+ exit;
+ end;
+ end;
+
+ if TrackerFoundInList = tf_NotFound then
+ begin
+ Result := False;
+ VerifyTracker.ErrorString := 'Error: TrackerAdded trackers are missing';
+ exit;
+ end;
+
+ end;
+
+
+ finally
+ //free all the memory
+ FreeTVerifyTrackerResult(VerifyTrackerResult_copy);
+ end;
+
+end;
+
+function CheckValidURL_EndResult(var VerifyTracker: TVerifyTrackerResult): boolean;
+var
+ tracker_URL: string;
+
+ function IsValid(const str: string): boolean;
+ var
+ i: integer;
+ begin
+ for i := low(VALID_TRACKERS_URL) to high(VALID_TRACKERS_URL) do
+ begin
+ //compare the string
+ if (Pos(VALID_TRACKERS_URL[i], str) = 1) then
+ begin
+ //found correct URL
+ Result := True;
+ exit;
+ end;
+ end;
+ VerifyTracker.ErrorString := 'Can not validate URL: ' + str;
+ Result := False;
+ end;
+
+begin
+ for tracker_URL in VerifyTracker.TrackerEndResult do
+ begin
+ //skip empty line
+ if tracker_URL = '' then
+ Continue;
+
+ if not IsValid(tracker_URL) then
+ begin
+ Result := False;
+ exit;
+ end;
+ end;
+ Result := True;
+end;
+
+function CheckIfRemoveIsNotPresent(var VerifyTracker: TVerifyTrackerResult): boolean;
+var
+ tracker_URL: string;
+begin
+ //scan the TrackerEndResult for trackers present in TrackerRemoved
+ for tracker_URL in VerifyTracker.TrackerRemoved do
+ begin
+ //it should not be present in TrackerEndResult
+ if VerifyTracker.TrackerEndResult.IndexOf(tracker_URL) >= 0 then
+ begin
+ Result := False;
+ VerifyTracker.ErrorString :=
+ 'This tracker URL should not be present: ' + tracker_URL;
+ end;
+ end;
+ Result := True;
+end;
+
+function VerifyTrackerResult(var VerifyTracker: TVerifyTrackerResult): boolean;
+var
+ atBegin_TrackerAdded, MustBeIntact_TrackerAdded: boolean;
+begin
+
+ //Check if URL is valid
+ Result := CheckValidURL_EndResult(VerifyTracker);
+ if not Result then
+ begin
+ exit;
+ end;
+
+ //There should not be any removed trackers items.
+ Result := CheckIfRemoveIsNotPresent(VerifyTracker);
+ if not Result then
+ begin
+ exit;
+ end;
+
+ //Must verify if the output is what we expected
+ case VerifyTracker.StartupParameter.TrackerListOrder of
+ // Console parameter: -U0
+ // Insert new trackers list BEFORE, the original trackers list inside the torrent file.
+ // And remove possible duplicated trackers from the ORIGINAL trackers list.
+ tloInsertNewBeforeAndKeepNewIntact:
+ begin
+ atBegin_TrackerAdded := True;
+ MustBeIntact_TrackerAdded := True;
+ Result := CheckIfStillIntack(VerifyTracker, atBegin_TrackerAdded,
+ MustBeIntact_TrackerAdded);
+
+ end;
+
+ // Console parameter: -U1
+ // Insert new trackers list BEFORE, the original trackers list inside the torrent file.
+ // And remove possible duplicated trackers from the NEW trackers list.
+ tloInsertNewBeforeAndKeepOriginalIntact:
+ begin
+ atBegin_TrackerAdded := True;
+ MustBeIntact_TrackerAdded := False;
+ Result := CheckIfStillIntack(VerifyTracker, atBegin_TrackerAdded,
+ MustBeIntact_TrackerAdded);
+
+ end;
+
+ // Console parameter: -U2
+ // Append new trackers list AFTER, the original trackers list inside the torrent file.
+ // And remove possible duplicated trackers from the ORIGINAL trackers list.
+ tloAppendNewAfterAndKeepNewIntact:
+ begin
+ atBegin_TrackerAdded := False;
+ MustBeIntact_TrackerAdded := True;
+ Result := CheckIfStillIntack(VerifyTracker, atBegin_TrackerAdded,
+ MustBeIntact_TrackerAdded);
+
+ end;
+
+ // Console parameter: -U3
+ // Append new trackers list AFTER, the original trackers list inside the torrent file.
+ // And remove possible duplicated trackers from the NEW trackers list.
+ tloAppendNewAfterAndKeepOriginalIntact:
+ begin
+ atBegin_TrackerAdded := False;
+ MustBeIntact_TrackerAdded := False;
+ Result := CheckIfStillIntack(VerifyTracker, atBegin_TrackerAdded,
+ MustBeIntact_TrackerAdded);
+
+ end;
+
+ // Console parameter: -U4
+ // Sort the trackers list by name.
+ tloSort:
+ begin
+ //Must check if all trackers are still present.
+ Result := CheckIfEverythingIsCompleat(VerifyTracker);
+ end;
+
+ // Console parameter: -U5
+ // Append new trackers list BEFORE, the original trackers list inside the torrent file.
+ // Keep original tracker list 'of each individual torrent' unchanged and remove nothing.
+ // Every torent may have diferent tracker list!
+ tloInsertNewBeforeAndKeepOriginalIntactAndRemoveNothing:
+ begin
+ atBegin_TrackerAdded := True;
+ MustBeIntact_TrackerAdded := False;
+ Result := CheckIfStillIntack(VerifyTracker, atBegin_TrackerAdded,
+ MustBeIntact_TrackerAdded);
+ end;
+
+ // Console parameter: -U6
+ // Append new trackers list AFTER, the original trackers list inside the torrent file.
+ // Keep original tracker list 'of each individual torrent' unchanged and remove nothing.
+ // Every torent may have diferent tracker list!
+ tloAppendNewAfterAndKeepOriginalIntactAndRemoveNothing:
+ begin
+ atBegin_TrackerAdded := False;
+ MustBeIntact_TrackerAdded := False;
+ Result := CheckIfStillIntack(VerifyTracker, atBegin_TrackerAdded,
+ MustBeIntact_TrackerAdded);
+ end;
+
+ // Console parameter: -U7
+ // Randomize the trackers list.
+ tloRandomize:
+ begin
+ //Must check if all trackers are still present.
+ Result := CheckIfEverythingIsCompleat(VerifyTracker);
+ end;
+ else
+ begin
+ Assert(False, 'ELSE: VerifyTrackerResult()');
+ end;
+
+ end;
+end;
+
+function LoadConsoleLog(const FileNameWithPath: string; out StatusOK: boolean;
+ out TorrentFilesCount: integer; out TrackersCount: integer): boolean;
+var
+ ConsoleStringlist: TStringList;
+begin
+{
+ console_log.txt is only created in console mode.
+ Show the in console mode the success/failure of the torrent update.
+ First line status: 'OK' or 'ERROR: xxxxxxx' xxxxxxx = error description
+ Second line files count: '1'
+ Third line tracker count: 23
+ Second and third line info are only valid if the first line is 'OK'
+}
+
+ //Result = true if file can be readed as expected.
+ // with 2 lines of values if first line is 'OK'
+
+ ConsoleStringlist := TStringList.Create;
+ try
+ ConsoleStringlist.LoadFromFile(FileNameWithPath);
+
+ Result := ConsoleStringlist.Count > 0;
+ if Result then
+ begin
+ StatusOK := ConsoleStringlist[0] = CONSOLE_SUCCESS_STATUS;
+ end;
+
+ if StatusOK then
+ begin
+ //The totall lines in the file must be 3
+ Result := ConsoleStringlist.Count >= 3;
+ if Result then
+ begin
+ Result := TryStrToInt(ConsoleStringlist[1], TorrentFilesCount);
+ end;
+
+ //read only if the TorrentFilesCount is successful
+ if Result then
+ begin
+ Result := TryStrToInt(ConsoleStringlist[2], TrackersCount);
+ end;
+ end;
+
+ except
+ Result := False;
+ end;
+
+ ConsoleStringlist.Free;
+end;
+
+end.
diff --git a/source/test/test_newtrackon.pas b/source/test/test_newtrackon.pas
new file mode 100644
index 0000000..ab9bb21
--- /dev/null
+++ b/source/test/test_newtrackon.pas
@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: MIT
+unit test_newtrackon;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils, fpcunit, testregistry, newtrackon; //testutils
+
+type
+
+ { TTestNewTrackon }
+
+ TTestNewTrackon = class(TTestCase)
+ private
+ FNewTrackon: TNewTrackon;
+ protected
+ procedure SetUp; override;
+ procedure TearDown; override;
+ published
+ procedure Test_API_Download;
+ procedure Test_API_Upload;
+ end;
+
+implementation
+
+procedure TTestNewTrackon.Test_API_Download;
+begin
+ Check(FNewTrackon.DownloadEverything, 'Download the newtrackon API');
+
+ Check(FNewTrackon.TrackerList_All.Count > 0,
+ 'TrackerList_All should never be empty');
+
+ Check(FNewTrackon.TrackerList_Live.Count > 0,
+ 'TrackerList_Live should never be empty');
+
+ Check(FNewTrackon.TrackerList_Stable.Count > 0,
+ 'TrackerList_Stable should never be empty');
+
+ Check(FNewTrackon.TrackerList_Udp.Count > 0,
+ 'TrackerList_Udp should never be empty');
+
+ Check(FNewTrackon.TrackerList_Http.Count > 0,
+ 'TrackerList_Http should never be empty');
+
+ Check(FNewTrackon.TrackerList_Dead.Count > 0,
+ 'TrackerList_Dead should never be empty');
+end;
+
+procedure TTestNewTrackon.Test_API_Upload;
+var
+ TrackerList: TStringList;
+ TrackersSendCount: integer;
+begin
+ TrackerList := TStringList.Create;
+
+ //Add two trackers
+ TrackerList.Add('udp://tracker.leechers-paradise.org:6969/announce');
+ TrackerList.Add('udp://tracker.test.org:6969/announce');//dummy URL
+ TrackerList.Add('wss://tracker.openwebtorrent.com');
+
+ //Test if upload is OK
+ try
+ Check(FNewTrackon.SubmitTrackers(TrackerList, TrackersSendCount),
+ 'Upload the newtrackon API');
+ Check(TrackersSendCount <= TrackerList.Count, 'TrackersSendCount have too high value');
+ finally
+ TrackerList.Free;
+ end;
+
+end;
+
+procedure TTestNewTrackon.SetUp;
+begin
+ WriteLn('TTestNewTrackon.SetUp');
+ FNewTrackon := TNewTrackon.Create;
+end;
+
+procedure TTestNewTrackon.TearDown;
+begin
+ WriteLn('TTestNewTrackon.TearDown');
+ FNewTrackon.Free;
+end;
+
+initialization
+
+ RegisterTest(TTestNewTrackon);
+end.
diff --git a/source/test/test_ngosang_trackers_list.pas b/source/test/test_ngosang_trackers_list.pas
new file mode 100644
index 0000000..13d694e
--- /dev/null
+++ b/source/test/test_ngosang_trackers_list.pas
@@ -0,0 +1,77 @@
+// SPDX-License-Identifier: MIT
+unit test_ngosang_trackers_list;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils, fpcunit, testregistry, ngosang_trackerslist; //testutils,
+
+type
+
+ TTestNgosangTrackersList = class(TTestCase)
+ private
+ FngosangTrackerList: TngosangTrackerList;
+ protected
+ procedure SetUp; override;
+ procedure TearDown; override;
+ published
+ procedure Test_DownloadAPI;
+ end;
+
+implementation
+
+procedure TTestNgosangTrackersList.Test_DownloadAPI;
+begin
+ Check(FngosangTrackerList.TrackerList_Blacklist.Count > 0,
+ 'TrackerList_Blacklist should never be empty');
+
+ Check(FngosangTrackerList.TrackerList_All.Count > 0,
+ 'TrackerList_All should never be empty');
+
+ Check(FngosangTrackerList.TrackerList_All_HTTP.Count > 0,
+ 'TrackerList_All_HTTP should never be empty');
+
+{ //HTTPS is not popular. it may be empty
+ Check(
+ FngosangTrackerList.TrackerList_All_HTTPS.Count > 0,
+ 'TrackerList_All_HTTPS should never be empty');
+}
+ Check(
+ FngosangTrackerList.TrackerList_All_IP.Count > 0,
+ 'TrackerList_All_IP should never be empty');
+
+ Check(
+ FngosangTrackerList.TrackerList_All_UDP.Count > 0,
+ 'TrackerList_All_UDP should never be empty');
+
+ Check(
+ FngosangTrackerList.TrackerList_All_WS.Count > 0,
+ 'TrackerList_All_WS should never be empty');
+
+ Check(
+ FngosangTrackerList.TrackerList_Best.Count > 0,
+ 'TrackerList_Best should never be empty');
+
+ Check(
+ FngosangTrackerList.TrackerList_Best_IP.Count > 0,
+ 'TrackerList_Best_IP should never be empty');
+end;
+
+procedure TTestNgosangTrackersList.SetUp;
+begin
+ WriteLn('TTestNgosangTrackersList.SetUp');
+ FngosangTrackerList := TngosangTrackerList.Create;
+end;
+
+procedure TTestNgosangTrackersList.TearDown;
+begin
+ WriteLn('TTestNgosangTrackersList.TearDown');
+ FngosangTrackerList.Free;
+end;
+
+initialization
+
+ RegisterTest(TTestNgosangTrackersList);
+end.
diff --git a/source/test/test_start_up_parameter.pas b/source/test/test_start_up_parameter.pas
new file mode 100644
index 0000000..60f2807
--- /dev/null
+++ b/source/test/test_start_up_parameter.pas
@@ -0,0 +1,616 @@
+// SPDX-License-Identifier: MIT
+unit test_start_up_parameter;
+
+{
+ Tracker Editor can be started via parameter.
+ The working of these parameter must be tested.
+
+ ------------------------------------
+ There are 4 txt files that are being used for this test
+ All these files are place in the same folder as the executable files
+
+ List of all the trackers that must added.
+ add_trackers.txt
+
+ remove_trackers.txt
+ List of all the trackers that must removed
+ note: if the file is empty then all trackers from the present torrent will be REMOVED.
+ note: if the file is not present then no trackers will be automatic removed.
+
+ Check if the program is working as expected:
+ log.txt is only created in console mode.
+ Show the in console mode the success/failure of the torrent update.
+ First line status: 'OK' or 'ERROR: xxxxxxx' xxxxxxx = error description
+ Second line files count: '1'
+ Third line tracker count: 23
+ Second and third line info are only valid if the first line is 'OK'
+
+ Check what the torrent output is:
+ export_trackers.txt
+
+}
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils, fpcunit, testregistry, newtrackon, torrent_miscellaneous,
+ test_miscellaneous;
+
+type
+ TConsoleLogData = record
+ StatusOK: boolean;
+ TorrentFilesCount: integer;
+ TrackersCount: integer;
+ end;
+
+ { TTestStartUpParameter }
+
+ TTestStartUpParameter = class(TTestCase)
+ private
+ FFullPathToRoot: string;
+ FFullPathToTorrent: string;
+ FFullPathToEndUser: string;
+ FFullPathToBinary: string;
+
+ FTorrentFilesNameStringList: TStringList;
+ FNewTrackon: TNewTrackon;
+ FVerifyTrackerResult: TVerifyTrackerResult;
+ FExitCode: integer;
+ FCommandLine: string;
+ FConsoleLogData: TConsoleLogData;
+
+ function ReadConsoleLogFile: boolean;
+ procedure TestParameter(const StartupParameter: TStartupParameter);
+ procedure DownloadPreTestTrackerList;
+ procedure LoadTrackerListAddAndRemoved;
+ procedure CallExecutableFile;
+ procedure CopyTrackerEndResultToVerifyTrackerResult;
+ procedure CreateEmptyTorrent(const StartupParameter: TStartupParameter);
+ procedure TestEmptyTorrentResult;
+ procedure CreateFilledTorrent(const StartupParameter: TStartupParameter);
+ procedure DownloadNewTrackonTrackers;
+ procedure Test_Paramater_Ux(TrackerListOrder: TTrackerListOrder);
+ procedure Add_One_URL(const StartupParameter: TStartupParameter;
+ const tracker_URL: string; TestMustBeSuccess: boolean);
+
+ protected
+ procedure SetUp; override;
+ procedure TearDown; override;
+ published
+ procedure Test_Parameter_TEST_SSL;
+ procedure Test_Tracker_UserInput_All_Different_URL;
+ procedure Test_Tracker_UserInput_All_Different_URL_And_SAC;
+ procedure Test_Create_Empty_Torrent_And_Then_Filled_It_All_List_Order_Mode;
+
+ procedure Test_Paramater_U0;
+ procedure Test_Paramater_U1;
+ procedure Test_Paramater_U2;
+ procedure Test_Paramater_U3;
+ procedure Test_Paramater_U4;
+ procedure Test_Paramater_U5_TODO;
+ procedure Test_Paramater_U6_TODO;
+ procedure Test_Paramater_U7;
+
+ end;
+
+implementation
+
+uses LazUTF8;
+
+const
+ PROGRAME_TO_BE_TESTED_NAME = 'trackereditor';
+ TORRENT_FOLDER = 'test_torrent';
+ END_USER_FOLDER = 'enduser';
+
+ //there are 3 test torrent files in 'test_torrent' folder.
+ TEST_TORRENT_FILES_COUNT = 3;
+
+procedure TTestStartUpParameter.Test_Paramater_U0;
+begin
+ Test_Paramater_Ux(tloInsertNewBeforeAndKeepNewIntact);
+end;
+
+procedure TTestStartUpParameter.Test_Paramater_U1;
+begin
+ Test_Paramater_Ux(tloInsertNewBeforeAndKeepOriginalIntact);
+end;
+
+procedure TTestStartUpParameter.Test_Paramater_U2;
+begin
+ Test_Paramater_Ux(tloAppendNewAfterAndKeepNewIntact);
+end;
+
+procedure TTestStartUpParameter.Test_Paramater_U3;
+begin
+ Test_Paramater_Ux(tloAppendNewAfterAndKeepOriginalIntact);
+end;
+
+procedure TTestStartUpParameter.Test_Paramater_U4;
+begin
+ Test_Paramater_Ux(tloSort);
+end;
+
+procedure TTestStartUpParameter.Test_Paramater_U5_TODO;
+begin
+ //TODO: Must check every torrent file one by one
+ //Test_Paramater_Ux(tloInsertNewBeforeAndKeepOriginalIntactAndRemoveNothing);
+end;
+
+procedure TTestStartUpParameter.Test_Paramater_U6_TODO;
+begin
+ //TODO: Must check every torrent file one by one
+ //Test_Paramater_Ux(tloAppendNewAfterAndKeepOriginalIntactAndRemoveNothing);
+end;
+
+procedure TTestStartUpParameter.Test_Paramater_U7;
+begin
+ Test_Paramater_Ux(tloRandomize);
+end;
+
+procedure TTestStartUpParameter.Test_Parameter_TEST_SSL;
+begin
+ // Check if SSL connection is working.
+ FCommandLine := '-TEST_SSL';
+ CallExecutableFile;
+ // Exit code should be zero
+ CheckEquals(0, FExitCode);
+end;
+
+//procedure TTestStartUpParameter.TestParameter(TrackerListOrder: TTrackerListOrder);
+procedure TTestStartUpParameter.TestParameter(const StartupParameter: TStartupParameter);
+begin
+ FVerifyTrackerResult.StartupParameter := StartupParameter;
+
+ //Fill in the command line parameter '-Ux', x = number
+ FCommandLine := format('%s -U%d', [FFullPathToTorrent,
+ Ord(StartupParameter.TrackerListOrder)]);
+
+ if StartupParameter.SkipAnnounceCheck then
+ begin
+ FCommandLine := FCommandLine + ' -SAC';
+ end;
+
+ if StartupParameter.SourcePresent then
+ begin
+ FCommandLine := FCommandLine + ' -SOURCE ' + StartupParameter.SourceText;
+ end;
+end;
+
+procedure TTestStartUpParameter.DownloadPreTestTrackerList;
+begin
+ DownloadNewTrackonTrackers;
+
+ //copy all the download to txt file.
+
+ //TrackerList_All have all the trackers available
+ FNewTrackon.TrackerList_All.SaveToFile(FFullPathToEndUser + FILE_NAME_ADD_TRACKERS);
+
+ //TrackerList_Dead must remove the dead one.
+ FNewTrackon.TrackerList_Dead.SaveToFile(FFullPathToEndUser +
+ FILE_NAME_REMOVE_TRACKERS);
+
+end;
+
+procedure TTestStartUpParameter.LoadTrackerListAddAndRemoved;
+begin
+ FVerifyTrackerResult.TrackerAdded.LoadFromFile(FFullPathToEndUser +
+ FILE_NAME_ADD_TRACKERS);
+
+ FVerifyTrackerResult.TrackerRemoved.LoadFromFile(FFullPathToEndUser +
+ FILE_NAME_REMOVE_TRACKERS);
+end;
+
+procedure TTestStartUpParameter.CallExecutableFile;
+begin
+ //start the. This will return the Exit code
+ FExitCode := SysUtils.ExecuteProcess(UTF8ToSys(FFullPathToBinary), FCommandLine, []);
+end;
+
+procedure TTestStartUpParameter.CopyTrackerEndResultToVerifyTrackerResult;
+begin
+ FVerifyTrackerResult.TrackerEndResult.LoadFromFile(FFullPathToEndUser +
+ FILE_NAME_EXPORT_TRACKERS);
+
+ //remove empty space
+ RemoveLineSeperation(FVerifyTrackerResult.TrackerEndResult);
+
+end;
+
+procedure TTestStartUpParameter.CreateEmptyTorrent(
+ const StartupParameter: TStartupParameter);
+begin
+ //write a empty remove trackers
+ FVerifyTrackerResult.TrackerRemoved.Clear;
+ FVerifyTrackerResult.TrackerRemoved.SaveToFile(FFullPathToEndUser +
+ FILE_NAME_REMOVE_TRACKERS);
+
+ //write a empty add trackers
+ FVerifyTrackerResult.TrackerAdded.Clear;
+ FVerifyTrackerResult.TrackerAdded.SaveToFile(FFullPathToEndUser +
+ FILE_NAME_ADD_TRACKERS);
+
+ //Generate the command line parameter
+ TestParameter(StartupParameter);
+
+ //call the tracker editor exe file
+ CallExecutableFile;
+end;
+
+procedure TTestStartUpParameter.TestEmptyTorrentResult;
+begin
+ //Copy test result into FVerifyTrackerResult
+ CopyTrackerEndResultToVerifyTrackerResult;
+
+ Check(FVerifyTrackerResult.TrackerEndResult.Count = 0,
+ 'The tracker list should be empty.');
+end;
+
+procedure TTestStartUpParameter.CreateFilledTorrent(
+ const StartupParameter: TStartupParameter);
+begin
+ DownloadNewTrackonTrackers;
+
+ //write a empty remove trackers
+ FVerifyTrackerResult.TrackerRemoved.Clear;
+ FVerifyTrackerResult.TrackerRemoved.SaveToFile(FFullPathToEndUser +
+ FILE_NAME_REMOVE_TRACKERS);
+
+ //write a some trackers to add. This
+ FVerifyTrackerResult.TrackerAdded.Clear;
+ FVerifyTrackerResult.TrackerAdded.Add('udp://1.test/announce');
+
+ //Add one torrent that later will be removed
+ if FNewTrackon.TrackerList_Dead.Count > 0 then
+ begin
+ FVerifyTrackerResult.TrackerAdded.Add(FNewTrackon.TrackerList_Dead[0]);
+ end;
+
+ //Add one torrent that that must may be removed
+ if FNewTrackon.TrackerList_Live.Count > 0 then
+ begin
+ FVerifyTrackerResult.TrackerAdded.Add(FNewTrackon.TrackerList_Live[0]);
+ end;
+
+ FVerifyTrackerResult.TrackerAdded.Add('udp://2.test/announce');
+ FVerifyTrackerResult.TrackerAdded.SaveToFile(FFullPathToEndUser +
+ FILE_NAME_ADD_TRACKERS);
+
+ //Generate the command line parameter
+ TestParameter(StartupParameter);
+
+ //call the tracker editor exe file
+ CallExecutableFile;
+
+ //Copy test result into FVerifyTrackerResult
+ CopyTrackerEndResultToVerifyTrackerResult;
+
+ Check(FVerifyTrackerResult.TrackerEndResult.Count =
+ FVerifyTrackerResult.TrackerAdded.Count,
+ 'TrackerEndResult should have the same count as TrackerAdded');
+
+ //For the next test load the present content inside the torrent
+ FVerifyTrackerResult.TrackerOriginal.Assign(FVerifyTrackerResult.TrackerAdded);
+
+end;
+
+procedure TTestStartUpParameter.DownloadNewTrackonTrackers;
+begin
+ //download only one time
+ if FNewTrackon.TrackerList_All.Count = 0 then
+ begin
+ Check(FNewTrackon.DownloadEverything, 'Download Newtrackon failed');
+ end;
+end;
+
+procedure TTestStartUpParameter.Test_Paramater_Ux(TrackerListOrder: TTrackerListOrder);
+
+var
+ OK: boolean;
+ StartupParameter: TStartupParameter;
+begin
+ //Create a torrent with fix torrent items
+ //this is the pre test condition
+ StartupParameter.TrackerListOrder := tloInsertNewBeforeAndKeepNewIntact;
+ StartupParameter.SkipAnnounceCheck := False;
+ StartupParameter.SourcePresent := False;
+ CreateFilledTorrent(StartupParameter);
+
+ //Download all the trackers .txt files
+ DownloadPreTestTrackerList;
+
+ //load all the txt file into memory
+ LoadTrackerListAddAndRemoved;
+
+ //Generate the command line parameter
+ StartupParameter.TrackerListOrder := TrackerListOrder;
+ TestParameter(StartupParameter);
+
+ //call the tracker editor exe file
+ CallExecutableFile;
+
+ //Copy test result into FVerifyTrackerResult
+ CopyTrackerEndResultToVerifyTrackerResult;
+
+ //check if the test result is correct
+ OK := VerifyTrackerResult(FVerifyTrackerResult);
+ Check(OK, FVerifyTrackerResult.ErrorString);
+
+ //check the exit code
+ CheckEquals(0, FExitCode);
+
+ //Check the logdata status
+ Check(ReadConsoleLogFile, 'Log data is not present');
+ Check(FConsoleLogData.StatusOK);
+ Check(FConsoleLogData.TrackersCount > 0);
+ Check(FConsoleLogData.TorrentFilesCount = TEST_TORRENT_FILES_COUNT);
+end;
+
+procedure TTestStartUpParameter.Add_One_URL(const StartupParameter: TStartupParameter;
+ const tracker_URL: string; TestMustBeSuccess: boolean);
+begin
+ //add one tracker to the 'add_trackers'
+ FVerifyTrackerResult.TrackerAdded.Clear;
+ FVerifyTrackerResult.TrackerAdded.Add(tracker_URL);
+
+ FVerifyTrackerResult.TrackerAdded.SaveToFile(FFullPathToEndUser +
+ FILE_NAME_ADD_TRACKERS);
+
+ //Generate the command line parameter
+ TestParameter(StartupParameter);
+
+ //call the tracker editor exe file
+ CallExecutableFile;
+
+ //Check the logdata status
+ Check(ReadConsoleLogFile, 'Log data is not present');
+
+
+ if TestMustBeSuccess then
+ begin
+ //check the exit code. Must be OK
+ CheckEquals(0, FExitCode, tracker_URL);
+
+ //the result must be True
+ CheckTrue(FConsoleLogData.StatusOK, tracker_URL);
+ end
+ else
+ begin
+ //check the exit code. Must be an error
+ CheckNotEquals(0, FExitCode, tracker_URL);
+
+ //the result must be false
+ CheckFalse(FConsoleLogData.StatusOK, tracker_URL);
+ end;
+
+end;
+
+
+procedure TTestStartUpParameter.Test_Tracker_UserInput_All_Different_URL;
+var
+ TrackerListOrder: TTrackerListOrder;
+ TrackerURL: string;
+ StartupParameter: TStartupParameter;
+const
+ ANNOUNCE = '/announce';
+ ANNOUNCE_PHP = '/announce.php';
+begin
+ StartupParameter.SkipAnnounceCheck := False;
+ StartupParameter.SourcePresent := False;
+
+ //Test if all the tracker update mode is working
+ for TrackerListOrder in TTrackerListOrder do
+ begin
+ StartupParameter.TrackerListOrder := TrackerListOrder;
+
+ TrackerURL := 'udp://test.com';
+ Add_One_URL(StartupParameter, TrackerURL, False);
+ Add_One_URL(StartupParameter, TrackerURL + ANNOUNCE, True);
+ Add_One_URL(StartupParameter, TrackerURL + ANNOUNCE_PHP, True);
+
+ TrackerURL := 'http://test.com';
+ Add_One_URL(StartupParameter, TrackerURL, False);
+ Add_One_URL(StartupParameter, TrackerURL + ANNOUNCE, True);
+ Add_One_URL(StartupParameter, TrackerURL + ANNOUNCE_PHP, True);
+
+ TrackerURL := 'https://test.com';
+ Add_One_URL(StartupParameter, TrackerURL, False);
+ Add_One_URL(StartupParameter, TrackerURL + ANNOUNCE, True);
+ Add_One_URL(StartupParameter, TrackerURL + ANNOUNCE_PHP, True);
+
+ //webtorrent may have NOT announce
+ TrackerURL := 'ws://test.com';
+ Add_One_URL(StartupParameter, TrackerURL, True);
+ Add_One_URL(StartupParameter, TrackerURL + ANNOUNCE, True);
+
+ TrackerURL := 'wss://test.com';
+ Add_One_URL(StartupParameter, TrackerURL, True);
+ Add_One_URL(StartupParameter, TrackerURL + ANNOUNCE, True);
+ end;
+end;
+
+procedure TTestStartUpParameter.Test_Tracker_UserInput_All_Different_URL_And_SAC;
+var
+ TrackerListOrder: TTrackerListOrder;
+ TrackerURL: string;
+ StartupParameter: TStartupParameter;
+const
+ ANNOUNCE = '/announce';
+ ANNOUNCE_PHP = '/announce.php';
+ ANNOUNCE_private = '/announce?abcd';
+
+ procedure TestStartUpParameter;
+ begin
+ Add_One_URL(StartupParameter, TrackerURL, True);
+ Add_One_URL(StartupParameter, TrackerURL + ANNOUNCE, True);
+ Add_One_URL(StartupParameter, TrackerURL + ANNOUNCE_PHP, True);
+ Add_One_URL(StartupParameter, TrackerURL + ANNOUNCE_private, True);
+ end;
+
+ procedure TestAllURL;
+ begin
+ //Test if all the tracker update mode is working
+ for TrackerListOrder in TTrackerListOrder do
+ begin
+ StartupParameter.TrackerListOrder := TrackerListOrder;
+
+ TrackerURL := 'udp://test.com';
+ TestStartUpParameter;
+
+ TrackerURL := 'http://test.com';
+ TestStartUpParameter;
+
+ TrackerURL := 'https://test.com';
+ TestStartUpParameter;
+
+ TrackerURL := 'ws://test.com';
+ TestStartUpParameter;
+
+ TrackerURL := 'wss://test.com';
+ TestStartUpParameter;
+ end;
+ end;
+
+begin
+ // Skip announce check.
+ StartupParameter.SkipAnnounceCheck := True;
+ StartupParameter.SourcePresent := False;
+ TestAllURL;
+
+ // Skip announce check and add SOURCE
+ StartupParameter.SkipAnnounceCheck := True;
+ StartupParameter.SourcePresent := True;
+ StartupParameter.SourceText := 'ABCDE';
+ TestAllURL;
+end;
+
+procedure TTestStartUpParameter.
+Test_Create_Empty_Torrent_And_Then_Filled_It_All_List_Order_Mode;
+var
+ TrackerListOrder: TTrackerListOrder;
+ StartupParameter: TStartupParameter;
+begin
+ //Test if all the mode that support empty torrent creation
+ //Empty torrent -> filled torrent -> empty torrent
+
+ StartupParameter.SkipAnnounceCheck := False;
+ StartupParameter.SourcePresent := False;
+
+ for TrackerListOrder in TTrackerListOrder do
+ begin
+ StartupParameter.TrackerListOrder := TrackerListOrder;
+
+ //It is by design that it can not create a empty torrent
+ //The 'KeepOriginalIntactAndRemoveNothing' prevent it from deleting the torrent
+ //must skip the test for this one
+ if TrackerListOrder = tloInsertNewBeforeAndKeepOriginalIntactAndRemoveNothing then
+ continue;
+
+ //It is by design that it can not create a empty torrent
+ //The 'KeepOriginalIntactAndRemoveNothing' prevent it from deleting the torrent
+ //must skip the test for this one
+ if TrackerListOrder = tloAppendNewAfterAndKeepOriginalIntactAndRemoveNothing then
+ continue;
+
+ //Create empty the torrent
+ CreateEmptyTorrent(StartupParameter);
+ //check the exit code
+ CheckEquals(0, FExitCode);
+
+ TestEmptyTorrentResult;
+ //Check the logdata status
+ Check(ReadConsoleLogFile, 'Log data is not present');
+ Check(FConsoleLogData.StatusOK);
+ Check(FConsoleLogData.TrackersCount = 0);
+ Check(FConsoleLogData.TorrentFilesCount = TEST_TORRENT_FILES_COUNT);
+
+ //fill the empty torrent with data
+ CreateFilledTorrent(StartupParameter);
+ //check the exit code
+ CheckEquals(0, FExitCode);
+
+ //Check the logdata status
+ Check(ReadConsoleLogFile, 'Log data is not present');
+ Check(FConsoleLogData.StatusOK);
+ Check(FConsoleLogData.TrackersCount > 0);
+ Check(FConsoleLogData.TorrentFilesCount = TEST_TORRENT_FILES_COUNT);
+
+ //Create empty the torrent again
+ CreateEmptyTorrent(StartupParameter);
+ //check the exit code
+ CheckEquals(0, FExitCode);
+
+ TestEmptyTorrentResult;
+ //Check the log data status
+ Check(ReadConsoleLogFile, 'Log data is not present');
+ Check(FConsoleLogData.StatusOK);
+ Check(FConsoleLogData.TrackersCount = 0);
+ Check(FConsoleLogData.TorrentFilesCount = TEST_TORRENT_FILES_COUNT);
+
+ end;
+end;
+
+procedure TTestStartUpParameter.SetUp;
+begin
+ WriteLn('TTestStartUpParameter.SetUp');
+ //Create all the TStringList items
+ FVerifyTrackerResult.TrackerOriginal := TStringList.Create;
+ FVerifyTrackerResult.TrackerAdded := TStringList.Create;
+ FVerifyTrackerResult.TrackerRemoved := TStringList.Create;
+ FVerifyTrackerResult.TrackerEndResult := TStringList.Create;
+
+ //Create some full path link
+ FFullPathToRoot := GetProjectRootFolderWithPathDelimiter;
+ FFullPathToTorrent := FFullPathToRoot + TORRENT_FOLDER + PathDelim;
+ FFullPathToEndUser := FFullPathToRoot + END_USER_FOLDER + PathDelim;
+
+ //fill with torrent file(s)
+ FTorrentFilesNameStringList := TStringList.Create;
+ torrent_miscellaneous.LoadTorrentViaDir(FFullPathToTorrent,
+ FTorrentFilesNameStringList);
+
+ FNewTrackon := TNewTrackon.Create;
+
+ //path to the programe we want to test.
+ FFullPathToBinary := FFullPathToEndUser + PROGRAME_TO_BE_TESTED_NAME +
+ ExtractFileExt(ParamStr(0));
+
+ //Delete all the previeus test result
+ DeleteFile(FFullPathToEndUser + FILE_NAME_CONSOLE_LOG);
+ DeleteFile(FFullPathToEndUser + FILE_NAME_EXPORT_TRACKERS);
+ DeleteFile(FFullPathToEndUser + FILE_NAME_ADD_TRACKERS);
+ DeleteFile(FFullPathToEndUser + FILE_NAME_REMOVE_TRACKERS);
+
+end;
+
+procedure TTestStartUpParameter.TearDown;
+begin
+ WriteLn('TTestStartUpParameter.TearDown');
+ //Free the TStringList items
+ FVerifyTrackerResult.TrackerOriginal.Free;
+ FVerifyTrackerResult.TrackerAdded.Free;
+ FVerifyTrackerResult.TrackerRemoved.Free;
+ FVerifyTrackerResult.TrackerEndResult.Free;
+
+
+ FTorrentFilesNameStringList.Free;
+ FNewTrackon.Free;
+end;
+
+function TTestStartUpParameter.ReadConsoleLogFile: boolean;
+begin
+ Result := LoadConsoleLog(FFullPathToEndUser + FILE_NAME_CONSOLE_LOG,
+ FConsoleLogData.StatusOK, FConsoleLogData.TorrentFilesCount,
+ FConsoleLogData.TrackersCount);
+end;
+
+initialization
+ // macOS version does not support startup parameter
+{$IFNDEF CPUAARCH64}
+{$IFNDEF DARWIN}
+ RegisterTest(TTestStartUpParameter);
+{$ENDIF}
+{$ENDIF}
+
+end.
diff --git a/test_torrent/Sintel.2010.2K.SURROUND.x264-VODO.torrent b/test_torrent/Sintel.2010.2K.SURROUND.x264-VODO.torrent
new file mode 100644
index 0000000..06b1573
Binary files /dev/null and b/test_torrent/Sintel.2010.2K.SURROUND.x264-VODO.torrent differ
diff --git a/test_torrent/Sintel.2010.2K.Theora.Ogv-VODO.torrent b/test_torrent/Sintel.2010.2K.Theora.Ogv-VODO.torrent
new file mode 100644
index 0000000..bac714d
Binary files /dev/null and b/test_torrent/Sintel.2010.2K.Theora.Ogv-VODO.torrent differ
diff --git a/test_torrent/Sintel.2010.720p.SURROUND.x264-VODO.torrent b/test_torrent/Sintel.2010.720p.SURROUND.x264-VODO.torrent
new file mode 100644
index 0000000..c499c9f
Binary files /dev/null and b/test_torrent/Sintel.2010.720p.SURROUND.x264-VODO.torrent differ
diff --git a/travis-lazarus b/travis-lazarus
index 060c730..e5caece 160000
--- a/travis-lazarus
+++ b/travis-lazarus
@@ -1 +1 @@
-Subproject commit 060c73066537137ca7b3748e4c7747fbaf91fd69
+Subproject commit e5caece318f06832ff767e3824ee450bcb7b7512