From 44b98841fd8b7f84bb27a313de3e19d6629339cd Mon Sep 17 00:00:00 2001 From: jerrymakesjelly Date: Sun, 9 Feb 2020 00:15:57 +0800 Subject: [PATCH] Add avg max_dl_speed and min_ul_speed condition Closes #49. --- autoremovetorrents/client/qbittorrent.py | 2 ++ autoremovetorrents/client/transmission.py | 32 +++++++++++++++++-- .../condition/avgdownloadspeed.py | 15 +++++++++ .../condition/avguploadspeed.py | 15 +++++++++ autoremovetorrents/strategy.py | 4 +++ .../test_max_average_downloadspeed.yml | 12 +++++++ .../test_min_average_uploadspeed.yml | 9 ++++++ pytest/test_strategies/conftest.py | 2 ++ pytest/test_strategies/data.json | 32 +++++++++++++++++++ 9 files changed, 120 insertions(+), 3 deletions(-) create mode 100644 autoremovetorrents/condition/avgdownloadspeed.py create mode 100644 autoremovetorrents/condition/avguploadspeed.py create mode 100644 pytest/test_strategies/cases/max_average_downloadspeed/test_max_average_downloadspeed.yml create mode 100644 pytest/test_strategies/cases/min_average_uploadspeed/test_min_average_uploadspeed.yml diff --git a/autoremovetorrents/client/qbittorrent.py b/autoremovetorrents/client/qbittorrent.py index 92329b2..77f1fc9 100644 --- a/autoremovetorrents/client/qbittorrent.py +++ b/autoremovetorrents/client/qbittorrent.py @@ -186,6 +186,8 @@ def torrent_properties(self, torrent_hash): torrent_obj.connected_seeder = properties['seeds'] torrent_obj.leecher = properties['peers_total'] torrent_obj.connected_leecher = properties['peers'] + torrent_obj.average_upload_speed = properties['up_speed_avg'] + torrent_obj.average_download_speed = properties['dl_speed_avg'] # For qBittorrent 3.x, the last activity field doesn't exist. # We need to check the existence if 'last_activity' in torrent: diff --git a/autoremovetorrents/client/transmission.py b/autoremovetorrents/client/transmission.py index 3b9e5ee..d5d4368 100644 --- a/autoremovetorrents/client/transmission.py +++ b/autoremovetorrents/client/transmission.py @@ -75,8 +75,32 @@ def torrents_list(self): # Get Torrent Properties def torrent_properties(self, torrent_hash): result = self._make_transmission_request('torrent-get', - {'ids': [torrent_hash], - 'fields': ['hashString', 'name', 'trackers', 'status', 'totalSize', 'uploadRatio', 'uploadedEver', 'addedDate', 'secondsSeeding', 'isStalled', 'error', 'labels', 'rateDownload', 'rateUpload', 'peersGettingFromUs', 'peersSendingToUs', 'trackerStats', 'activityDate']} + { + 'ids': [torrent_hash], + 'fields': [ + 'hashString', + 'name', + 'trackers', + 'status', + 'totalSize', + 'uploadRatio', + 'uploadedEver', + 'addedDate', + 'secondsSeeding', + 'isStalled', + 'error', + 'labels', + 'rateDownload', + 'rateUpload', + 'peersGettingFromUs', + 'peersSendingToUs', + 'trackerStats', + 'activityDate', + 'uploadedEver', + 'secondsSeeding', + 'downloadedEver', + 'secondsDownloading', + ]} ) if len(result['torrents']) == 0: # No such torrent raise NoSuchClient("No such torrent of hash '%s'." % torrent_hash) @@ -101,7 +125,9 @@ def torrent_properties(self, torrent_hash): torrent_obj.leecher = sum([tracker['leecherCount'] for tracker in torrent['trackerStats']]) torrent_obj.connected_leecher = torrent['peersGettingFromUs'] torrent_obj.last_activity = torrent['activityDate'] - + torrent_obj.average_upload_speed = torrent['uploadedEver'] / torrent['secondsSeeding'] + torrent_obj.average_download_speed = torrent['downloadedEver'] / torrent['secondsDownloading'] + return torrent_obj # Judge Torrent Status diff --git a/autoremovetorrents/condition/avgdownloadspeed.py b/autoremovetorrents/condition/avgdownloadspeed.py new file mode 100644 index 0000000..54b67cc --- /dev/null +++ b/autoremovetorrents/condition/avgdownloadspeed.py @@ -0,0 +1,15 @@ +from .base import Comparer +from .base import Condition + +class AverageDownloadSpeedCondition(Condition): + def __init__(self, avg_dl_speed, comp = Comparer.GT): + Condition.__init__(self) # Initialize remain and remove list + self._avg_dl_speed = avg_dl_speed # In KiB + self._comparer = comp + + def apply(self, torrents): + for torrent in torrents: + if self.compare(torrent.average_download_speed, self._avg_dl_speed * 1024, self._comparer): + self.remove.add(torrent) + else: + self.remain.add(torrent) \ No newline at end of file diff --git a/autoremovetorrents/condition/avguploadspeed.py b/autoremovetorrents/condition/avguploadspeed.py new file mode 100644 index 0000000..8636b4d --- /dev/null +++ b/autoremovetorrents/condition/avguploadspeed.py @@ -0,0 +1,15 @@ +from .base import Comparer +from .base import Condition + +class AverageUploadSpeedCondition(Condition): + def __init__(self, avg_ul_speed, comp = Comparer.LT): + Condition.__init__(self) # Initialize remain and remove list + self._avg_ul_speed = avg_ul_speed # In KiB + self._comparer = comp + + def apply(self, torrents): + for torrent in torrents: + if self.compare(torrent.average_upload_speed, self._avg_ul_speed * 1024, self._comparer): + self.remove.add(torrent) + else: + self.remain.add(torrent) \ No newline at end of file diff --git a/autoremovetorrents/strategy.py b/autoremovetorrents/strategy.py index a3152e0..bc68a50 100644 --- a/autoremovetorrents/strategy.py +++ b/autoremovetorrents/strategy.py @@ -10,7 +10,9 @@ from .condition.connectedseeder import ConnectedSeederCondition from .condition.leecher import LeecherCondition from .condition.connectedleecher import ConnectedLeecherCondition +from .condition.avgdownloadspeed import AverageDownloadSpeedCondition from .condition.downloadspeed import DownloadSpeedCondition +from .condition.avguploadspeed import AverageUploadSpeedCondition from .condition.uploadspeed import UploadSpeedCondition from .condition.torrentsize import TorrentSizeCondition from .condition.torrentnumber import TorrentNumberCondition @@ -79,7 +81,9 @@ def _apply_conditions(self): 'min_leecher': LeecherCondition, 'min_connected_leecher': ConnectedLeecherCondition, 'max_downloadspeed': DownloadSpeedCondition, + 'max_average_downloadspeed': AverageDownloadSpeedCondition, 'min_uploadspeed': UploadSpeedCondition, + 'min_average_uploadspeed': AverageUploadSpeedCondition, 'size': SizeCondition, 'last_activity': LastActivityCondition, 'seed_size': TorrentSizeCondition, diff --git a/pytest/test_strategies/cases/max_average_downloadspeed/test_max_average_downloadspeed.yml b/pytest/test_strategies/cases/max_average_downloadspeed/test_max_average_downloadspeed.yml new file mode 100644 index 0000000..2937e40 --- /dev/null +++ b/pytest/test_strategies/cases/max_average_downloadspeed/test_max_average_downloadspeed.yml @@ -0,0 +1,12 @@ +test: + max_average_downloadspeed: 5120 +remove: + - Torrent - 3 + - Torrent - 5 + - Torrent - 7 + - Torrent - 8 + - Torrent - 9 + - Torrent - 11 + - Torrent - 13 + - Torrent - 14 + - Torrent - 16 diff --git a/pytest/test_strategies/cases/min_average_uploadspeed/test_min_average_uploadspeed.yml b/pytest/test_strategies/cases/min_average_uploadspeed/test_min_average_uploadspeed.yml new file mode 100644 index 0000000..9c69e81 --- /dev/null +++ b/pytest/test_strategies/cases/min_average_uploadspeed/test_min_average_uploadspeed.yml @@ -0,0 +1,9 @@ +test: + min_average_uploadspeed: 512 +remove: + - Torrent - 1 + - Torrent - 3 + - Torrent - 6 + - Torrent - 10 + - Torrent - 12 + - Torrent - 14 diff --git a/pytest/test_strategies/conftest.py b/pytest/test_strategies/conftest.py index c27dc04..6d96c81 100644 --- a/pytest/test_strategies/conftest.py +++ b/pytest/test_strategies/conftest.py @@ -29,7 +29,9 @@ def test_data(): torrent_obj.create_time = torrent['added_on'] torrent_obj.seeding_time = torrent['seeding_time'] torrent_obj.upload_speed = torrent['upspeed'] + torrent_obj.average_upload_speed = torrent['up_speed_avg'] torrent_obj.download_speed = torrent['dlspeed'] + torrent_obj.average_download_speed = torrent['dl_speed_avg'] torrent_obj.last_activity = torrent['last_activity'] torrent_obj.seeder = torrent['num_complete'] torrent_obj.connected_seeder = torrent['num_seeds'] diff --git a/pytest/test_strategies/data.json b/pytest/test_strategies/data.json index d3d6162..30e6ab8 100644 --- a/pytest/test_strategies/data.json +++ b/pytest/test_strategies/data.json @@ -5,6 +5,7 @@ "completed": 5707223927, "completion_on": 4294967295, "dl_limit": 0, + "dl_speed_avg": 499524, "dlspeed": 2270401, "downloaded": 5710905998, "downloaded_session": 5710905998, @@ -36,6 +37,7 @@ "https://tracker.site1.com/announce" ], "up_limit": 0, + "up_speed_avg": 78804, "uploaded": 8564552428, "uploaded_session": 8564552428, "upspeed": 984644 @@ -46,6 +48,7 @@ "completed": 19054854172, "completion_on": 4294967295, "dl_limit": 0, + "dl_speed_avg": 188567, "dlspeed": 1583918, "downloaded": 19053990510, "downloaded_session": 19053990510, @@ -77,6 +80,7 @@ "https://www.site2.org/tracker/announce" ], "up_limit": 0, + "up_speed_avg": 808605, "uploaded": 51623504177, "uploaded_session": 51623504177, "upspeed": 2886504 @@ -87,6 +91,7 @@ "completed": 347000034, "completion_on": 1526732525, "dl_limit": 0, + "dl_speed_avg": 5584975, "dlspeed": 0, "downloaded": 347198660, "downloaded_session": 347198660, @@ -118,6 +123,7 @@ "https://www.site2.org/tracker/announce" ], "up_limit": 0, + "up_speed_avg": 456008, "uploaded": 812985418, "uploaded_session": 812985418, "upspeed": 0 @@ -128,6 +134,7 @@ "completed": 10152029087, "completion_on": 1525970677, "dl_limit": 0, + "dl_speed_avg": 5019202, "dlspeed": 0, "downloaded": 0, "downloaded_session": 0, @@ -159,6 +166,7 @@ "http://tracker.site3.com/?action=announce" ], "up_limit": 0, + "up_speed_avg": 832684, "uploaded": 43783272788, "uploaded_session": 0, "upspeed": 0 @@ -169,6 +177,7 @@ "completed": 9627866528, "completion_on": 1526723020, "dl_limit": 0, + "dl_speed_avg": 7858040, "dlspeed": 0, "downloaded": 9628171953, "downloaded_session": 9628171953, @@ -200,6 +209,7 @@ "https://www.site2.org/tracker/announce" ], "up_limit": 0, + "up_speed_avg": 851779, "uploaded": 29372377819, "uploaded_session": 29372377819, "upspeed": 0 @@ -211,6 +221,7 @@ "completion_on": 1526736296, "dl_limit": 0, "dlspeed": 0, + "dl_speed_avg": 4633382, "downloaded": 13201638292, "downloaded_session": 13201638292, "eta": 8640000, @@ -241,6 +252,7 @@ "https://www.site2.org/tracker/announce" ], "up_limit": 0, + "up_speed_avg": 37146, "uploaded": 23420454865, "uploaded_session": 23420454865, "upspeed": 121201 @@ -252,6 +264,7 @@ "completion_on": 1526738269, "dl_limit": 0, "dlspeed": 0, + "dl_speed_avg": 9855309, "downloaded": 7240240790, "downloaded_session": 7240240790, "eta": 8640000, @@ -282,6 +295,7 @@ "https://tracker.site1.com/announce" ], "up_limit": 0, + "up_speed_avg": 812996, "uploaded": 18854220629, "uploaded_session": 18854220629, "upspeed": 0 @@ -293,6 +307,7 @@ "completion_on": 1526731123, "dl_limit": 0, "dlspeed": 0, + "dl_speed_avg": 7062911, "downloaded": 7621738011, "downloaded_session": 7621738011, "eta": 8640000, @@ -323,6 +338,7 @@ "https://www.site2.org/tracker/announce" ], "up_limit": 0, + "up_speed_avg": 801737, "uploaded": 32700782429, "uploaded_session": 32700782429, "upspeed": 87463 @@ -333,6 +349,7 @@ "completed": 3022394751, "completion_on": 1525969428, "dl_limit": 0, + "dl_speed_avg": 6112945, "dlspeed": 0, "downloaded": 0, "downloaded_session": 0, @@ -364,6 +381,7 @@ "http://tracker.site3.com/?action=announce" ], "up_limit": 0, + "up_speed_avg": 900793, "uploaded": 6949286694, "uploaded_session": 26198016, "upspeed": 0 @@ -374,6 +392,7 @@ "completed": 14844911534, "completion_on": 1526735607, "dl_limit": 0, + "dl_speed_avg": 4306811, "dlspeed": 0, "downloaded": 14846696889, "downloaded_session": 14846696889, @@ -405,6 +424,7 @@ "https://www.site2.org/tracker/announce" ], "up_limit": 0, + "up_speed_avg": 152048, "uploaded": 32388045222, "uploaded_session": 32388045222, "upspeed": 327541 @@ -415,6 +435,7 @@ "completed": 2321891132, "completion_on": 4294967295, "dl_limit": 0, + "dl_speed_avg": 6403655, "dlspeed": 302084, "downloaded": 2321882559, "downloaded_session": 2321882559, @@ -446,6 +467,7 @@ "https://tracker.site1.com/announce" ], "up_limit": 0, + "up_speed_avg": 586125, "uploaded": 5750836550, "uploaded_session": 5750836550, "upspeed": 442042 @@ -456,6 +478,7 @@ "completed": 1715653161, "completion_on": 4294967295, "dl_limit": 0, + "dl_speed_avg": 3792899, "dlspeed": 269870, "downloaded": 1716876766, "downloaded_session": 1716876766, @@ -487,6 +510,7 @@ "https://www.site2.org/tracker/announce" ], "up_limit": 0, + "up_speed_avg": 254117, "uploaded": 4056422836, "uploaded_session": 4056422836, "upspeed": 668038 @@ -497,6 +521,7 @@ "completed": 1746686185, "completion_on": 1527342372, "dl_limit": 0, + "dl_speed_avg": 10211715, "dlspeed": 0, "downloaded": 1747429022, "downloaded_session": 1747429022, @@ -528,6 +553,7 @@ "https://tracker.site4.io:2710/" ], "up_limit": 0, + "up_speed_avg": 661650, "uploaded": 1898576526, "uploaded_session": 1898576526, "upspeed": 0 @@ -538,6 +564,7 @@ "completed": 312186667, "completion_on": 1527335960, "dl_limit": 0, + "dl_speed_avg": 9987804, "dlspeed": 0, "downloaded": 312891624, "downloaded_session": 312891624, @@ -569,6 +596,7 @@ "https://tracker.site4.io:2710/" ], "up_limit": 0, + "up_speed_avg": 482248, "uploaded": 107814988, "uploaded_session": 107814988, "upspeed": 0 @@ -579,6 +607,7 @@ "completed": 2126568405, "completion_on": 1527350573, "dl_limit": 0, + "dl_speed_avg": 2708163, "dlspeed": 0, "downloaded": 2127119819, "downloaded_session": 2127119819, @@ -610,6 +639,7 @@ "https://tracker.site4.io:2710/" ], "up_limit": 0, + "up_speed_avg": 950107, "uploaded": 3323768148, "uploaded_session": 3323768148, "upspeed": 0 @@ -620,6 +650,7 @@ "completed": 1132013553, "completion_on": 1527335868, "dl_limit": 0, + "dl_speed_avg": 7002425, "dlspeed": 0, "downloaded": 1139339147, "downloaded_session": 1139339147, @@ -651,6 +682,7 @@ "https://tracker.site4.io:2710/" ], "up_limit": 0, + "up_speed_avg": 924258, "uploaded": 395526144, "uploaded_session": 395526144, "upspeed": 8055