Merge branch 'develop_seed_fixes' of git://github.com/mano3m/CouchPotatoServer into mano3m-develop_seed_fixes
This commit is contained in:
@@ -47,7 +47,7 @@ config = [{
|
|||||||
{
|
{
|
||||||
'name': 'remove_complete',
|
'name': 'remove_complete',
|
||||||
'label': 'Remove torrent',
|
'label': 'Remove torrent',
|
||||||
'default': False,
|
'default': True,
|
||||||
'advanced': True,
|
'advanced': True,
|
||||||
'type': 'bool',
|
'type': 'bool',
|
||||||
'description': 'Remove the torrent from Transmission after it finished seeding.',
|
'description': 'Remove the torrent from Transmission after it finished seeding.',
|
||||||
|
|||||||
@@ -129,9 +129,9 @@ class Transmission(Downloader):
|
|||||||
|
|
||||||
def pause(self, item, pause = True):
|
def pause(self, item, pause = True):
|
||||||
if pause:
|
if pause:
|
||||||
return self.trpc.stop_torrent(item['hashString'])
|
return self.trpc.stop_torrent(item['id'])
|
||||||
else:
|
else:
|
||||||
return self.trpc.start_torrent(item['hashString'])
|
return self.trpc.start_torrent(item['id'])
|
||||||
|
|
||||||
def removeFailed(self, item):
|
def removeFailed(self, item):
|
||||||
log.info('%s failed downloading, deleting...', item['name'])
|
log.info('%s failed downloading, deleting...', item['name'])
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ config = [{
|
|||||||
{
|
{
|
||||||
'name': 'remove_complete',
|
'name': 'remove_complete',
|
||||||
'label': 'Remove torrent',
|
'label': 'Remove torrent',
|
||||||
'default': False,
|
'default': True,
|
||||||
'advanced': True,
|
'advanced': True,
|
||||||
'type': 'bool',
|
'type': 'bool',
|
||||||
'description': 'Remove the torrent from uTorrent after it finished seeding.',
|
'description': 'Remove the torrent from uTorrent after it finished seeding.',
|
||||||
|
|||||||
@@ -10,7 +10,9 @@ from multipartpost import MultipartPostHandler
|
|||||||
import cookielib
|
import cookielib
|
||||||
import httplib
|
import httplib
|
||||||
import json
|
import json
|
||||||
|
import os
|
||||||
import re
|
import re
|
||||||
|
import stat
|
||||||
import time
|
import time
|
||||||
import urllib
|
import urllib
|
||||||
import urllib2
|
import urllib2
|
||||||
@@ -52,7 +54,7 @@ class uTorrent(Downloader):
|
|||||||
new_settings['seed_prio_limitul_flag'] = True
|
new_settings['seed_prio_limitul_flag'] = True
|
||||||
log.info('Updated uTorrent settings to set a torrent to complete after it the seeding requirements are met.')
|
log.info('Updated uTorrent settings to set a torrent to complete after it the seeding requirements are met.')
|
||||||
|
|
||||||
if settings.get('bt.read_only_on_complete'): #This doesnt work as this option seems to be not available through the api
|
if settings.get('bt.read_only_on_complete'): #This doesn't work as this option seems to be not available through the api. Mitigated with removeReadOnly function
|
||||||
new_settings['bt.read_only_on_complete'] = False
|
new_settings['bt.read_only_on_complete'] = False
|
||||||
log.info('Updated uTorrent settings to not set the files to read only after completing.')
|
log.info('Updated uTorrent settings to not set the files to read only after completing.')
|
||||||
|
|
||||||
@@ -93,7 +95,7 @@ class uTorrent(Downloader):
|
|||||||
else:
|
else:
|
||||||
self.utorrent_api.add_torrent_file(torrent_filename, filedata)
|
self.utorrent_api.add_torrent_file(torrent_filename, filedata)
|
||||||
|
|
||||||
# Change settings of added torrents
|
# Change settings of added torrent
|
||||||
self.utorrent_api.set_torrent(torrent_hash, torrent_params)
|
self.utorrent_api.set_torrent(torrent_hash, torrent_params)
|
||||||
if self.conf('paused', default = 0):
|
if self.conf('paused', default = 0):
|
||||||
self.utorrent_api.pause_torrent(torrent_hash)
|
self.utorrent_api.pause_torrent(torrent_hash)
|
||||||
@@ -130,8 +132,10 @@ class uTorrent(Downloader):
|
|||||||
status = 'busy'
|
status = 'busy'
|
||||||
if 'Finished' in item[21]:
|
if 'Finished' in item[21]:
|
||||||
status = 'completed'
|
status = 'completed'
|
||||||
|
self.removeReadOnly(item[26])
|
||||||
elif 'Seeding' in item[21]:
|
elif 'Seeding' in item[21]:
|
||||||
status = 'seeding'
|
status = 'seeding'
|
||||||
|
self.removeReadOnly(item[26])
|
||||||
|
|
||||||
statuses.append({
|
statuses.append({
|
||||||
'id': item[0],
|
'id': item[0],
|
||||||
@@ -145,10 +149,10 @@ class uTorrent(Downloader):
|
|||||||
|
|
||||||
return statuses
|
return statuses
|
||||||
|
|
||||||
def pause(self, download_info, pause = True):
|
def pause(self, item, pause = True):
|
||||||
if not self.connect():
|
if not self.connect():
|
||||||
return False
|
return False
|
||||||
return self.utorrent_api.pause_torrent(download_info['id'], pause)
|
return self.utorrent_api.pause_torrent(item['id'], pause)
|
||||||
|
|
||||||
def removeFailed(self, item):
|
def removeFailed(self, item):
|
||||||
log.info('%s failed downloading, deleting...', item['name'])
|
log.info('%s failed downloading, deleting...', item['name'])
|
||||||
@@ -161,6 +165,13 @@ class uTorrent(Downloader):
|
|||||||
if not self.connect():
|
if not self.connect():
|
||||||
return False
|
return False
|
||||||
return self.utorrent_api.remove_torrent(item['id'], remove_data = delete_files)
|
return self.utorrent_api.remove_torrent(item['id'], remove_data = delete_files)
|
||||||
|
|
||||||
|
def removeReadOnly(self, folder):
|
||||||
|
#Removes all read-only flags in a folder
|
||||||
|
if folder and os.path.isdir(folder):
|
||||||
|
for root, folders, filenames in os.walk(folder):
|
||||||
|
for filename in filenames:
|
||||||
|
os.chmod(os.path.join(root, filename), stat.S_IWRITE)
|
||||||
|
|
||||||
class uTorrentAPI(object):
|
class uTorrentAPI(object):
|
||||||
|
|
||||||
|
|||||||
@@ -140,7 +140,11 @@ def tryInt(s):
|
|||||||
except: return 0
|
except: return 0
|
||||||
|
|
||||||
def tryFloat(s):
|
def tryFloat(s):
|
||||||
try: return float(s) if '.' in s else tryInt(s)
|
try:
|
||||||
|
if isinstance(s, str):
|
||||||
|
return float(s) if '.' in s else tryInt(s)
|
||||||
|
else:
|
||||||
|
return float(s)
|
||||||
except: return 0
|
except: return 0
|
||||||
|
|
||||||
def natsortKey(s):
|
def natsortKey(s):
|
||||||
|
|||||||
@@ -213,7 +213,7 @@ class Renamer(Plugin):
|
|||||||
# Move nfo depending on settings
|
# Move nfo depending on settings
|
||||||
if file_type is 'nfo' and not self.conf('rename_nfo'):
|
if file_type is 'nfo' and not self.conf('rename_nfo'):
|
||||||
log.debug('Skipping, renaming of %s disabled', file_type)
|
log.debug('Skipping, renaming of %s disabled', file_type)
|
||||||
if self.conf('cleanup') and not (self.conf('file_action') != 'move' and self.downloadIsTorrent(download_info)):
|
if self.conf('cleanup') and not self.downloadIsTorrent(download_info):
|
||||||
for current_file in group['files'][file_type]:
|
for current_file in group['files'][file_type]:
|
||||||
remove_files.append(current_file)
|
remove_files.append(current_file)
|
||||||
continue
|
continue
|
||||||
@@ -395,7 +395,7 @@ class Renamer(Plugin):
|
|||||||
|
|
||||||
# Remove leftover files
|
# Remove leftover files
|
||||||
if self.conf('cleanup') and not self.conf('move_leftover') and remove_leftovers and \
|
if self.conf('cleanup') and not self.conf('move_leftover') and remove_leftovers and \
|
||||||
not (self.conf('file_action') != 'move' and self.downloadIsTorrent(download_info)):
|
not self.downloadIsTorrent(download_info):
|
||||||
log.debug('Removing leftover files')
|
log.debug('Removing leftover files')
|
||||||
for current_file in group['files']['leftover']:
|
for current_file in group['files']['leftover']:
|
||||||
remove_files.append(current_file)
|
remove_files.append(current_file)
|
||||||
@@ -452,8 +452,7 @@ class Renamer(Plugin):
|
|||||||
self.tagDir(group, 'failed_rename')
|
self.tagDir(group, 'failed_rename')
|
||||||
|
|
||||||
# Tag folder if it is in the 'from' folder and it will not be removed because it is a torrent
|
# Tag folder if it is in the 'from' folder and it will not be removed because it is a torrent
|
||||||
if self.movieInFromFolder(movie_folder) and \
|
if self.movieInFromFolder(movie_folder) and self.downloadIsTorrent(download_info):
|
||||||
self.conf('file_action') != 'move' and self.downloadIsTorrent(download_info):
|
|
||||||
self.tagDir(group, 'renamed_already')
|
self.tagDir(group, 'renamed_already')
|
||||||
|
|
||||||
# Remove matching releases
|
# Remove matching releases
|
||||||
@@ -464,8 +463,7 @@ class Renamer(Plugin):
|
|||||||
except:
|
except:
|
||||||
log.error('Failed removing %s: %s', (release.identifier, traceback.format_exc()))
|
log.error('Failed removing %s: %s', (release.identifier, traceback.format_exc()))
|
||||||
|
|
||||||
if group['dirname'] and group['parentdir'] and \
|
if group['dirname'] and group['parentdir'] and not self.downloadIsTorrent(download_info):
|
||||||
not (self.conf('file_action') != 'move' and self.downloadIsTorrent(download_info)):
|
|
||||||
try:
|
try:
|
||||||
log.info('Deleting folder: %s', group['parentdir'])
|
log.info('Deleting folder: %s', group['parentdir'])
|
||||||
self.deleteEmptyFolder(group['parentdir'])
|
self.deleteEmptyFolder(group['parentdir'])
|
||||||
@@ -525,22 +523,22 @@ Remove it if you want it to be renamed (again, or at least let it try again)
|
|||||||
if ignore_file:
|
if ignore_file:
|
||||||
self.createFile(ignore_file, text)
|
self.createFile(ignore_file, text)
|
||||||
|
|
||||||
def untagDir(self, folder, tag = None):
|
def untagDir(self, folder, tag = ''):
|
||||||
if not os.path.isdir(folder):
|
if not os.path.isdir(folder):
|
||||||
return
|
return
|
||||||
|
|
||||||
# Remove any .ignore files
|
# Remove any .ignore files
|
||||||
for root, dirnames, filenames in os.walk(folder):
|
for root, dirnames, filenames in os.walk(folder):
|
||||||
for filename in fnmatch.filter(filenames, '%s.ignore' % tag if tag else '*'):
|
for filename in fnmatch.filter(filenames, '*%s.ignore' % tag):
|
||||||
os.remove((os.path.join(root, filename)))
|
os.remove((os.path.join(root, filename)))
|
||||||
|
|
||||||
def hastagDir(self, folder, tag = None):
|
def hastagDir(self, folder, tag = ''):
|
||||||
if not os.path.isdir(folder):
|
if not os.path.isdir(folder):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# Find any .ignore files
|
# Find any .ignore files
|
||||||
for root, dirnames, filenames in os.walk(folder):
|
for root, dirnames, filenames in os.walk(folder):
|
||||||
if fnmatch.filter(filenames, '%s.ignore' % tag if tag else '*'):
|
if fnmatch.filter(filenames, '*%s.ignore' % tag):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
return False
|
return False
|
||||||
@@ -560,7 +558,11 @@ Remove it if you want it to be renamed (again, or at least let it try again)
|
|||||||
shutil.copy(old, dest)
|
shutil.copy(old, dest)
|
||||||
elif self.conf('file_action') == 'move_symlink':
|
elif self.conf('file_action') == 'move_symlink':
|
||||||
shutil.move(old, dest)
|
shutil.move(old, dest)
|
||||||
symlink(dest, old)
|
try:
|
||||||
|
symlink(dest, old)
|
||||||
|
except:
|
||||||
|
log.error('Couldn\'t symlink file "%s" to "%s". Copying the file back. Error: %s. ', (old, dest, traceback.format_exc()))
|
||||||
|
shutil.copy(dest, old)
|
||||||
else:
|
else:
|
||||||
shutil.move(old, dest)
|
shutil.move(old, dest)
|
||||||
|
|
||||||
|
|||||||
@@ -329,14 +329,17 @@ class Scanner(Plugin):
|
|||||||
|
|
||||||
del movie_files
|
del movie_files
|
||||||
|
|
||||||
|
total_found = len(valid_files)
|
||||||
|
|
||||||
# Make sure only one movie was found if a download ID is provided
|
# Make sure only one movie was found if a download ID is provided
|
||||||
if download_info and not len(valid_files) == 1:
|
if download_info and total_found == 0:
|
||||||
|
log.info('Download ID provided (%s), but no groups found! Make sure the download contains valid media files (fully extracted).', download_info.get('imdb_id'))
|
||||||
|
elif download_info and total_found > 1:
|
||||||
log.info('Download ID provided (%s), but more than one group found (%s). Ignoring Download ID...', (download_info.get('imdb_id'), len(valid_files)))
|
log.info('Download ID provided (%s), but more than one group found (%s). Ignoring Download ID...', (download_info.get('imdb_id'), len(valid_files)))
|
||||||
download_info = None
|
download_info = None
|
||||||
|
|
||||||
# Determine file types
|
# Determine file types
|
||||||
processed_movies = {}
|
processed_movies = {}
|
||||||
total_found = len(valid_files)
|
|
||||||
while True and not self.shuttingDown():
|
while True and not self.shuttingDown():
|
||||||
try:
|
try:
|
||||||
identifier, group = valid_files.popitem()
|
identifier, group = valid_files.popitem()
|
||||||
|
|||||||
Reference in New Issue
Block a user