mirror of
https://github.com/rembo10/headphones.git
synced 2026-05-22 11:27:45 +01:00
Torrent seed ratio part 2
Set scheduled job to remove torrent when post processed and finished seeding
This commit is contained in:
@@ -395,7 +395,7 @@
|
||||
</div>
|
||||
<div class="row">
|
||||
<label>Seed Ratio: </label>
|
||||
<input type="text" class="override-float" name="piratebay_ratio" value="${config['piratebay_ratio']}" size="10" title="Stop seeding when ratio met, 0 = unlimited">
|
||||
<input type="text" class="override-float" name="piratebay_ratio" value="${config['piratebay_ratio']}" size="10" title="Stop seeding when ratio met, 0 = unlimited. Scheduled job will remove torrent when post processed and finished seeding">
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
@@ -412,7 +412,7 @@
|
||||
</div>
|
||||
<div class="row">
|
||||
<label>Seed Ratio: </label>
|
||||
<input type="text" class="override-float" name="kat_ratio" value="${config['kat_ratio']}" size="10" title="Stop seeding when ratio met, 0 = unlimited">
|
||||
<input type="text" class="override-float" name="kat_ratio" value="${config['kat_ratio']}" size="10" title="Stop seeding when ratio met, 0 = unlimited. Scheduled job will remove torrent when post processed and finished seeding">
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
@@ -433,7 +433,7 @@
|
||||
</div>
|
||||
<div class="row">
|
||||
<label>Seed Ratio: </label>
|
||||
<input type="text" class="override-float" name="waffles_ratio" value="${config['waffles_ratio']}" size="10" title="Stop seeding when ratio met, 0 = unlimited">
|
||||
<input type="text" class="override-float" name="waffles_ratio" value="${config['waffles_ratio']}" size="10" title="Stop seeding when ratio met, 0 = unlimited. Scheduled job will remove torrent when post processed and finished seeding">
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
@@ -454,7 +454,7 @@
|
||||
</div>
|
||||
<div class="row">
|
||||
<label>Seed Ratio: </label>
|
||||
<input type="text" class="override-float" name="rutracker_ratio" value="${config['rutracker_ratio']}" size="10" title="Stop seeding when ratio met, 0 = unlimited">
|
||||
<input type="text" class="override-float" name="rutracker_ratio" value="${config['rutracker_ratio']}" size="10" title="Stop seeding when ratio met, 0 = unlimited. Scheduled job will remove torrent when post processed and finished seeding">
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
@@ -475,7 +475,7 @@
|
||||
</div>
|
||||
<div class="row">
|
||||
<label>Seed Ratio: </label>
|
||||
<input type="text" class="override-float" name="whatcd_ratio" value="${config['whatcd_ratio']}" size="10" title="Stop seeding when ratio met, 0 = unlimited">
|
||||
<input type="text" class="override-float" name="whatcd_ratio" value="${config['whatcd_ratio']}" size="10" title="Stop seeding when ratio met, 0 = unlimited. Scheduled job will remove torrent when post processed and finished seeding">
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
@@ -488,7 +488,7 @@
|
||||
<div class="config">
|
||||
<div class="row">
|
||||
<label>Seed Ratio: </label>
|
||||
<input type="text" class="override-float" name="mininova_ratio" value="${config['mininova_ratio']}" size="10" title="Stop seeding when ratio met, 0 = unlimited">
|
||||
<input type="text" class="override-float" name="mininova_ratio" value="${config['mininova_ratio']}" size="10" title="Stop seeding when ratio met, 0 = unlimited. Scheduled job will remove torrent when post processed and finished seeding">
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
@@ -514,7 +514,6 @@ def initialize():
|
||||
WHATCD_USERNAME = check_setting_str(CFG, 'What.cd', 'whatcd_username', '')
|
||||
WHATCD_PASSWORD = check_setting_str(CFG, 'What.cd', 'whatcd_password', '')
|
||||
WHATCD_RATIO = check_setting_str(CFG, 'What.cd', 'whatcd_ratio', '')
|
||||
WHATCD_PASSWORD = check_setting_str(CFG, 'What.cd', 'whatcd_password', '')
|
||||
|
||||
SAB_HOST = check_setting_str(CFG, 'SABnzbd', 'sab_host', '')
|
||||
SAB_USERNAME = check_setting_str(CFG, 'SABnzbd', 'sab_username', '')
|
||||
@@ -1135,7 +1134,7 @@ def start():
|
||||
if __INITIALIZED__:
|
||||
|
||||
# Start our scheduled background tasks
|
||||
from headphones import updater, searcher, librarysync, postprocessor
|
||||
from headphones import updater, searcher, librarysync, postprocessor, torrentfinished
|
||||
|
||||
SCHED.add_interval_job(updater.dbUpdate, hours=UPDATE_DB_INTERVAL)
|
||||
SCHED.add_interval_job(searcher.searchforalbum, minutes=SEARCH_INTERVAL)
|
||||
@@ -1147,6 +1146,9 @@ def start():
|
||||
if DOWNLOAD_SCAN_INTERVAL > 0:
|
||||
SCHED.add_interval_job(postprocessor.checkFolder, minutes=DOWNLOAD_SCAN_INTERVAL)
|
||||
|
||||
# Remove Torrent + data if Post Processed and finished Seeding
|
||||
SCHED.add_interval_job(torrentfinished.checkTorrentFinished, hours=12)
|
||||
|
||||
SCHED.start()
|
||||
|
||||
started = True
|
||||
|
||||
+1
-1
@@ -145,7 +145,7 @@ class Api(object):
|
||||
return
|
||||
|
||||
def _getHistory(self, **kwargs):
|
||||
self.data = self._dic_from_query('SELECT * from snatched order by DateAdded DESC')
|
||||
self.data = self._dic_from_query('SELECT * from snatched WHERE status NOT LIKE "Seed%" order by DateAdded DESC')
|
||||
return
|
||||
|
||||
def _getUpcoming(self, **kwargs):
|
||||
|
||||
@@ -24,7 +24,7 @@ import headphones
|
||||
from beets import autotag
|
||||
from beets.mediafile import MediaFile, FileTypeError, UnreadableFileError
|
||||
|
||||
from headphones import notifiers
|
||||
from headphones import notifiers, utorrent, transmission
|
||||
from headphones import db, albumart, librarysync, lyrics
|
||||
from headphones import logger, helpers, request, mb, music_encoder
|
||||
|
||||
@@ -305,7 +305,7 @@ def verify(albumid, albumpath, Kind=None, forced=False):
|
||||
return
|
||||
|
||||
logger.warn(u'Could not identify album: %s. It may not be the intended album.' % albumpath.decode(headphones.SYS_ENCODING, 'replace'))
|
||||
myDB.action('UPDATE snatched SET status = "Unprocessed" WHERE AlbumID=?', [albumid])
|
||||
myDB.action('UPDATE snatched SET status = "Unprocessed" WHERE status NOT LIKE "Seed%" and AlbumID=?', [albumid])
|
||||
processed = re.search(r' \(Unprocessed\)(?:\[\d+\])?', albumpath)
|
||||
if not processed:
|
||||
renameUnprocessedFolder(albumpath)
|
||||
@@ -416,7 +416,24 @@ def doPostProcessing(albumid, albumpath, release, tracks, downloaded_track_list,
|
||||
|
||||
myDB = db.DBConnection()
|
||||
myDB.action('UPDATE albums SET status = "Downloaded" WHERE AlbumID=?', [albumid])
|
||||
myDB.action('UPDATE snatched SET status = "Processed" WHERE AlbumID=?', [albumid])
|
||||
myDB.action('UPDATE snatched SET status = "Processed" WHERE Status NOT LIKE "Seed%" and AlbumID=?', [albumid])
|
||||
|
||||
# Check if torrent has finished seeding
|
||||
if headphones.TORRENT_DOWNLOADER == (1 or 2):
|
||||
seed_snatched = myDB.action('SELECT * from snatched WHERE Status="Seed_Snatched" and AlbumID=?', [albumid]).fetchone()
|
||||
if seed_snatched:
|
||||
hash = seed_snatched['FolderName']
|
||||
torrent_removed = False
|
||||
if headphones.TORRENT_DOWNLOADER == 1:
|
||||
torrent_removed = transmission.removeTorrent(hash, True)
|
||||
else:
|
||||
torrent_removed = utorrent.removeTorrent(hash, True)
|
||||
|
||||
# Torrent removed, delete the snatched record, else update Status for scheduled job to check
|
||||
if torrent_removed:
|
||||
myDB.action('DELETE from snatched WHERE status = "Seed_Snatched" and AlbumID=?', [albumid])
|
||||
else:
|
||||
myDB.action('UPDATE snatched SET status = "Seed_Processed" WHERE status = "Seed_Snatched" and AlbumID=?', [albumid])
|
||||
|
||||
# Update the have tracks for all created dirs:
|
||||
for albumpath in albumpaths:
|
||||
|
||||
+13
-7
@@ -569,6 +569,8 @@ def send_to_downloader(data, bestqual, album):
|
||||
logger.info(u'Found best result from %s: <a href="%s">%s</a> - %s', bestqual[3], bestqual[2], bestqual[0], helpers.bytes_to_mb(bestqual[1]))
|
||||
# Get rid of any dodgy chars here so we can prevent sab from renaming our downloads
|
||||
kind = bestqual[4]
|
||||
seed_ratio = None
|
||||
torrentid = None
|
||||
|
||||
if kind == 'nzb':
|
||||
folder_name = helpers.sab_sanitize_foldername(bestqual[0])
|
||||
@@ -674,7 +676,7 @@ def send_to_downloader(data, bestqual, album):
|
||||
|
||||
# rutracker needs cookies to be set, pass the .torrent file instead of url
|
||||
if bestqual[3] == 'rutracker.org':
|
||||
file_or_url, _hash = rutracker.get_torrent(bestqual[2])
|
||||
file_or_url, torrentid = rutracker.get_torrent(bestqual[2])
|
||||
else:
|
||||
file_or_url = bestqual[2]
|
||||
|
||||
@@ -708,14 +710,14 @@ def send_to_downloader(data, bestqual, album):
|
||||
|
||||
# rutracker needs cookies to be set, pass the .torrent file instead of url
|
||||
if bestqual[3] == 'rutracker.org':
|
||||
file_or_url, _hash = rutracker.get_torrent(bestqual[2])
|
||||
folder_name, cacheid = utorrent.dirTorrent(_hash)
|
||||
file_or_url, torrentid = rutracker.get_torrent(bestqual[2])
|
||||
folder_name, cacheid = utorrent.dirTorrent(torrentid)
|
||||
folder_name = os.path.basename(os.path.normpath(folder_name))
|
||||
utorrent.labelTorrent(_hash)
|
||||
utorrent.labelTorrent(torrentid)
|
||||
else:
|
||||
file_or_url = bestqual[2]
|
||||
_hash = CalculateTorrentHash(file_or_url, data)
|
||||
folder_name = utorrent.addTorrent(file_or_url, _hash)
|
||||
torrentid = CalculateTorrentHash(file_or_url, data)
|
||||
folder_name = utorrent.addTorrent(file_or_url, torrentid)
|
||||
|
||||
if folder_name:
|
||||
logger.info('Torrent folder name: %s' % folder_name)
|
||||
@@ -733,12 +735,16 @@ def send_to_downloader(data, bestqual, album):
|
||||
# Set Seed Ratio
|
||||
seed_ratio = getSeedRatio(bestqual[3])
|
||||
if seed_ratio != None:
|
||||
utorrent.setSeedRatio(_hash, seed_ratio)
|
||||
utorrent.setSeedRatio(torrentid, seed_ratio)
|
||||
|
||||
myDB = db.DBConnection()
|
||||
myDB.action('UPDATE albums SET status = "Snatched" WHERE AlbumID=?', [album['AlbumID']])
|
||||
myDB.action('INSERT INTO snatched VALUES( ?, ?, ?, ?, DATETIME("NOW", "localtime"), ?, ?, ?)', [album['AlbumID'], bestqual[0], bestqual[1], bestqual[2], "Snatched", folder_name, kind])
|
||||
|
||||
# Store the torrent id so we can check later if it's finished seeding and can be removed
|
||||
if seed_ratio != None and seed_ratio != 0 and torrentid:
|
||||
myDB.action('INSERT INTO snatched VALUES( ?, ?, ?, ?, DATETIME("NOW", "localtime"), ?, ?, ?)', [album['AlbumID'], bestqual[0], bestqual[1], bestqual[2], "Seed_Snatched", torrentid, kind])
|
||||
|
||||
# notify
|
||||
artist = album[1]
|
||||
albumname = album[2]
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
# This file is part of Headphones.
|
||||
#
|
||||
# Headphones is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Headphones is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Headphones. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import threading
|
||||
import headphones
|
||||
from headphones import db, utorrent, transmission, logger
|
||||
|
||||
postprocessor_lock = threading.Lock()
|
||||
|
||||
# Remove Torrent + data if Post Processed and finished Seeding
|
||||
def checkTorrentFinished():
|
||||
|
||||
with postprocessor_lock:
|
||||
|
||||
myDB = db.DBConnection()
|
||||
results = myDB.select('SELECT * from snatched WHERE Status="Seed_Processed"')
|
||||
|
||||
for album in results:
|
||||
hash = album['FolderName']
|
||||
albumid = album['AlbumID']
|
||||
torrent_removed = False
|
||||
if headphones.TORRENT_DOWNLOADER == 1:
|
||||
torrent_removed = transmission.removeTorrent(hash, True)
|
||||
else:
|
||||
torrent_removed = utorrent.removeTorrent(hash, True)
|
||||
|
||||
if torrent_removed:
|
||||
myDB.action('DELETE from snatched WHERE status = "Seed_Processed" and AlbumID=?', [albumid])
|
||||
@@ -47,10 +47,10 @@ def addTorrent(link):
|
||||
if response['result'] == 'success':
|
||||
if 'torrent-added' in response['arguments']:
|
||||
name = response['arguments']['torrent-added']['name']
|
||||
retid = response['arguments']['torrent-added']['id']
|
||||
retid = response['arguments']['torrent-added']['hashString']
|
||||
elif 'torrent-duplicate' in response['arguments']:
|
||||
name = response['arguments']['torrent-duplicate']['name']
|
||||
retid = response['arguments']['torrent-duplicate']['id']
|
||||
retid = response['arguments']['torrent-duplicate']['hashString']
|
||||
else:
|
||||
name = link
|
||||
retid = False
|
||||
@@ -93,6 +93,28 @@ def setSeedRatio(torrentid, ratio):
|
||||
if not response:
|
||||
return False
|
||||
|
||||
def removeTorrent(torrentid, remove_data = False):
|
||||
|
||||
method = 'torrent-get'
|
||||
arguments = { 'ids': torrentid, 'fields': ['isFinished', 'name']}
|
||||
|
||||
response = torrentAction(method, arguments)
|
||||
|
||||
finished = response['arguments']['torrents'][0]['isFinished']
|
||||
name = response['arguments']['torrents'][0]['name']
|
||||
|
||||
if finished:
|
||||
logger.info('%s has finished seeding, removing torrent and data' % name)
|
||||
method = 'torrent-remove'
|
||||
if remove_data:
|
||||
arguments = {'delete-local-data': True, 'ids': torrentid}
|
||||
else:
|
||||
arguments = {'ids': torrentid}
|
||||
response = torrentAction(method, arguments)
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def torrentAction(method, arguments):
|
||||
|
||||
host = headphones.TRANSMISSION_HOST
|
||||
|
||||
@@ -132,6 +132,13 @@ class utorrentclient(object):
|
||||
return settings[key]
|
||||
return settings
|
||||
|
||||
def remove(self, hash, remove_data = False):
|
||||
if remove_data:
|
||||
params = [('action', 'removedata'), ('hash', hash)]
|
||||
else:
|
||||
params = [('action', 'remove'), ('hash', hash)]
|
||||
return self._action(params)
|
||||
|
||||
def _action(self, params, body=None, content_type=None):
|
||||
url = self.base_url + '/gui/' + '?token=' + self.token + '&' + urllib.urlencode(params)
|
||||
request = urllib2.Request(url)
|
||||
@@ -155,6 +162,17 @@ def labelTorrent(hash):
|
||||
if label:
|
||||
uTorrentClient.setprops(hash,'label',label)
|
||||
|
||||
def removeTorrent(hash):
|
||||
uTorrentClient = utorrentclient()
|
||||
status, torrentList = uTorrentClient.list()
|
||||
torrents = torrentList['torrents']
|
||||
for torrent in torrents:
|
||||
if torrent[0].lower() == hash and torrent[21] == 'Finished':
|
||||
logger.info('%s has finished seeding, removing torrent and data' % torrent[2])
|
||||
uTorrentClient.remove(hash, True)
|
||||
return True
|
||||
return False
|
||||
|
||||
def setSeedRatio(hash, ratio):
|
||||
uTorrentClient = utorrentclient()
|
||||
uTorrentClient.setprops(hash, 'seed_override', '1')
|
||||
@@ -215,6 +233,7 @@ def addTorrent(link, hash):
|
||||
|
||||
if torrent_folder == active_dir or not torrent_folder:
|
||||
torrent_folder, cacheid = dirTorrent(hash, cacheid, return_name=True)
|
||||
labelTorrent(hash)
|
||||
return torrent_folder
|
||||
else:
|
||||
labelTorrent(hash)
|
||||
|
||||
@@ -735,7 +735,7 @@ class WebInterface(object):
|
||||
|
||||
def history(self):
|
||||
myDB = db.DBConnection()
|
||||
history = myDB.select('''SELECT * from snatched order by DateAdded DESC''')
|
||||
history = myDB.select('''SELECT * from snatched WHERE Status NOT LIKE "Seed%" order by DateAdded DESC''')
|
||||
return serve_template(templatename="history.html", title="History", history=history)
|
||||
history.exposed = True
|
||||
|
||||
@@ -901,13 +901,13 @@ class WebInterface(object):
|
||||
if type:
|
||||
if type == 'all':
|
||||
logger.info(u"Clearing all history")
|
||||
myDB.action('DELETE from snatched')
|
||||
myDB.action('DELETE from snatched WHERE Status NOT LIKE "Seed%"')
|
||||
else:
|
||||
logger.info(u"Clearing history where status is %s" % type)
|
||||
myDB.action('DELETE from snatched WHERE Status=?', [type])
|
||||
else:
|
||||
logger.info(u"Deleting '%s' from history" % title)
|
||||
myDB.action('DELETE from snatched WHERE Title=? AND DateAdded=?', [title, date_added])
|
||||
myDB.action('DELETE from snatched WHERE Status NOT LIKE "Seed%" AND Title=? AND DateAdded=?', [title, date_added])
|
||||
raise cherrypy.HTTPRedirect("history")
|
||||
clearhistory.exposed = True
|
||||
|
||||
|
||||
Reference in New Issue
Block a user