commit
6b63bd9626
61
README.md
61
README.md
@ -1,6 +1,6 @@
|
|||||||
# qbit-maid
|
# qbit-maid
|
||||||
|
|
||||||
Warning: This application removes torrents that aren't downloading and that aren't from iptorrents. Age in the config.json only controls the age for torrents from iptorrents.
|
## Warning: This application removes torrents that are over the minimum age and that are not part of the ignored categories, domains or tags. Please use the delete_torrents feature set to false when first testing its functionality.
|
||||||
|
|
||||||
The objective is to remove torrents based on the following criteria:
|
The objective is to remove torrents based on the following criteria:
|
||||||
- tracker domain name
|
- tracker domain name
|
||||||
@ -24,9 +24,32 @@ graph TD;
|
|||||||
| qlist.py | Builds out torrent lists |
|
| qlist.py | Builds out torrent lists |
|
||||||
| qlogging.py | Logging and push notification communication |
|
| qlogging.py | Logging and push notification communication |
|
||||||
| qprocess.py | Submits qualifying torrents for deletion |
|
| qprocess.py | Submits qualifying torrents for deletion |
|
||||||
|
| test_qbitmaid.py | Unit tests |
|
||||||
|
| ignored_categories.json | whitelist for categorys to ignore |
|
||||||
|
| ignored_tags.json | whitelist for torrent tags to ignore |
|
||||||
|
| ignored_trackers.json | whitelist of fqdn names to ignore |
|
||||||
|
|
||||||
You will need a config.json in the root directory.
|
You will need a config.json in the root directory.
|
||||||
|
|
||||||
|
| Key | Value |
|
||||||
|
| --- | --- |
|
||||||
|
| host | string, ip or hostname of qbittorrent server |
|
||||||
|
| port | number, port of admin gui(used for api aswell) |
|
||||||
|
| username | admin account for qbittorrent |
|
||||||
|
| password | password for admin account |
|
||||||
|
| loglevel | is what log messages are written to the log file. INFO or DEBUG are valid entries(case sensitive) |
|
||||||
|
| protected_tag | used to mark torrents to handle with care |
|
||||||
|
| non_protected_tag | we don't care about these torrents |
|
||||||
|
| logpath | will write a log in root directory if left as is other wise specify other path using forward slashes |
|
||||||
|
| age | number, seconds for how long we keep torrents from IPTORRENTS |
|
||||||
|
| minimum_age | age in seconds torrents should reached before they are removed |
|
||||||
|
| use_pushover | true or false to enable or disable pushover notification summary |
|
||||||
|
| use_log | true or false to enable or disable writing to alog file |
|
||||||
|
| po_key | pushover key |
|
||||||
|
| po_token | pushover api token |
|
||||||
|
| delete_torrents | true or false to enable or disable deletion. Useful for dry-runs |
|
||||||
|
| enable_dragnet | true or false to enable dragnet functionality. Useful for debugging |
|
||||||
|
|
||||||
It should look something like this:
|
It should look something like this:
|
||||||
Config.json
|
Config.json
|
||||||
```
|
```
|
||||||
@ -51,7 +74,7 @@ Config.json
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
You will need a category-whitelist.json in the root directory. This will ignore any of the categories found in the values of the entries.
|
You will need a ignored_categories.json in the root directory. This will ignore any of the categories found in the values of the entries.
|
||||||
```
|
```
|
||||||
{
|
{
|
||||||
"example": "general",
|
"example": "general",
|
||||||
@ -59,22 +82,20 @@ You will need a category-whitelist.json in the root directory. This will ignore
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
You will need a ignored_domains.json in the root directory. This will ignore any torrents from these trackers.
|
||||||
|
```
|
||||||
|
{
|
||||||
|
"iptorrents-empirehost": "ssl.empirehost.me",
|
||||||
|
"iptorrents-stackoverflow": "localhost.stackoverflow.tech",
|
||||||
|
"iptorrents-bgp": "routing.bgp.technology"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
| Key | Value |
|
You will need a ignored_tags.json in the root directory. This will ignore any torrents with these tags.
|
||||||
| --- | --- |
|
```
|
||||||
| host | string, ip or hostname of qbittorrent server |
|
{
|
||||||
| port | number, port of admin gui(used for api aswell) |
|
"first":"first",
|
||||||
| username | admin account for qbittorrent |
|
"second":"second",
|
||||||
| password | password for admin account |
|
"third":"third"
|
||||||
| loglevel | is what log messages are written to the log file. INFO or DEBUG are valid entries(case sensitive) |
|
}
|
||||||
| protected_tag | used to mark torrents to handle with care |
|
```
|
||||||
| non_protected_tag | we don't care about these torrents |
|
|
||||||
| logpath | will write a log in root directory if left as is other wise specify other path using forward slashes |
|
|
||||||
| age | number, seconds for how long we keep torrents from IPTORRENTS |
|
|
||||||
| minimum_age | age in seconds torrents should reached before they are removed |
|
|
||||||
| use_pushover | true or false to enable or disable pushover notification summary |
|
|
||||||
| use_log | true or false to enable or disable writing to alog file |
|
|
||||||
| po_key | pushover key |
|
|
||||||
| po_token | pushover api token |
|
|
||||||
| delete_torrents | true or false to enable or disable deletion. Useful for dry-runs |
|
|
||||||
| enable_dragnet | true or false to enable dragnet functionality. Useful for debugging |
|
|
5
ignored_tags.json.example
Normal file
5
ignored_tags.json.example
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"first":"first",
|
||||||
|
"second":"second",
|
||||||
|
"third":"third"
|
||||||
|
}
|
@ -18,8 +18,10 @@ class Qbt:
|
|||||||
self.st = datetime.datetime.now()
|
self.st = datetime.datetime.now()
|
||||||
c = open('./config.json')
|
c = open('./config.json')
|
||||||
self.config = load(c)
|
self.config = load(c)
|
||||||
w = open('./category-whitelist.json')
|
w = open('./ignored_categories.json')
|
||||||
self.cat_whitelist = load(w)
|
self.cat_whitelist = load(w)
|
||||||
|
tg = open('./ignored_tags.json')
|
||||||
|
self.ignored_tags = load(tg)
|
||||||
# Create the api object
|
# Create the api object
|
||||||
self.qbt_client = qbittorrentapi.Client(
|
self.qbt_client = qbittorrentapi.Client(
|
||||||
host=self.config["host"],
|
host=self.config["host"],
|
||||||
@ -50,7 +52,7 @@ class Qbt:
|
|||||||
tornotify(self)
|
tornotify(self)
|
||||||
self.t = time
|
self.t = time
|
||||||
# Pulling domain names to treat carefully
|
# Pulling domain names to treat carefully
|
||||||
f = open('./tracker-whitelist.json')
|
f = open('./ignored_domains.json')
|
||||||
self.tracker_whitelist = load(f)
|
self.tracker_whitelist = load(f)
|
||||||
self.tracker_list = []
|
self.tracker_list = []
|
||||||
self.up_tor_counter = 0
|
self.up_tor_counter = 0
|
||||||
|
9
qlist.py
9
qlist.py
@ -9,6 +9,9 @@ def buildtorlist(self):
|
|||||||
torrent = self.torrentlist.pop()
|
torrent = self.torrentlist.pop()
|
||||||
if self.use_log:
|
if self.use_log:
|
||||||
self.tl.debug(f'["{torrent["name"][0:20]}..."] {torrent["infohash_v1"]}')
|
self.tl.debug(f'["{torrent["name"][0:20]}..."] {torrent["infohash_v1"]}')
|
||||||
|
if isignoredtag(self.ignored_tags.values(),torrent['tags']):
|
||||||
|
self.ignored_counter += 1
|
||||||
|
continue
|
||||||
# if torrent['added_on'] + self.minimum_age >= self.t.time():
|
# if torrent['added_on'] + self.minimum_age >= self.t.time():
|
||||||
if ispreme(torrent['added_on'], self.minimum_age, self.t.time()):
|
if ispreme(torrent['added_on'], self.minimum_age, self.t.time()):
|
||||||
self.preme_tor_counter += 1
|
self.preme_tor_counter += 1
|
||||||
@ -63,4 +66,8 @@ def isnotprotectedtracker(tracker, trackerlist):
|
|||||||
def istagblank(tag):
|
def istagblank(tag):
|
||||||
if tag == '':
|
if tag == '':
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def isignoredtag(igtags, tortags):
|
||||||
|
for igt in igtags:
|
||||||
|
if igt in tortags:
|
||||||
|
return True
|
@ -1,5 +1,5 @@
|
|||||||
import unittest
|
import unittest
|
||||||
from qlist import ispreme,iscatignored,istrackerblank,isprotectedtracker,isnotprotectedtracker,istagblank
|
from qlist import ispreme,iscatignored,istrackerblank,isprotectedtracker,isnotprotectedtracker,istagblank,isignoredtag
|
||||||
from qprocess import isdownloading,isprotectedunderratio,isoldtor,isprotectedoverratio,isnonprotectedtor
|
from qprocess import isdownloading,isprotectedunderratio,isoldtor,isprotectedoverratio,isnonprotectedtor
|
||||||
|
|
||||||
class TestQbitmaid(unittest.TestCase):
|
class TestQbitmaid(unittest.TestCase):
|
||||||
@ -87,6 +87,12 @@ class TestQbitmaid(unittest.TestCase):
|
|||||||
def test_isnonprotectedtor(self):
|
def test_isnonprotectedtor(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def test_isignoredtag_sanity(self):
|
||||||
|
self.assertTrue(isignoredtag(['a','b','c'], 'first,second,third,a'))
|
||||||
|
|
||||||
|
def test_isignoredtag_sanity(self):
|
||||||
|
self.assertTrue(isignoredtag(['a','b','c'], 'first,second,third,a'))
|
||||||
|
|
||||||
# def test__sanity(self):
|
# def test__sanity(self):
|
||||||
# pass
|
# pass
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user