Merge remote-tracking branch 'origin/develop'

This commit is contained in:
Pieter Janssens
2014-08-14 13:45:54 +02:00
16 changed files with 569 additions and 153 deletions
+1 -1
View File
@@ -128,7 +128,7 @@
%if album['Status'] == 'Skipped' or album['Status'] == 'Ignored': %if album['Status'] == 'Skipped' or album['Status'] == 'Ignored':
[<a href="#" onclick="doAjaxCall('queueAlbum?AlbumID=${album['AlbumID']}&ArtistID=${album['ArtistID']}',$(this),'table')" data-success="'${album['AlbumTitle']}' added to Wanted list">want</a>] [<a href="#" onclick="doAjaxCall('queueAlbum?AlbumID=${album['AlbumID']}&ArtistID=${album['ArtistID']}',$(this),'table')" data-success="'${album['AlbumTitle']}' added to Wanted list">want</a>]
%elif (album['Status'] == 'Wanted' or album['Status'] == 'Wanted Lossless'): %elif (album['Status'] == 'Wanted' or album['Status'] == 'Wanted Lossless'):
[<a href="#" onclick="doAjaxCall('unqueueAlbum?AlbumID=${album['AlbumID']}&ArtistID=${album['ArtistID']}',$(this),'table')" data-success="'${album['AlbumTitle']}' skipped">skip</a>] [<a href="#" onclick="doAjaxCall('unqueueAlbum?AlbumID=${album['AlbumID']}&ArtistID=${album['ArtistID']}',$(this),'table')" data-success="'${album['AlbumTitle']}' skipped">skip</a>] [<a href="#" onclick="doAjaxCall('queueAlbum?AlbumID=${album['AlbumID']}&ArtistID=${album['ArtistID']}', $(this),'table')" data-success="Trying to download'${album['AlbumTitle']}'" title="Search if available for download">search</a>]
%else: %else:
[<a href="#" onclick="doAjaxCall('queueAlbum?AlbumID=${album['AlbumID']}&ArtistID=${album['ArtistID']}', $(this),'table')" data-success="Retrying the same version of '${album['AlbumTitle']}'" title="Retry the same download again">retry</a>][<a href="#" onclick="doAjaxCall('queueAlbum?AlbumID=${album['AlbumID']}&ArtistID=${album['ArtistID']}&new=True', $(this),'table')" title="Try a new download, skipping all previously tried nzbs" data-success="Downloading new version for '${album['AlbumTitle']}'" data-success="Looking for a new version of '${album['AlbumTitle']}'">new</a>] [<a href="#" onclick="doAjaxCall('queueAlbum?AlbumID=${album['AlbumID']}&ArtistID=${album['ArtistID']}', $(this),'table')" data-success="Retrying the same version of '${album['AlbumTitle']}'" title="Retry the same download again">retry</a>][<a href="#" onclick="doAjaxCall('queueAlbum?AlbumID=${album['AlbumID']}&ArtistID=${album['ArtistID']}&new=True', $(this),'table')" title="Try a new download, skipping all previously tried nzbs" data-success="Downloading new version for '${album['AlbumTitle']}'" data-success="Looking for a new version of '${album['AlbumTitle']}'">new</a>]
%endif %endif
+168 -53
View File
@@ -168,6 +168,68 @@
<label>NZBget Category:</label> <label>NZBget Category:</label>
<input type="text" name="nzbget_category" value="${config['nzbget_cat']}" size="20"> <input type="text" name="nzbget_category" value="${config['nzbget_cat']}" size="20">
</div> </div>
<%
if config['nzbget_priority'] == -100:
prio_verylow = 'selected="selected"'
prio_low = ''
prio_normal = ''
prio_high = ''
prio_veryhigh = ''
prio_force = ''
elif config['nzbget_priority'] == -50:
prio_verylow = ''
prio_low = 'selected="selected"'
prio_normal = ''
prio_high = ''
prio_veryhigh = ''
prio_force = ''
elif config['nzbget_priority'] == 0:
prio_verylow = ''
prio_low = ''
prio_normal = 'selected="selected"'
prio_high = ''
prio_veryhigh = ''
prio_force = ''
elif config['nzbget_priority'] == 50:
prio_verylow = ''
prio_low = ''
prio_normal = ''
prio_high = 'selected="selected"'
prio_veryhigh = ''
prio_force = ''
elif config['nzbget_priority'] == 100:
prio_verylow = ''
prio_low = ''
prio_normal = ''
prio_high = ''
prio_veryhigh = 'selected="selected"'
prio_force = ''
elif config['nzbget_priority'] == 900:
prio_verylow = ''
prio_low = ''
prio_normal = ''
prio_high = ''
prio_veryhigh = ''
prio_force = 'selected="selected"'
else:
prio_verylow = ''
prio_low = ''
prio_normal = 'selected="selected"'
prio_high = ''
prio_veryhigh = ''
prio_force = ''
%>
<div class="row">
<label>NZBget Priority:</label>
<select name="nzbget_priority" id="nzbget_priority">
<option value="-100" ${prio_verylow}>Very Low</option>
<option value="-50" ${prio_low}>Low</option>
<option value="0" ${prio_normal}>Normal</option>
<option value="50" ${prio_high}>High</option>
<option value="100" ${prio_veryhigh}>Very High</option>
<option value="900" ${prio_force}>Force</option>
</select>
</div>
</fieldset> </fieldset>
<fieldset id="blackhole_options"> <fieldset id="blackhole_options">
@@ -382,66 +444,117 @@
<td> <td>
<fieldset> <fieldset>
<legend>Torrents</legend> <legend>Torrents</legend>
<div class="row checkbox">
<input id="usepiratebay" type="checkbox" name="use_piratebay" value="1" ${config['use_piratebay']} /><label>The Pirate Bay</label> <fieldset>
</div> <legend>The Pirate Bay</legend>
<div class="config"> <div class="row checkbox">
<div class="row"> <input id="usepiratebay" type="checkbox" name="use_piratebay" value="1" ${config['use_piratebay']} /><label>Use The Pirate Bay</label>
<label>Proxy URL (Optional): </label>
<input type="text" name="piratebay_proxy_url" value="${config['piratebay_proxy_url']}" size="36">
</div> </div>
</div> <div class="config">
<div class="row checkbox"> <div class="row">
<input type="checkbox" name="use_mininova" value="1" ${config['use_mininova']} /><label>Mininova</label> <label>Proxy URL (Optional): </label>
</div> <input type="text" name="piratebay_proxy_url" value="${config['piratebay_proxy_url']}" size="36">
<div class="row checkbox"> </div>
<input id="usekat" type="checkbox" name="use_kat" value="1" ${config['use_kat']} /><label>Kick Ass Torrents</label> <div class="row">
</div> <label>Seed Ratio: </label>
<div class="config"> <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 class="row"> </div>
<label>Proxy URL (Optional): </label>
<input type="text" name="kat_proxy_url" value="${config['kat_proxy_url']}" size="36">
</div> </div>
</div> </fieldset>
<div class="row checkbox">
<input id="usewaffles" type="checkbox" name="waffles" onclick="initConfigCheckbox($(this));" value="1" ${config['use_waffles']} /><label>Waffles.fm</label> <fieldset>
</div> <legend>Kick Ass Torrents</legend>
<div class="config"> <div class="row checkbox">
<div class="row"> <input id="usekat" type="checkbox" name="use_kat" value="1" ${config['use_kat']} /><label>Use Kick Ass Torrents</label>
<label>Waffles UID Number: </label>
<input type="text" name="waffles_uid" value="${config['waffles_uid']}" size="36">
</div> </div>
<div class="row"> <div class="config">
<label>Waffles Passkey: </label> <div class="row">
<input type="password" name="waffles_passkey" value="${config['waffles_passkey']}" size="36"> <label>Proxy URL (Optional): </label>
<input type="text" name="kat_proxy_url" value="${config['kat_proxy_url']}" size="36">
</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. Scheduled job will remove torrent when post processed and finished seeding">
</div>
</div> </div>
</div> </fieldset>
<div class="row checkbox">
<input id="userutracker" type="checkbox" name="rutracker" onclick="initConfigCheckbox($(this));" value="1" ${config['use_rutracker']} /><label>rutracker.org</label> <fieldset>
</div> <legend>Waffles.fm</legend>
<div class="config"> <div class="row checkbox">
<div class="row"> <input id="usewaffles" type="checkbox" name="waffles" onclick="initConfigCheckbox($(this));" value="1" ${config['use_waffles']} /><label>Use Waffles.fm</label>
<label>rutracker User Name: </label>
<input type="text" name="rutracker_user" value="${config['rutracker_user']}" size="36">
</div> </div>
<div class="row"> <div class="config">
<label>rutracker Password: </label> <div class="row">
<input type="password" name="rutracker_password" value="${config['rutracker_password']}" size="36"> <label>UID Number: </label>
<input type="text" name="waffles_uid" value="${config['waffles_uid']}" size="36">
</div>
<div class="row">
<label>Passkey: </label>
<input type="password" name="waffles_passkey" value="${config['waffles_passkey']}" size="36">
</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. Scheduled job will remove torrent when post processed and finished seeding">
</div>
</div> </div>
</div> </fieldset>
<div class="row checkbox">
<input id="usewhatcd" type="checkbox" name="whatcd" onclick="initConfigCheckbox($(this));" value="1" ${config['use_whatcd']} /><label>What.cd</label> <fieldset>
</div> <legend>rutracker.org</legend>
<div class="config"> <div class="row checkbox">
<div class="row"> <input id="userutracker" type="checkbox" name="rutracker" onclick="initConfigCheckbox($(this));" value="1" ${config['use_rutracker']} /><label>Use rutracker.org</label>
<label>What.cd Username: </label>
<input type="text" name="whatcd_username" value="${config['whatcd_username']}" size="36">
</div> </div>
<div class="row"> <div class="config">
<label>What.cd Password: </label> <div class="row">
<input type="password" name="whatcd_password" value="${config['whatcd_password']}" size="36"> <label>User Name: </label>
<input type="text" name="rutracker_user" value="${config['rutracker_user']}" size="36">
</div>
<div class="row">
<label>Password: </label>
<input type="password" name="rutracker_password" value="${config['rutracker_password']}" size="36">
</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. Scheduled job will remove torrent when post processed and finished seeding">
</div>
</div> </div>
</div> </fieldset>
<fieldset>
<legend>What.cd</legend>
<div class="row checkbox">
<input id="usewhatcd" type="checkbox" name="whatcd" onclick="initConfigCheckbox($(this));" value="1" ${config['use_whatcd']} /><label>Use What.cd</label>
</div>
<div class="config">
<div class="row">
<label>Username: </label>
<input type="text" name="whatcd_username" value="${config['whatcd_username']}" size="36">
</div>
<div class="row">
<label>Password: </label>
<input type="password" name="whatcd_password" value="${config['whatcd_password']}" size="36">
</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. Scheduled job will remove torrent when post processed and finished seeding">
</div>
</div>
</fieldset>
<fieldset>
<legend>Mininova</legend>
<div class="row checkbox">
<input id="usemininova" type="checkbox" name="use_mininova" value="1" ${config['use_mininova']} /><label>Use Mininova</label>
</div>
<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. Scheduled job will remove torrent when post processed and finished seeding">
</div>
</div>
</fieldset>
</fieldset> </fieldset>
</td> </td>
</tr> </tr>
@@ -514,6 +627,7 @@
<input type="checkbox" name="rename_files" value="1" ${config['rename_files']} /><label>Rename files</label> <input type="checkbox" name="rename_files" value="1" ${config['rename_files']} /><label>Rename files</label>
<input type="checkbox" name="correct_metadata" value="1" ${config['correct_metadata']} /><label>Correct metadata</label> <input type="checkbox" name="correct_metadata" value="1" ${config['correct_metadata']} /><label>Correct metadata</label>
<input type="checkbox" name="cleanup_files" value="1" ${config['cleanup_files']} /><label>Delete leftover files <small>(.m3u, .nfo, .sfv, .nzb, etc.)</small></label> <input type="checkbox" name="cleanup_files" value="1" ${config['cleanup_files']} /><label>Delete leftover files <small>(.m3u, .nfo, .sfv, .nzb, etc.)</small></label>
<input type="checkbox" name="keep_nfo" value="1" ${config['keep_nfo']} /><label>Keep original nfo <small>(extension changed to .orig.nfo)</small></label>
<input type="checkbox" name="add_album_art" id="add_album_art" value="1" ${config['add_album_art']}><label>Add album art jpeg to album folder</label> <input type="checkbox" name="add_album_art" id="add_album_art" value="1" ${config['add_album_art']}><label>Add album art jpeg to album folder</label>
<div id="album_art_options"> <div id="album_art_options">
<div class="row"> <div class="row">
@@ -834,7 +948,7 @@
<div class="row"> <div class="row">
<label>Folder Format</label> <label>Folder Format</label>
<input type="text" name="folder_format" value="${config['folder_format']}" size="43"> <input type="text" name="folder_format" value="${config['folder_format']}" size="43">
<small>Use: $Artist/$artist, $Album/$album, $Year/$year, $Type/$type (release type) and $First/$first (first letter in artist name) <small>Use: $Artist/$artist, $Album/$album, $Year/$year, $Type/$type (release type) and $First/$first (first letter in artist name), $OriginalFolder/$originalfolder (downloaded directory name)
E.g.: $Type/$First/$artist/$album [$year] = Album/G/girl talk/all day [2010]</small> E.g.: $Type/$First/$artist/$album [$year] = Album/G/girl talk/all day [2010]</small>
</div> </div>
@@ -1744,6 +1858,7 @@
initConfigCheckbox("#useomgwtfnzbs"); initConfigCheckbox("#useomgwtfnzbs");
initConfigCheckbox("#usekat"); initConfigCheckbox("#usekat");
initConfigCheckbox("#usepiratebay"); initConfigCheckbox("#usepiratebay");
initConfigCheckbox("#usemininova");
initConfigCheckbox("#usewaffles"); initConfigCheckbox("#usewaffles");
initConfigCheckbox("#userutracker"); initConfigCheckbox("#userutracker");
initConfigCheckbox("#usewhatcd"); initConfigCheckbox("#usewhatcd");
+54 -15
View File
@@ -111,6 +111,7 @@ CORRECT_METADATA = False
MOVE_FILES = False MOVE_FILES = False
RENAME_FILES = False RENAME_FILES = False
CLEANUP_FILES = False CLEANUP_FILES = False
KEEP_NFO = False
ADD_ALBUM_ART = False ADD_ALBUM_ART = False
ALBUM_ART_FORMAT = None ALBUM_ART_FORMAT = None
EMBED_ALBUM_ART = False EMBED_ALBUM_ART = False
@@ -147,6 +148,7 @@ NZBGET_USERNAME = None
NZBGET_PASSWORD = None NZBGET_PASSWORD = None
NZBGET_CATEGORY = None NZBGET_CATEGORY = None
NZBGET_HOST = None NZBGET_HOST = None
NZBGET_PRIORITY = 0
HEADPHONES_INDEXER = False HEADPHONES_INDEXER = False
@@ -189,18 +191,24 @@ TORRENTBLACKHOLE_DIR = None
NUMBEROFSEEDERS = 10 NUMBEROFSEEDERS = 10
KAT = None KAT = None
KAT_PROXY_URL = None KAT_PROXY_URL = None
KAT_RATIO = None
MININOVA = None MININOVA = None
MININOVA_RATIO = None
PIRATEBAY = None PIRATEBAY = None
PIRATEBAY_PROXY_URL = None PIRATEBAY_PROXY_URL = None
PIRATEBAY_RATIO = None
WAFFLES = None WAFFLES = None
WAFFLES_UID = None WAFFLES_UID = None
WAFFLES_PASSKEY = None WAFFLES_PASSKEY = None
WAFFLES_RATIO = None
RUTRACKER = None RUTRACKER = None
RUTRACKER_USER = None RUTRACKER_USER = None
RUTRACKER_PASSWORD = None RUTRACKER_PASSWORD = None
RUTRACKER_RATIO = None
WHATCD = None WHATCD = None
WHATCD_USERNAME = None WHATCD_USERNAME = None
WHATCD_PASSWORD = None WHATCD_PASSWORD = None
WHATCD_RATIO = None
DOWNLOAD_TORRENT_DIR = None DOWNLOAD_TORRENT_DIR = None
INTERFACE = None INTERFACE = None
@@ -343,12 +351,12 @@ def initialize():
HTTP_PORT, HTTP_HOST, HTTP_USERNAME, HTTP_PASSWORD, HTTP_ROOT, HTTP_PROXY, LAUNCH_BROWSER, API_ENABLED, API_KEY, GIT_PATH, GIT_USER, GIT_BRANCH, DO_NOT_OVERRIDE_GIT_BRANCH, \ HTTP_PORT, HTTP_HOST, HTTP_USERNAME, HTTP_PASSWORD, HTTP_ROOT, HTTP_PROXY, LAUNCH_BROWSER, API_ENABLED, API_KEY, GIT_PATH, GIT_USER, GIT_BRANCH, DO_NOT_OVERRIDE_GIT_BRANCH, \
CURRENT_VERSION, LATEST_VERSION, CHECK_GITHUB, CHECK_GITHUB_ON_STARTUP, CHECK_GITHUB_INTERVAL, MUSIC_DIR, DESTINATION_DIR, \ CURRENT_VERSION, LATEST_VERSION, CHECK_GITHUB, CHECK_GITHUB_ON_STARTUP, CHECK_GITHUB_INTERVAL, MUSIC_DIR, DESTINATION_DIR, \
LOSSLESS_DESTINATION_DIR, PREFERRED_QUALITY, PREFERRED_BITRATE, DETECT_BITRATE, ADD_ARTISTS, CORRECT_METADATA, MOVE_FILES, \ LOSSLESS_DESTINATION_DIR, PREFERRED_QUALITY, PREFERRED_BITRATE, DETECT_BITRATE, ADD_ARTISTS, CORRECT_METADATA, MOVE_FILES, \
RENAME_FILES, FOLDER_FORMAT, FILE_FORMAT, FILE_UNDERSCORES, CLEANUP_FILES, INCLUDE_EXTRAS, EXTRAS, AUTOWANT_UPCOMING, AUTOWANT_ALL, KEEP_TORRENT_FILES, PREFER_TORRENTS, OPEN_MAGNET_LINKS, \ RENAME_FILES, FOLDER_FORMAT, FILE_FORMAT, FILE_UNDERSCORES, CLEANUP_FILES, KEEP_NFO, INCLUDE_EXTRAS, EXTRAS, AUTOWANT_UPCOMING, AUTOWANT_ALL, KEEP_TORRENT_FILES, PREFER_TORRENTS, OPEN_MAGNET_LINKS, \
ADD_ALBUM_ART, ALBUM_ART_FORMAT, EMBED_ALBUM_ART, EMBED_LYRICS, REPLACE_EXISTING_FOLDERS, DOWNLOAD_DIR, BLACKHOLE, BLACKHOLE_DIR, USENET_RETENTION, SEARCH_INTERVAL, \ ADD_ALBUM_ART, ALBUM_ART_FORMAT, EMBED_ALBUM_ART, EMBED_LYRICS, REPLACE_EXISTING_FOLDERS, DOWNLOAD_DIR, BLACKHOLE, BLACKHOLE_DIR, USENET_RETENTION, SEARCH_INTERVAL, \
TORRENTBLACKHOLE_DIR, NUMBEROFSEEDERS, KAT, KAT_PROXY_URL, PIRATEBAY, PIRATEBAY_PROXY_URL, MININOVA, WAFFLES, WAFFLES_UID, WAFFLES_PASSKEY, \ TORRENTBLACKHOLE_DIR, NUMBEROFSEEDERS, KAT, KAT_PROXY_URL, KAT_RATIO, PIRATEBAY, PIRATEBAY_PROXY_URL, PIRATEBAY_RATIO, MININOVA, MININOVA_RATIO, WAFFLES, WAFFLES_UID, WAFFLES_PASSKEY, WAFFLES_RATIO, \
RUTRACKER, RUTRACKER_USER, RUTRACKER_PASSWORD, WHATCD, WHATCD_USERNAME, WHATCD_PASSWORD, DOWNLOAD_TORRENT_DIR, \ RUTRACKER, RUTRACKER_USER, RUTRACKER_PASSWORD, RUTRACKER_RATIO, WHATCD, WHATCD_USERNAME, WHATCD_PASSWORD, WHATCD_RATIO, DOWNLOAD_TORRENT_DIR, \
LIBRARYSCAN, LIBRARYSCAN_INTERVAL, DOWNLOAD_SCAN_INTERVAL, UPDATE_DB_INTERVAL, MB_IGNORE_AGE, SAB_HOST, SAB_USERNAME, SAB_PASSWORD, SAB_APIKEY, SAB_CATEGORY, \ LIBRARYSCAN, LIBRARYSCAN_INTERVAL, DOWNLOAD_SCAN_INTERVAL, UPDATE_DB_INTERVAL, MB_IGNORE_AGE, SAB_HOST, SAB_USERNAME, SAB_PASSWORD, SAB_APIKEY, SAB_CATEGORY, \
NZBGET_USERNAME, NZBGET_PASSWORD, NZBGET_CATEGORY, NZBGET_HOST, HEADPHONES_INDEXER, NZBMATRIX, TRANSMISSION_HOST, TRANSMISSION_USERNAME, TRANSMISSION_PASSWORD, \ NZBGET_USERNAME, NZBGET_PASSWORD, NZBGET_CATEGORY, NZBGET_PRIORITY, NZBGET_HOST, HEADPHONES_INDEXER, NZBMATRIX, TRANSMISSION_HOST, TRANSMISSION_USERNAME, TRANSMISSION_PASSWORD, \
UTORRENT_HOST, UTORRENT_USERNAME, UTORRENT_PASSWORD, UTORRENT_LABEL, NEWZNAB, NEWZNAB_HOST, NEWZNAB_APIKEY, NEWZNAB_ENABLED, EXTRA_NEWZNABS, \ UTORRENT_HOST, UTORRENT_USERNAME, UTORRENT_PASSWORD, UTORRENT_LABEL, NEWZNAB, NEWZNAB_HOST, NEWZNAB_APIKEY, NEWZNAB_ENABLED, EXTRA_NEWZNABS, \
NZBSORG, NZBSORG_UID, NZBSORG_HASH, OMGWTFNZBS, OMGWTFNZBS_UID, OMGWTFNZBS_APIKEY, \ NZBSORG, NZBSORG_UID, NZBSORG_HASH, OMGWTFNZBS, OMGWTFNZBS_UID, OMGWTFNZBS_APIKEY, \
NZB_DOWNLOADER, TORRENT_DOWNLOADER, PREFERRED_WORDS, REQUIRED_WORDS, IGNORED_WORDS, LASTFM_USERNAME, \ NZB_DOWNLOADER, TORRENT_DOWNLOADER, PREFERRED_WORDS, REQUIRED_WORDS, IGNORED_WORDS, LASTFM_USERNAME, \
@@ -377,6 +385,9 @@ def initialize():
CheckSection('Newznab') CheckSection('Newznab')
CheckSection('NZBsorg') CheckSection('NZBsorg')
CheckSection('omgwtfnzbs') CheckSection('omgwtfnzbs')
CheckSection('Piratebay')
CheckSection('Kat')
CheckSection('Mininova')
CheckSection('Waffles') CheckSection('Waffles')
CheckSection('Rutracker') CheckSection('Rutracker')
CheckSection('What.cd') CheckSection('What.cd')
@@ -448,6 +459,7 @@ def initialize():
FILE_FORMAT = check_setting_str(CFG, 'General', 'file_format', 'Track Artist - Album [Year] - Title') FILE_FORMAT = check_setting_str(CFG, 'General', 'file_format', 'Track Artist - Album [Year] - Title')
FILE_UNDERSCORES = bool(check_setting_int(CFG, 'General', 'file_underscores', 0)) FILE_UNDERSCORES = bool(check_setting_int(CFG, 'General', 'file_underscores', 0))
CLEANUP_FILES = bool(check_setting_int(CFG, 'General', 'cleanup_files', 0)) CLEANUP_FILES = bool(check_setting_int(CFG, 'General', 'cleanup_files', 0))
KEEP_NFO = bool(check_setting_int(CFG, 'General', 'keep_nfo', 0))
ADD_ALBUM_ART = bool(check_setting_int(CFG, 'General', 'add_album_art', 0)) ADD_ALBUM_ART = bool(check_setting_int(CFG, 'General', 'add_album_art', 0))
ALBUM_ART_FORMAT = check_setting_str(CFG, 'General', 'album_art_format', 'folder') ALBUM_ART_FORMAT = check_setting_str(CFG, 'General', 'album_art_format', 'folder')
EMBED_ALBUM_ART = bool(check_setting_int(CFG, 'General', 'embed_album_art', 0)) EMBED_ALBUM_ART = bool(check_setting_int(CFG, 'General', 'embed_album_art', 0))
@@ -476,24 +488,33 @@ def initialize():
TORRENTBLACKHOLE_DIR = check_setting_str(CFG, 'General', 'torrentblackhole_dir', '') TORRENTBLACKHOLE_DIR = check_setting_str(CFG, 'General', 'torrentblackhole_dir', '')
NUMBEROFSEEDERS = check_setting_str(CFG, 'General', 'numberofseeders', '10') NUMBEROFSEEDERS = check_setting_str(CFG, 'General', 'numberofseeders', '10')
KAT = bool(check_setting_int(CFG, 'General', 'kat', 0))
KAT_PROXY_URL = check_setting_str(CFG, 'General', 'kat_proxy_url', '')
PIRATEBAY = bool(check_setting_int(CFG, 'General', 'piratebay', 0))
PIRATEBAY_PROXY_URL = check_setting_str(CFG, 'General', 'piratebay_proxy_url', '')
MININOVA = bool(check_setting_int(CFG, 'General', 'mininova', 0))
DOWNLOAD_TORRENT_DIR = check_setting_str(CFG, 'General', 'download_torrent_dir', '') DOWNLOAD_TORRENT_DIR = check_setting_str(CFG, 'General', 'download_torrent_dir', '')
KAT = bool(check_setting_int(CFG, 'Kat', 'kat', 0))
KAT_PROXY_URL = check_setting_str(CFG, 'Kat', 'kat_proxy_url', '')
KAT_RATIO = check_setting_str(CFG, 'Kat', 'kat_ratio', '')
PIRATEBAY = bool(check_setting_int(CFG, 'Piratebay', 'piratebay', 0))
PIRATEBAY_PROXY_URL = check_setting_str(CFG, 'Piratebay', 'piratebay_proxy_url', '')
PIRATEBAY_RATIO = check_setting_str(CFG, 'Piratebay', 'piratebay_ratio', '')
MININOVA = bool(check_setting_int(CFG, 'Mininova', 'mininova', 0))
MININOVA_RATIO = check_setting_str(CFG, 'Mininova', 'mininova_ratio', '')
WAFFLES = bool(check_setting_int(CFG, 'Waffles', 'waffles', 0)) WAFFLES = bool(check_setting_int(CFG, 'Waffles', 'waffles', 0))
WAFFLES_UID = check_setting_str(CFG, 'Waffles', 'waffles_uid', '') WAFFLES_UID = check_setting_str(CFG, 'Waffles', 'waffles_uid', '')
WAFFLES_PASSKEY = check_setting_str(CFG, 'Waffles', 'waffles_passkey', '') WAFFLES_PASSKEY = check_setting_str(CFG, 'Waffles', 'waffles_passkey', '')
WAFFLES_RATIO = check_setting_str(CFG, 'Waffles', 'waffles_ratio', '')
RUTRACKER = bool(check_setting_int(CFG, 'Rutracker', 'rutracker', 0)) RUTRACKER = bool(check_setting_int(CFG, 'Rutracker', 'rutracker', 0))
RUTRACKER_USER = check_setting_str(CFG, 'Rutracker', 'rutracker_user', '') RUTRACKER_USER = check_setting_str(CFG, 'Rutracker', 'rutracker_user', '')
RUTRACKER_PASSWORD = check_setting_str(CFG, 'Rutracker', 'rutracker_password', '') RUTRACKER_PASSWORD = check_setting_str(CFG, 'Rutracker', 'rutracker_password', '')
RUTRACKER_RATIO = check_setting_str(CFG, 'Rutracker', 'rutracker_ratio', '')
WHATCD = bool(check_setting_int(CFG, 'What.cd', 'whatcd', 0)) WHATCD = bool(check_setting_int(CFG, 'What.cd', 'whatcd', 0))
WHATCD_USERNAME = check_setting_str(CFG, 'What.cd', 'whatcd_username', '') WHATCD_USERNAME = check_setting_str(CFG, 'What.cd', 'whatcd_username', '')
WHATCD_PASSWORD = check_setting_str(CFG, 'What.cd', 'whatcd_password', '') WHATCD_PASSWORD = check_setting_str(CFG, 'What.cd', 'whatcd_password', '')
WHATCD_RATIO = check_setting_str(CFG, 'What.cd', 'whatcd_ratio', '')
SAB_HOST = check_setting_str(CFG, 'SABnzbd', 'sab_host', '') SAB_HOST = check_setting_str(CFG, 'SABnzbd', 'sab_host', '')
SAB_USERNAME = check_setting_str(CFG, 'SABnzbd', 'sab_username', '') SAB_USERNAME = check_setting_str(CFG, 'SABnzbd', 'sab_username', '')
@@ -505,6 +526,7 @@ def initialize():
NZBGET_PASSWORD = check_setting_str(CFG, 'NZBget', 'nzbget_password', '') NZBGET_PASSWORD = check_setting_str(CFG, 'NZBget', 'nzbget_password', '')
NZBGET_CATEGORY = check_setting_str(CFG, 'NZBget', 'nzbget_category', '') NZBGET_CATEGORY = check_setting_str(CFG, 'NZBget', 'nzbget_category', '')
NZBGET_HOST = check_setting_str(CFG, 'NZBget', 'nzbget_host', '') NZBGET_HOST = check_setting_str(CFG, 'NZBget', 'nzbget_host', '')
NZBGET_PRIORITY = check_setting_int(CFG, 'NZBget', 'nzbget_priority', 0)
HEADPHONES_INDEXER = bool(check_setting_int(CFG, 'Headphones', 'headphones_indexer', 0)) HEADPHONES_INDEXER = bool(check_setting_int(CFG, 'Headphones', 'headphones_indexer', 0))
@@ -872,6 +894,7 @@ def config_write():
new_config['General']['file_format'] = FILE_FORMAT new_config['General']['file_format'] = FILE_FORMAT
new_config['General']['file_underscores'] = int(FILE_UNDERSCORES) new_config['General']['file_underscores'] = int(FILE_UNDERSCORES)
new_config['General']['cleanup_files'] = int(CLEANUP_FILES) new_config['General']['cleanup_files'] = int(CLEANUP_FILES)
new_config['General']['keep_nfo'] = int(KEEP_NFO)
new_config['General']['add_album_art'] = int(ADD_ALBUM_ART) new_config['General']['add_album_art'] = int(ADD_ALBUM_ART)
new_config['General']['album_art_format'] = ALBUM_ART_FORMAT new_config['General']['album_art_format'] = ALBUM_ART_FORMAT
new_config['General']['embed_album_art'] = int(EMBED_ALBUM_ART) new_config['General']['embed_album_art'] = int(EMBED_ALBUM_ART)
@@ -892,27 +915,39 @@ def config_write():
new_config['General']['numberofseeders'] = NUMBEROFSEEDERS new_config['General']['numberofseeders'] = NUMBEROFSEEDERS
new_config['General']['torrentblackhole_dir'] = TORRENTBLACKHOLE_DIR new_config['General']['torrentblackhole_dir'] = TORRENTBLACKHOLE_DIR
new_config['General']['kat'] = int(KAT)
new_config['General']['kat_proxy_url'] = KAT_PROXY_URL
new_config['General']['mininova'] = int(MININOVA)
new_config['General']['piratebay'] = int(PIRATEBAY)
new_config['General']['piratebay_proxy_url'] = PIRATEBAY_PROXY_URL
new_config['General']['download_torrent_dir'] = DOWNLOAD_TORRENT_DIR new_config['General']['download_torrent_dir'] = DOWNLOAD_TORRENT_DIR
new_config['Kat'] = {}
new_config['Kat']['kat'] = int(KAT)
new_config['Kat']['kat_proxy_url'] = KAT_PROXY_URL
new_config['Kat']['kat_ratio'] = KAT_RATIO
new_config['Mininova'] = {}
new_config['Mininova']['mininova'] = int(MININOVA)
new_config['Mininova']['mininova_ratio'] = MININOVA_RATIO
new_config['Piratebay'] = {}
new_config['Piratebay']['piratebay'] = int(PIRATEBAY)
new_config['Piratebay']['piratebay_proxy_url'] = PIRATEBAY_PROXY_URL
new_config['Piratebay']['piratebay_ratio'] = PIRATEBAY_RATIO
new_config['Waffles'] = {} new_config['Waffles'] = {}
new_config['Waffles']['waffles'] = int(WAFFLES) new_config['Waffles']['waffles'] = int(WAFFLES)
new_config['Waffles']['waffles_uid'] = WAFFLES_UID new_config['Waffles']['waffles_uid'] = WAFFLES_UID
new_config['Waffles']['waffles_passkey'] = WAFFLES_PASSKEY new_config['Waffles']['waffles_passkey'] = WAFFLES_PASSKEY
new_config['Waffles']['waffles_ratio'] = WAFFLES_RATIO
new_config['Rutracker'] = {} new_config['Rutracker'] = {}
new_config['Rutracker']['rutracker'] = int(RUTRACKER) new_config['Rutracker']['rutracker'] = int(RUTRACKER)
new_config['Rutracker']['rutracker_user'] = RUTRACKER_USER new_config['Rutracker']['rutracker_user'] = RUTRACKER_USER
new_config['Rutracker']['rutracker_password'] = RUTRACKER_PASSWORD new_config['Rutracker']['rutracker_password'] = RUTRACKER_PASSWORD
new_config['Rutracker']['rutracker_ratio'] = RUTRACKER_RATIO
new_config['What.cd'] = {} new_config['What.cd'] = {}
new_config['What.cd']['whatcd'] = int(WHATCD) new_config['What.cd']['whatcd'] = int(WHATCD)
new_config['What.cd']['whatcd_username'] = WHATCD_USERNAME new_config['What.cd']['whatcd_username'] = WHATCD_USERNAME
new_config['What.cd']['whatcd_password'] = WHATCD_PASSWORD new_config['What.cd']['whatcd_password'] = WHATCD_PASSWORD
new_config['What.cd']['whatcd_ratio'] = WHATCD_RATIO
new_config['General']['search_interval'] = SEARCH_INTERVAL new_config['General']['search_interval'] = SEARCH_INTERVAL
new_config['General']['libraryscan'] = int(LIBRARYSCAN) new_config['General']['libraryscan'] = int(LIBRARYSCAN)
@@ -933,6 +968,7 @@ def config_write():
new_config['NZBget']['nzbget_password'] = NZBGET_PASSWORD new_config['NZBget']['nzbget_password'] = NZBGET_PASSWORD
new_config['NZBget']['nzbget_category'] = NZBGET_CATEGORY new_config['NZBget']['nzbget_category'] = NZBGET_CATEGORY
new_config['NZBget']['nzbget_host'] = NZBGET_HOST new_config['NZBget']['nzbget_host'] = NZBGET_HOST
new_config['NZBget']['nzbget_priority'] = NZBGET_PRIORITY
new_config['Headphones'] = {} new_config['Headphones'] = {}
new_config['Headphones']['headphones_indexer'] = int(HEADPHONES_INDEXER) new_config['Headphones']['headphones_indexer'] = int(HEADPHONES_INDEXER)
@@ -1101,7 +1137,7 @@ def start():
if __INITIALIZED__: if __INITIALIZED__:
# Start our scheduled background tasks # 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(updater.dbUpdate, hours=UPDATE_DB_INTERVAL)
SCHED.add_interval_job(searcher.searchforalbum, minutes=SEARCH_INTERVAL) SCHED.add_interval_job(searcher.searchforalbum, minutes=SEARCH_INTERVAL)
@@ -1113,6 +1149,9 @@ def start():
if DOWNLOAD_SCAN_INTERVAL > 0: if DOWNLOAD_SCAN_INTERVAL > 0:
SCHED.add_interval_job(postprocessor.checkFolder, minutes=DOWNLOAD_SCAN_INTERVAL) 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() SCHED.start()
started = True started = True
+1 -1
View File
@@ -145,7 +145,7 @@ class Api(object):
return return
def _getHistory(self, **kwargs): 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 return
def _getUpcoming(self, **kwargs): def _getUpcoming(self, **kwargs):
+5 -6
View File
@@ -20,7 +20,7 @@ import headphones
from headphones import db, helpers, logger, lastfm, request from headphones import db, helpers, logger, lastfm, request
lastfm_apikey = "690e1ed3bc00bc91804cd8f7fe5ed6d4" LASTFM_API_KEY = "690e1ed3bc00bc91804cd8f7fe5ed6d4"
class Cache(object): class Cache(object):
""" """
@@ -59,7 +59,6 @@ class Cache(object):
info_content = None info_content = None
def __init__(self): def __init__(self):
pass pass
def _findfilesstartingwith(self,pattern,folder): def _findfilesstartingwith(self,pattern,folder):
@@ -209,7 +208,7 @@ class Cache(object):
if ArtistID: if ArtistID:
self.id_type = 'artist' self.id_type = 'artist'
data = lastfm.request_lastfm("artist.getinfo", mbid=ArtistID, api_key=lastfm_apikey) data = lastfm.request_lastfm("artist.getinfo", mbid=ArtistID, api_key=LASTFM_API_KEY)
if not data: if not data:
return return
@@ -227,7 +226,7 @@ class Cache(object):
else: else:
self.id_type = 'album' self.id_type = 'album'
data = lastfm.request_lastfm("album.getinfo", mbid=AlbumID, api_key=lastfm_apikey) data = lastfm.request_lastfm("album.getinfo", mbid=AlbumID, api_key=LASTFM_API_KEY)
if not data: if not data:
return return
@@ -254,7 +253,7 @@ class Cache(object):
# Since lastfm uses release ids rather than release group ids for albums, we have to do a artist + album search for albums # Since lastfm uses release ids rather than release group ids for albums, we have to do a artist + album search for albums
if self.id_type == 'artist': if self.id_type == 'artist':
data = lastfm.request_lastfm("artist.getinfo", mbid=self.id, api_key=lastfm_apikey) data = lastfm.request_lastfm("artist.getinfo", mbid=self.id, api_key=LASTFM_API_KEY)
if not data: if not data:
return return
@@ -282,7 +281,7 @@ class Cache(object):
else: else:
dbartist = myDB.action('SELECT ArtistName, AlbumTitle FROM albums WHERE AlbumID=?', [self.id]).fetchone() dbartist = myDB.action('SELECT ArtistName, AlbumTitle FROM albums WHERE AlbumID=?', [self.id]).fetchone()
data = lastfm.request_lastfm("album.getinfo", artist=dbartist['ArtistName'], album=dbartist['AlbumTitle'], api_key=lastfm_apikey) data = lastfm.request_lastfm("album.getinfo", artist=dbartist['ArtistName'], album=dbartist['AlbumTitle'], api_key=LASTFM_API_KEY)
if not data: if not data:
return return
+15 -20
View File
@@ -59,37 +59,32 @@ class DBConnection:
return return
sqlResult = None sqlResult = None
attempt = 0
while attempt < 5: try:
try: with self.connection as c:
if args == None: if args == None:
#logger.debug(self.filename+": "+query) sqlResult = c.execute(query)
sqlResult = self.connection.execute(query)
else: else:
#logger.debug(self.filename+": "+query+" with args "+str(args)) sqlResult = c.execute(query, args)
sqlResult = self.connection.execute(query, args)
self.connection.commit() except sqlite3.OperationalError, e:
break if "unable to open database file" in e.message or "database is locked" in e.message:
except sqlite3.OperationalError, e: logger.warn('Database Error: %s', e)
if "unable to open database file" in e.message or "database is locked" in e.message: else:
logger.warn('Database Error: %s', e) logger.error('Database error: %s', e)
attempt += 1
time.sleep(1)
else:
logger.error('Database error: %s', e)
raise
except sqlite3.DatabaseError, e:
logger.error('Fatal Error executing %s :: %s', query, e)
raise raise
except sqlite3.DatabaseError, e:
logger.error('Fatal Error executing %s :: %s', query, e)
raise
return sqlResult return sqlResult
def select(self, query, args=None): def select(self, query, args=None):
sqlResults = self.action(query, args).fetchall() sqlResults = self.action(query, args).fetchall()
if sqlResults == None: if sqlResults == None or sqlResults == [None]:
return [] return []
return sqlResults return sqlResults
+10 -2
View File
@@ -98,9 +98,10 @@ def artistlist_to_mbids(artistlist, forced=False):
# Update the similar artist tag cloud: # Update the similar artist tag cloud:
logger.info('Updating artist information from Last.fm') logger.info('Updating artist information from Last.fm')
try: try:
lastfm.getSimilar() lastfm.getSimilar()
except Exception, e: except Exception as e:
logger.warn('Failed to update arist information from Last.fm: %s' % e) logger.warn('Failed to update arist information from Last.fm: %s' % e)
def addArtistIDListToDB(artistidlist): def addArtistIDListToDB(artistidlist):
@@ -431,9 +432,16 @@ def addArtisttoDB(artistid, extrasonly=False, forcefull=False):
tracks = myDB.action('SELECT * from alltracks WHERE ReleaseID=?', [releaseid]).fetchall() tracks = myDB.action('SELECT * from alltracks WHERE ReleaseID=?', [releaseid]).fetchall()
# This is used to see how many tracks you have from an album - to mark it as downloaded. Default is 80%, can be set in config as ALBUM_COMPLETION_PCT # This is used to see how many tracks you have from an album - to
# mark it as downloaded. Default is 80%, can be set in config as
# ALBUM_COMPLETION_PCT
total_track_count = len(tracks) total_track_count = len(tracks)
if total_track_count == 0:
logger.warning("Total track count is zero for Release ID " +
"'%s', skipping.", releaseid)
continue
for track in tracks: for track in tracks:
controlValueDict = {"TrackID": track['TrackID'], controlValueDict = {"TrackID": track['TrackID'],
+9 -8
View File
@@ -21,8 +21,9 @@ from headphones import db, logger, request
from collections import defaultdict from collections import defaultdict
ENTRY_POINT = 'http://ws.audioscrobbler.com/2.0/' TIMEOUT = 60 # seconds
API_KEY = '395e6ec6bb557382fc41fde867bce66f' ENTRY_POINT = "http://ws.audioscrobbler.com/2.0/"
API_KEY = "395e6ec6bb557382fc41fde867bce66f"
def request_lastfm(method, **kwargs): def request_lastfm(method, **kwargs):
""" """
@@ -40,7 +41,7 @@ def request_lastfm(method, **kwargs):
# Send request # Send request
logger.debug("Calling Last.FM method: %s", method) logger.debug("Calling Last.FM method: %s", method)
data = request.request_json(ENTRY_POINT, timeout=20, params=kwargs) data = request.request_json(ENTRY_POINT, timeout=TIMEOUT, params=kwargs)
# Parse response and check for errors. # Parse response and check for errors.
if not data: if not data:
@@ -55,13 +56,13 @@ def request_lastfm(method, **kwargs):
def getSimilar(): def getSimilar():
myDB = db.DBConnection() myDB = db.DBConnection()
results = myDB.select('SELECT ArtistID from artists ORDER BY HaveTracks DESC') results = myDB.select("SELECT ArtistID from artists ORDER BY HaveTracks DESC")
logger.info("Fetching similar artists from Last.FM for tag cloud") logger.info("Fetching similar artists from Last.FM for tag cloud")
artistlist = [] artistlist = []
for result in results[:12]: for result in results[:12]:
data = request_lastfm("artist.getsimilar", mbid=result['ArtistId']) data = request_lastfm("artist.getsimilar", mbid=result["ArtistId"])
time.sleep(10) time.sleep(10)
if data and "similarartists" in data: if data and "similarartists" in data:
@@ -94,13 +95,13 @@ def getSimilar():
artist_name, artist_mbid = item[0] artist_name, artist_mbid = item[0]
count = item[1] count = item[1]
myDB.action('INSERT INTO lastfmcloud VALUES( ?, ?, ?)', [artist_name, artist_mbid, count]) myDB.action("INSERT INTO lastfmcloud VALUES( ?, ?, ?)", [artist_name, artist_mbid, count])
logger.debug("Inserted %d artists into Last.FM tag cloud", len(top_list)) logger.debug("Inserted %d artists into Last.FM tag cloud", len(top_list))
def getArtists(): def getArtists():
myDB = db.DBConnection() myDB = db.DBConnection()
results = myDB.select('SELECT ArtistID from artists') results = myDB.select("SELECT ArtistID from artists")
if not headphones.LASTFM_USERNAME: if not headphones.LASTFM_USERNAME:
logger.warn("Last.FM username not set, not importing artists.") logger.warn("Last.FM username not set, not importing artists.")
@@ -129,7 +130,7 @@ def getArtists():
def getTagTopArtists(tag, limit=50): def getTagTopArtists(tag, limit=50):
myDB = db.DBConnection() myDB = db.DBConnection()
results = myDB.select('SELECT ArtistID from artists') results = myDB.select("SELECT ArtistID from artists")
logger.info("Fetching top artists from Last.FM for tag: %s", tag) logger.info("Fetching top artists from Last.FM for tag: %s", tag)
data = request_lastfm("tag.gettopartists", limit=limit, tag=tag) data = request_lastfm("tag.gettopartists", limit=limit, tag=tag)
+51 -16
View File
@@ -69,25 +69,60 @@ def sendNZB(nzb):
logger.error(u"Protocol Error: " + e.errmsg) logger.error(u"Protocol Error: " + e.errmsg)
return False return False
# if it's a normal result need to download the NZB content nzbcontent64 = None
if nzb.resultType == "nzb": if nzb.resultType == "nzbdata":
genProvider = GenericProvider("")
data = genProvider.getURL(nzb.url)
if (data == None):
return False
# if we get a raw data result thats even better
elif nzb.resultType == "nzbdata":
data = nzb.extraInfo[0] data = nzb.extraInfo[0]
nzbcontent64 = standard_b64encode(data)
nzbcontent64 = standard_b64encode(data)
logger.info(u"Sending NZB to NZBget") logger.info(u"Sending NZB to NZBget")
logger.debug(u"URL: " + url) logger.debug(u"URL: " + url)
if nzbGetRPC.append(nzb.name + ".nzb", headphones.NZBGET_CATEGORY, addToTop, nzbcontent64): dupekey = ""
logger.debug(u"NZB sent to NZBget successfully") dupescore = 0
return True
else: try:
logger.error(u"NZBget could not add %s to the queue" % (nzb.name + ".nzb")) # Find out if nzbget supports priority (Version 9.0+), old versions beginning with a 0.x will use the old command
nzbget_version_str = nzbGetRPC.version()
nzbget_version = int(nzbget_version_str[:nzbget_version_str.find(".")])
if nzbget_version == 0:
if nzbcontent64 is not None:
nzbget_result = nzbGetRPC.append(nzb.name + ".nzb", headphones.NZBGET_CATEGORY, addToTop, nzbcontent64)
else:
if nzb.resultType == "nzb":
genProvider = GenericProvider("")
data = genProvider.getURL(nzb.url)
if (data == None):
return False
nzbcontent64 = standard_b64encode(data)
nzbget_result = nzbGetRPC.append(nzb.name + ".nzb", headphones.NZBGET_CATEGORY, addToTop, nzbcontent64)
elif nzbget_version == 12:
if nzbcontent64 is not None:
nzbget_result = nzbGetRPC.append(nzb.name + ".nzb", headphones.NZBGET_CATEGORY, headphones.NZBGET_PRIORITY, False,
nzbcontent64, False, dupekey, dupescore, "score")
else:
nzbget_result = nzbGetRPC.appendurl(nzb.name + ".nzb", headphones.NZBGET_CATEGORY, headphones.NZBGET_PRIORITY, False,
nzb.url, False, dupekey, dupescore, "score")
# v13+ has a new combined append method that accepts both (url and content)
# also the return value has changed from boolean to integer
# (Positive number representing NZBID of the queue item. 0 and negative numbers represent error codes.)
elif nzbget_version >= 13:
nzbget_result = True if nzbGetRPC.append(nzb.name + ".nzb", nzbcontent64 if nzbcontent64 is not None else nzb.url,
headphones.NZBGET_CATEGORY, headphones.NZBGET_PRIORITY, False, False, dupekey, dupescore,
"score") > 0 else False
else:
if nzbcontent64 is not None:
nzbget_result = nzbGetRPC.append(nzb.name + ".nzb", headphones.NZBGET_CATEGORY, headphones.NZBGET_PRIORITY, False,
nzbcontent64)
else:
nzbget_result = nzbGetRPC.appendurl(nzb.name + ".nzb", headphones.NZBGET_CATEGORY, headphones.NZBGET_PRIORITY, False,
nzb.url)
if nzbget_result:
logger.debug(u"NZB sent to NZBget successfully")
return True
else:
logger.error(u"NZBget could not add %s to the queue" % (nzb.name + ".nzb"))
return False
except:
logger.error(u"Connect Error to NZBget: could not add %s to the queue" % (nzb.name + ".nzb"))
return False return False
+46 -7
View File
@@ -24,7 +24,7 @@ import headphones
from beets import autotag from beets import autotag
from beets.mediafile import MediaFile, FileTypeError, UnreadableFileError 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 db, albumart, librarysync, lyrics
from headphones import logger, helpers, request, mb, music_encoder from headphones import logger, helpers, request, mb, music_encoder
@@ -305,7 +305,7 @@ def verify(albumid, albumpath, Kind=None, forced=False):
return return
logger.warn(u'Could not identify album: %s. It may not be the intended album.' % albumpath.decode(headphones.SYS_ENCODING, 'replace')) 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) processed = re.search(r' \(Unprocessed\)(?:\[\d+\])?', albumpath)
if not processed: if not processed:
renameUnprocessedFolder(albumpath) renameUnprocessedFolder(albumpath)
@@ -389,6 +389,9 @@ def doPostProcessing(albumid, albumpath, release, tracks, downloaded_track_list,
if headphones.CLEANUP_FILES: if headphones.CLEANUP_FILES:
cleanupFiles(albumpath) cleanupFiles(albumpath)
if headphones.KEEP_NFO:
renameNFO(albumpath)
if headphones.ADD_ALBUM_ART and artwork: if headphones.ADD_ALBUM_ART and artwork:
addAlbumArt(artwork, albumpath, release) addAlbumArt(artwork, albumpath, release)
@@ -413,7 +416,24 @@ def doPostProcessing(albumid, albumpath, release, tracks, downloaded_track_list,
myDB = db.DBConnection() myDB = db.DBConnection()
myDB.action('UPDATE albums SET status = "Downloaded" WHERE AlbumID=?', [albumid]) 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 headphones.TORRENT_DOWNLOADER == 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: # Update the have tracks for all created dirs:
for albumpath in albumpaths: for albumpath in albumpaths:
@@ -560,11 +580,23 @@ def cleanupFiles(albumpath):
for r,d,f in os.walk(albumpath): for r,d,f in os.walk(albumpath):
for files in f: for files in f:
if not any(files.lower().endswith('.' + x.lower()) for x in headphones.MEDIA_FORMATS): if not any(files.lower().endswith('.' + x.lower()) for x in headphones.MEDIA_FORMATS):
logger.debug('Removing: %s' % files) if not (headphones.KEEP_NFO and files.lower().endswith('.nfo')):
logger.debug('Removing: %s' % files)
try:
os.remove(os.path.join(r, files))
except Exception, e:
logger.error(u'Could not remove file: %s. Error: %s' % (files.decode(headphones.SYS_ENCODING, 'replace'), e))
def renameNFO(albumpath):
for r,d,f in os.walk(albumpath):
for file in f:
if file.lower().endswith('.nfo'):
logger.debug('Renaming: "%s" to "%s"' % (file.decode(headphones.SYS_ENCODING, 'replace'), file.decode(headphones.SYS_ENCODING, 'replace') + '-orig'))
try: try:
os.remove(os.path.join(r, files)) new_file_name = os.path.join(r, file)[:-3] + 'orig.nfo'
os.rename(os.path.join(r, file), new_file_name)
except Exception, e: except Exception, e:
logger.error(u'Could not remove file: %s. Error: %s' % (files.decode(headphones.SYS_ENCODING, 'replace'), e)) logger.error(u'Could not rename file: %s. Error: %s' % (os.path.join(r, file).decode(headphones.SYS_ENCODING, 'replace'), e))
def moveFiles(albumpath, release, tracks): def moveFiles(albumpath, release, tracks):
@@ -591,19 +623,26 @@ def moveFiles(albumpath, release, tracks):
else: else:
firstchar = sortname[0] firstchar = sortname[0]
for r,d,f in os.walk(albumpath):
try:
origfolder = os.path.basename(os.path.normpath(r))
except:
origfolder = ''
values = { '$Artist': artist, values = { '$Artist': artist,
'$SortArtist': sortname, '$SortArtist': sortname,
'$Album': album, '$Album': album,
'$Year': year, '$Year': year,
'$Type': releasetype, '$Type': releasetype,
'$OriginalFolder': origfolder,
'$First': firstchar.upper(), '$First': firstchar.upper(),
'$artist': artist.lower(), '$artist': artist.lower(),
'$sortartist': sortname.lower(), '$sortartist': sortname.lower(),
'$album': album.lower(), '$album': album.lower(),
'$year': year, '$year': year,
'$type': releasetype.lower(), '$type': releasetype.lower(),
'$first': firstchar.lower() '$first': firstchar.lower(),
'$originalfolder': origfolder.lower()
} }
folder = helpers.replace_all(headphones.FOLDER_FORMAT.strip(), values) folder = helpers.replace_all(headphones.FOLDER_FORMAT.strip(), values)
+15
View File
@@ -1,3 +1,18 @@
# 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/>.
from headphones import logger from headphones import logger
from xml.dom import minidom from xml.dom import minidom
+46 -6
View File
@@ -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])) 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 # Get rid of any dodgy chars here so we can prevent sab from renaming our downloads
kind = bestqual[4] kind = bestqual[4]
seed_ratio = None
torrentid = None
if kind == 'nzb': if kind == 'nzb':
folder_name = helpers.sab_sanitize_foldername(bestqual[0]) 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 # rutracker needs cookies to be set, pass the .torrent file instead of url
if bestqual[3] == 'rutracker.org': if bestqual[3] == 'rutracker.org':
file_or_url, _hash = rutracker.get_torrent(bestqual[2]) file_or_url, torrentid = rutracker.get_torrent(bestqual[2])
else: else:
file_or_url = bestqual[2] file_or_url = bestqual[2]
@@ -698,19 +700,24 @@ def send_to_downloader(data, bestqual, album):
except Exception as e: except Exception as e:
logger.exception("Unhandled exception") logger.exception("Unhandled exception")
# Set Seed Ratio
seed_ratio = getSeedRatio(bestqual[3])
if seed_ratio != None:
transmission.setSeedRatio(torrentid, seed_ratio)
else:# if headphones.TORRENT_DOWNLOADER == 2: else:# if headphones.TORRENT_DOWNLOADER == 2:
logger.info("Sending torrent to uTorrent") logger.info("Sending torrent to uTorrent")
# rutracker needs cookies to be set, pass the .torrent file instead of url # rutracker needs cookies to be set, pass the .torrent file instead of url
if bestqual[3] == 'rutracker.org': if bestqual[3] == 'rutracker.org':
file_or_url, _hash = rutracker.get_torrent(bestqual[2]) file_or_url, torrentid = rutracker.get_torrent(bestqual[2])
folder_name, cacheid = utorrent.dirTorrent(_hash) folder_name, cacheid = utorrent.dirTorrent(torrentid)
folder_name = os.path.basename(os.path.normpath(folder_name)) folder_name = os.path.basename(os.path.normpath(folder_name))
utorrent.labelTorrent(_hash) utorrent.labelTorrent(torrentid)
else: else:
file_or_url = bestqual[2] file_or_url = bestqual[2]
_hash = CalculateTorrentHash(file_or_url, data) torrentid = CalculateTorrentHash(file_or_url, data)
folder_name = utorrent.addTorrent(file_or_url, _hash) folder_name = utorrent.addTorrent(file_or_url, torrentid)
if folder_name: if folder_name:
logger.info('Torrent folder name: %s' % folder_name) logger.info('Torrent folder name: %s' % folder_name)
@@ -725,10 +732,19 @@ def send_to_downloader(data, bestqual, album):
except Exception as e: except Exception as e:
logger.exception("Unhandled exception") logger.exception("Unhandled exception")
# Set Seed Ratio
seed_ratio = getSeedRatio(bestqual[3])
if seed_ratio != None:
utorrent.setSeedRatio(torrentid, seed_ratio)
myDB = db.DBConnection() myDB = db.DBConnection()
myDB.action('UPDATE albums SET status = "Snatched" WHERE AlbumID=?', [album['AlbumID']]) 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]) 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 # notify
artist = album[1] artist = album[1]
albumname = album[2] albumname = album[2]
@@ -1351,3 +1367,27 @@ def CalculateTorrentHash(link, data):
logger.debug('Torrent Hash: ' + str(tor_hash)) logger.debug('Torrent Hash: ' + str(tor_hash))
return tor_hash return tor_hash
def getSeedRatio(provider):
seed_ratio = ''
if provider == 'rutracker.org':
seed_ratio = headphones.RUTRACKER_RATIO
elif provider == 'Kick Ass Torrents':
seed_ratio = headphones.KAT_RATIO
elif provider == 'What.cd':
seed_ratio = headphones.WHATCD_RATIO
elif provider == 'The Pirate Bay':
seed_ratio = headphones.PIRATEBAY_RATIO
elif provider == 'Waffles.fm':
seed_ratio = headphones.WAFFLES_RATIO
elif provider == 'Mininova':
seed_ratio = headphones.MININOVA_RATIO
if seed_ratio != '':
try:
seed_ratio_float = float(seed_ratio)
except:
seed_ratio_float = None
logger.warn('Could not get Seed Ratio for %s' % provider)
return seed_ratio_float
else:
return None
+40
View File
@@ -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])
+35 -2
View File
@@ -47,10 +47,10 @@ def addTorrent(link):
if response['result'] == 'success': if response['result'] == 'success':
if 'torrent-added' in response['arguments']: if 'torrent-added' in response['arguments']:
name = response['arguments']['torrent-added']['name'] name = response['arguments']['torrent-added']['name']
retid = response['arguments']['torrent-added']['id'] retid = response['arguments']['torrent-added']['hashString']
elif 'torrent-duplicate' in response['arguments']: elif 'torrent-duplicate' in response['arguments']:
name = response['arguments']['torrent-duplicate']['name'] name = response['arguments']['torrent-duplicate']['name']
retid = response['arguments']['torrent-duplicate']['id'] retid = response['arguments']['torrent-duplicate']['hashString']
else: else:
name = link name = link
retid = False retid = False
@@ -82,6 +82,39 @@ def getTorrentFolder(torrentid):
return torrent_folder_name return torrent_folder_name
def setSeedRatio(torrentid, ratio):
method = 'torrent-set'
if ratio != 0:
arguments = {'seedRatioLimit': ratio, 'seedRatioMode': 1, 'ids': torrentid}
else:
arguments = {'seedRatioMode': 2, 'ids': torrentid}
response = torrentAction(method, arguments)
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): def torrentAction(method, arguments):
host = headphones.TRANSMISSION_HOST host = headphones.TRANSMISSION_HOST
+47 -6
View File
@@ -132,6 +132,13 @@ class utorrentclient(object):
return settings[key] return settings[key]
return settings 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): def _action(self, params, body=None, content_type=None):
url = self.base_url + '/gui/' + '?token=' + self.token + '&' + urllib.urlencode(params) url = self.base_url + '/gui/' + '?token=' + self.token + '&' + urllib.urlencode(params)
request = urllib2.Request(url) request = urllib2.Request(url)
@@ -155,7 +162,27 @@ def labelTorrent(hash):
if label: if label:
uTorrentClient.setprops(hash,'label',label) uTorrentClient.setprops(hash,'label',label)
def dirTorrent(hash, cacheid=None): def removeTorrent(hash, remove_data = False):
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, remove_data)
return True
return False
def setSeedRatio(hash, ratio):
uTorrentClient = utorrentclient()
uTorrentClient.setprops(hash, 'seed_override', '1')
if ratio != 0:
uTorrentClient.setprops(hash,'seed_ratio', ratio * 10)
else:
# TODO passing -1 should be unlimited
uTorrentClient.setprops(hash,'seed_ratio', -1.00)
def dirTorrent(hash, cacheid=None, return_name=None):
uTorrentClient = utorrentclient() uTorrentClient = utorrentclient()
@@ -174,7 +201,10 @@ def dirTorrent(hash, cacheid=None):
for torrent in torrents: for torrent in torrents:
if (torrent[0].lower() == hash): if (torrent[0].lower() == hash):
return torrent[26], cacheid if not return_name:
return torrent[26], cacheid
else:
return torrent[2], cacheid
return None, None return None, None
@@ -184,6 +214,10 @@ def addTorrent(link, hash):
# Get Active Directory from settings # Get Active Directory from settings
active_dir, completed_dir = getSettingsDirectories() active_dir, completed_dir = getSettingsDirectories()
if not active_dir or not completed_dir:
logger.error('Could not get "Put new downloads in:" or "Move completed downloads to:" directories from uTorrent settings, please ensure they are set')
return None
uTorrentClient.add_url(link) uTorrentClient.add_url(link)
# Get Torrent Folder Name # Get Torrent Folder Name
@@ -197,8 +231,10 @@ def addTorrent(link, hash):
time.sleep(6) time.sleep(6)
torrent_folder, cacheid = dirTorrent(hash, cacheid) torrent_folder, cacheid = dirTorrent(hash, cacheid)
if torrent_folder == active_dir: if torrent_folder == active_dir or not torrent_folder:
return None torrent_folder, cacheid = dirTorrent(hash, cacheid, return_name=True)
labelTorrent(hash)
return torrent_folder
else: else:
labelTorrent(hash) labelTorrent(hash)
return os.path.basename(os.path.normpath(torrent_folder)) return os.path.basename(os.path.normpath(torrent_folder))
@@ -206,6 +242,11 @@ def addTorrent(link, hash):
def getSettingsDirectories(): def getSettingsDirectories():
uTorrentClient = utorrentclient() uTorrentClient = utorrentclient()
settings = uTorrentClient.get_settings() settings = uTorrentClient.get_settings()
active = settings['dir_active_download'][2] active = None
completed = settings['dir_completed_download'][2] completed = None
if 'dir_active_download' in settings:
active = settings['dir_active_download'][2]
if 'dir_completed_download' in settings:
completed = settings['dir_completed_download'][2]
return active, completed return active, completed
+22 -6
View File
@@ -735,7 +735,7 @@ class WebInterface(object):
def history(self): def history(self):
myDB = db.DBConnection() 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) return serve_template(templatename="history.html", title="History", history=history)
history.exposed = True history.exposed = True
@@ -901,13 +901,13 @@ class WebInterface(object):
if type: if type:
if type == 'all': if type == 'all':
logger.info(u"Clearing all history") logger.info(u"Clearing all history")
myDB.action('DELETE from snatched') myDB.action('DELETE from snatched WHERE Status NOT LIKE "Seed%"')
else: else:
logger.info(u"Clearing history where status is %s" % type) logger.info(u"Clearing history where status is %s" % type)
myDB.action('DELETE from snatched WHERE Status=?', [type]) myDB.action('DELETE from snatched WHERE Status=?', [type])
else: else:
logger.info(u"Deleting '%s' from history" % title) 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") raise cherrypy.HTTPRedirect("history")
clearhistory.exposed = True clearhistory.exposed = True
@@ -971,6 +971,7 @@ class WebInterface(object):
"nzbget_user" : headphones.NZBGET_USERNAME, "nzbget_user" : headphones.NZBGET_USERNAME,
"nzbget_pass" : headphones.NZBGET_PASSWORD, "nzbget_pass" : headphones.NZBGET_PASSWORD,
"nzbget_cat" : headphones.NZBGET_CATEGORY, "nzbget_cat" : headphones.NZBGET_CATEGORY,
"nzbget_priority" : headphones.NZBGET_PRIORITY,
"transmission_host" : headphones.TRANSMISSION_HOST, "transmission_host" : headphones.TRANSMISSION_HOST,
"transmission_user" : headphones.TRANSMISSION_USERNAME, "transmission_user" : headphones.TRANSMISSION_USERNAME,
"transmission_pass" : headphones.TRANSMISSION_PASSWORD, "transmission_pass" : headphones.TRANSMISSION_PASSWORD,
@@ -1008,18 +1009,24 @@ class WebInterface(object):
"numberofseeders" : headphones.NUMBEROFSEEDERS, "numberofseeders" : headphones.NUMBEROFSEEDERS,
"use_kat" : checked(headphones.KAT), "use_kat" : checked(headphones.KAT),
"kat_proxy_url" : headphones.KAT_PROXY_URL, "kat_proxy_url" : headphones.KAT_PROXY_URL,
"kat_ratio": headphones.KAT_RATIO,
"use_piratebay" : checked(headphones.PIRATEBAY), "use_piratebay" : checked(headphones.PIRATEBAY),
"piratebay_proxy_url" : headphones.PIRATEBAY_PROXY_URL, "piratebay_proxy_url" : headphones.PIRATEBAY_PROXY_URL,
"piratebay_ratio": headphones.PIRATEBAY_RATIO,
"use_mininova" : checked(headphones.MININOVA), "use_mininova" : checked(headphones.MININOVA),
"mininova_ratio": headphones.MININOVA_RATIO,
"use_waffles" : checked(headphones.WAFFLES), "use_waffles" : checked(headphones.WAFFLES),
"waffles_uid" : headphones.WAFFLES_UID, "waffles_uid" : headphones.WAFFLES_UID,
"waffles_passkey": headphones.WAFFLES_PASSKEY, "waffles_passkey": headphones.WAFFLES_PASSKEY,
"waffles_ratio": headphones.WAFFLES_RATIO,
"use_rutracker" : checked(headphones.RUTRACKER), "use_rutracker" : checked(headphones.RUTRACKER),
"rutracker_user" : headphones.RUTRACKER_USER, "rutracker_user" : headphones.RUTRACKER_USER,
"rutracker_password": headphones.RUTRACKER_PASSWORD, "rutracker_password": headphones.RUTRACKER_PASSWORD,
"rutracker_ratio": headphones.RUTRACKER_RATIO,
"use_whatcd" : checked(headphones.WHATCD), "use_whatcd" : checked(headphones.WHATCD),
"whatcd_username" : headphones.WHATCD_USERNAME, "whatcd_username" : headphones.WHATCD_USERNAME,
"whatcd_password": headphones.WHATCD_PASSWORD, "whatcd_password": headphones.WHATCD_PASSWORD,
"whatcd_ratio": headphones.WHATCD_RATIO,
"pref_qual_0" : radio(headphones.PREFERRED_QUALITY, 0), "pref_qual_0" : radio(headphones.PREFERRED_QUALITY, 0),
"pref_qual_1" : radio(headphones.PREFERRED_QUALITY, 1), "pref_qual_1" : radio(headphones.PREFERRED_QUALITY, 1),
"pref_qual_3" : radio(headphones.PREFERRED_QUALITY, 3), "pref_qual_3" : radio(headphones.PREFERRED_QUALITY, 3),
@@ -1035,6 +1042,7 @@ class WebInterface(object):
"rename_files" : checked(headphones.RENAME_FILES), "rename_files" : checked(headphones.RENAME_FILES),
"correct_metadata" : checked(headphones.CORRECT_METADATA), "correct_metadata" : checked(headphones.CORRECT_METADATA),
"cleanup_files" : checked(headphones.CLEANUP_FILES), "cleanup_files" : checked(headphones.CLEANUP_FILES),
"keep_nfo" : checked(headphones.KEEP_NFO),
"add_album_art" : checked(headphones.ADD_ALBUM_ART), "add_album_art" : checked(headphones.ADD_ALBUM_ART),
"album_art_format" : headphones.ALBUM_ART_FORMAT, "album_art_format" : headphones.ALBUM_ART_FORMAT,
"embed_album_art" : checked(headphones.EMBED_ALBUM_ART), "embed_album_art" : checked(headphones.EMBED_ALBUM_ART),
@@ -1154,12 +1162,12 @@ class WebInterface(object):
def configUpdate(self, http_host='0.0.0.0', http_username=None, http_port=8181, http_password=None, launch_browser=0, api_enabled=0, api_key=None, def configUpdate(self, http_host='0.0.0.0', http_username=None, http_port=8181, http_password=None, launch_browser=0, api_enabled=0, api_key=None,
download_scan_interval=None, update_db_interval=None, mb_ignore_age=None, nzb_search_interval=None, libraryscan_interval=None, sab_host=None, sab_username=None, sab_apikey=None, sab_password=None, download_scan_interval=None, update_db_interval=None, mb_ignore_age=None, nzb_search_interval=None, libraryscan_interval=None, sab_host=None, sab_username=None, sab_apikey=None, sab_password=None,
sab_category=None, nzbget_host=None, nzbget_username=None, nzbget_password=None, nzbget_category=None, transmission_host=None, transmission_username=None, transmission_password=None, sab_category=None, nzbget_host=None, nzbget_username=None, nzbget_password=None, nzbget_category=None, nzbget_priority=0, transmission_host=None, transmission_username=None, transmission_password=None,
utorrent_host=None, utorrent_username=None, utorrent_password=None, utorrent_label=None,nzb_downloader=0, torrent_downloader=0, download_dir=None, blackhole_dir=None, usenet_retention=None, utorrent_host=None, utorrent_username=None, utorrent_password=None, utorrent_label=None,nzb_downloader=0, torrent_downloader=0, download_dir=None, blackhole_dir=None, usenet_retention=None,
use_headphones_indexer=0, newznab=0, newznab_host=None, newznab_apikey=None, newznab_enabled=0, nzbsorg=0, nzbsorg_uid=None, nzbsorg_hash=None, omgwtfnzbs=0, omgwtfnzbs_uid=None, omgwtfnzbs_apikey=None, use_headphones_indexer=0, newznab=0, newznab_host=None, newznab_apikey=None, newznab_enabled=0, nzbsorg=0, nzbsorg_uid=None, nzbsorg_hash=None, omgwtfnzbs=0, omgwtfnzbs_uid=None, omgwtfnzbs_apikey=None,
preferred_words=None, required_words=None, ignored_words=None, preferred_quality=0, preferred_bitrate=None, detect_bitrate=0, move_files=0, torrentblackhole_dir=None, download_torrent_dir=None, preferred_words=None, required_words=None, ignored_words=None, preferred_quality=0, preferred_bitrate=None, detect_bitrate=0, move_files=0, torrentblackhole_dir=None, download_torrent_dir=None,
numberofseeders=None, use_piratebay=0, piratebay_proxy_url=None, use_kat=0, kat_proxy_url=None, use_mininova=0, waffles=0, waffles_uid=None, waffles_passkey=None, whatcd=0, whatcd_username=None, whatcd_password=None, numberofseeders=None, use_piratebay=0, piratebay_proxy_url=None, piratebay_ratio=None, use_kat=0, kat_proxy_url=None, kat_ratio=None, use_mininova=0, mininova_ratio=None, waffles=0, waffles_uid=None, waffles_passkey=None, waffles_ratio=None, whatcd=0, whatcd_username=None, whatcd_password=None, whatcd_ratio=None,
rutracker=0, rutracker_user=None, rutracker_password=None, rename_files=0, correct_metadata=0, cleanup_files=0, add_album_art=0, album_art_format=None, embed_album_art=0, embed_lyrics=0, replace_existing_folders=False, rutracker=0, rutracker_user=None, rutracker_password=None, rutracker_ratio=None, rename_files=0, correct_metadata=0, cleanup_files=0, keep_nfo=0, add_album_art=0, album_art_format=None, embed_album_art=0, embed_lyrics=0, replace_existing_folders=False,
destination_dir=None, lossless_destination_dir=None, folder_format=None, file_format=None, file_underscores=0, include_extras=0, single=0, ep=0, compilation=0, soundtrack=0, live=0, destination_dir=None, lossless_destination_dir=None, folder_format=None, file_format=None, file_underscores=0, include_extras=0, single=0, ep=0, compilation=0, soundtrack=0, live=0,
remix=0, djmix=0, mixtape_street=0, broadcast=0, interview=0, spokenword=0, audiobook=0, other=0, autowant_upcoming=False, autowant_all=False, keep_torrent_files=False, prefer_torrents=0, open_magnet_links=0, interface=None, log_dir=None, cache_dir=None, music_encoder=0, encoder=None, xldprofile=None, remix=0, djmix=0, mixtape_street=0, broadcast=0, interview=0, spokenword=0, audiobook=0, other=0, autowant_upcoming=False, autowant_all=False, keep_torrent_files=False, prefer_torrents=0, open_magnet_links=0, interface=None, log_dir=None, cache_dir=None, music_encoder=0, encoder=None, xldprofile=None,
bitrate=None, samplingfrequency=None, encoderfolder=None, advancedencoder=None, encoderoutputformat=None, encodervbrcbr=None, encoderquality=None, encoderlossless=0, bitrate=None, samplingfrequency=None, encoderfolder=None, advancedencoder=None, encoderoutputformat=None, encodervbrcbr=None, encoderquality=None, encoderlossless=0,
@@ -1195,6 +1203,7 @@ class WebInterface(object):
headphones.NZBGET_USERNAME = nzbget_username headphones.NZBGET_USERNAME = nzbget_username
headphones.NZBGET_PASSWORD = nzbget_password headphones.NZBGET_PASSWORD = nzbget_password
headphones.NZBGET_CATEGORY = nzbget_category headphones.NZBGET_CATEGORY = nzbget_category
headphones.NZBGET_PRIORITY = int(nzbget_priority)
headphones.TRANSMISSION_HOST = transmission_host headphones.TRANSMISSION_HOST = transmission_host
headphones.TRANSMISSION_USERNAME = transmission_username headphones.TRANSMISSION_USERNAME = transmission_username
headphones.TRANSMISSION_PASSWORD = transmission_password headphones.TRANSMISSION_PASSWORD = transmission_password
@@ -1226,18 +1235,24 @@ class WebInterface(object):
headphones.DOWNLOAD_TORRENT_DIR = download_torrent_dir headphones.DOWNLOAD_TORRENT_DIR = download_torrent_dir
headphones.KAT = use_kat headphones.KAT = use_kat
headphones.KAT_PROXY_URL = kat_proxy_url headphones.KAT_PROXY_URL = kat_proxy_url
headphones.KAT_RATIO = kat_ratio
headphones.PIRATEBAY = use_piratebay headphones.PIRATEBAY = use_piratebay
headphones.PIRATEBAY_PROXY_URL = piratebay_proxy_url headphones.PIRATEBAY_PROXY_URL = piratebay_proxy_url
headphones.PIRATEBAY_RATIO = piratebay_ratio
headphones.MININOVA = use_mininova headphones.MININOVA = use_mininova
headphones.MININOVA_RATIO = mininova_ratio
headphones.WAFFLES = waffles headphones.WAFFLES = waffles
headphones.WAFFLES_UID = waffles_uid headphones.WAFFLES_UID = waffles_uid
headphones.WAFFLES_PASSKEY = waffles_passkey headphones.WAFFLES_PASSKEY = waffles_passkey
headphones.WAFFLES_RATIO = waffles_ratio
headphones.RUTRACKER = rutracker headphones.RUTRACKER = rutracker
headphones.RUTRACKER_USER = rutracker_user headphones.RUTRACKER_USER = rutracker_user
headphones.RUTRACKER_PASSWORD = rutracker_password headphones.RUTRACKER_PASSWORD = rutracker_password
headphones.RUTRACKER_RATIO = rutracker_ratio
headphones.WHATCD = whatcd headphones.WHATCD = whatcd
headphones.WHATCD_USERNAME = whatcd_username headphones.WHATCD_USERNAME = whatcd_username
headphones.WHATCD_PASSWORD = whatcd_password headphones.WHATCD_PASSWORD = whatcd_password
headphones.WHATCD_RATIO = whatcd_ratio
headphones.PREFERRED_QUALITY = int(preferred_quality) headphones.PREFERRED_QUALITY = int(preferred_quality)
headphones.PREFERRED_BITRATE = preferred_bitrate headphones.PREFERRED_BITRATE = preferred_bitrate
headphones.PREFERRED_BITRATE_HIGH_BUFFER = preferred_bitrate_high_buffer headphones.PREFERRED_BITRATE_HIGH_BUFFER = preferred_bitrate_high_buffer
@@ -1250,6 +1265,7 @@ class WebInterface(object):
headphones.CORRECT_METADATA = correct_metadata headphones.CORRECT_METADATA = correct_metadata
headphones.RENAME_FILES = rename_files headphones.RENAME_FILES = rename_files
headphones.CLEANUP_FILES = cleanup_files headphones.CLEANUP_FILES = cleanup_files
headphones.KEEP_NFO = keep_nfo
headphones.ADD_ALBUM_ART = add_album_art headphones.ADD_ALBUM_ART = add_album_art
headphones.ALBUM_ART_FORMAT = album_art_format headphones.ALBUM_ART_FORMAT = album_art_format
headphones.EMBED_ALBUM_ART = embed_album_art headphones.EMBED_ALBUM_ART = embed_album_art