Merged torrent-fixes branch and fixed some merge conflicts

This commit is contained in:
rembo10
2013-07-27 23:15:36 +05:30
9 changed files with 469 additions and 105 deletions

View File

@@ -162,41 +162,81 @@
</div>
</fieldset>
<fieldset id="nzb_download_dir">
<fieldset id="general_nzb_options">
<div class="row">
<label>Music Download Directory:</label>
<input type="text" name="download_dir" value="${config['download_dir']}" size="50">
<small>Full path where SAB or NZBget downloads your music. e.g. /Users/name/Downloads/music</small>
</div>
</fieldset>
<div class="checkbox row">
<input type="text" name="usenet_retention" value="${config['usenet_retention']}" size="5"><label>Usenet Retention</label>
</div>
<div class="row">
<input type="text" name="usenet_retention" value="${config['usenet_retention']}" size="5"><label>Usenet Retention</label>
</div>
</fieldset>
</td>
<td>
<fieldset>
<legend>Torrents</legend>
<div class="row">
<label>Black Hole Directory</label>
<input type="text" name="torrentblackhole_dir" value="${config['torrentblackhole_dir']}" size="50">
<small>Folder your Download program watches for Torrents</small>
</div>
<div class="row">
<label>Minimum seeders:</label>
<input type="text" name="numberofseeders" value="${config['numberofseeders']}" size="5">
<small>Number of minimum seeders a torrent must have to be accepted</small>
</div>
<div class="row">
<label>Music Download Directory</label>
<input type="text" name="download_torrent_dir" value="${config['download_torrent_dir']}" size="50">
<small>Full path where your torrent client downloads your music e.g. /Users/name/Downloads/music</small>
</div>
<div class="row checkbox">
<label>Keep Files for Seeding</label>
<input type="checkbox" name="keep_torrent_files" value="1" ${config['keep_torrent_files']}>
<input type="radio" name="torrent_downloader" id="torrent_downloader_blackhole" value="0" ${config['torrent_downloader_blackhole']}>Black Hole <input type="radio" name="torrent_downloader" id="torrent_downloader_transmission" value="1" ${config['torrent_downloader_transmission']}> Transmission <!-- <input type="radio" name="torrent_downloader" id="torrent_downloader_utorrent" value="2" ${config['torrent_downloader_utorrent']}> uTorrent -->
</fieldset>
<fieldset id="torrent_blackhole_options">
<div class="row">
<label>Black Hole Directory</label>
<input type="text" name="torrentblackhole_dir" value="${config['torrentblackhole_dir']}" size="50">
<small>Folder your Download program watches for Torrents</small>
</div>
</fieldset>
<fieldset id="transmission_options">
<div class="row">
<label>Transmission Host:</label>
<input type="text" name="transmission_host" value="${config['transmission_host']}" size="30">
<small>usually http://localhost:9091</small>
</div>
<div class="row">
<label>Transmission Username:</label>
<input type="text" name="transmission_username" value="${config['transmission_user']}" size="30">
</div>
<div class="row">
<label>Transmission Password:</label>
<input type="password" name="transmission_password" value="${config['transmission_pass']}" size="30">
</div>
<div class="row">
<small>Note: With Transmission, you can specify a different download directory for downloads sent from Headphones.
Set it in the Music Download Directory below</small></div>
</fieldset>
<fieldset id="utorrent_options">
<div class="row">
<label>uTorrent Host:</label>
<input type="text" name="utorrent_host" value="${config['utorrent_host']}" size="30">
<small>usually http://localhost:9091</small>
</div>
<div class="row">
<label>uTorrent Username:</label>
<input type="text" name="utorrent_username" value="${config['utorrent_user']}" size="30">
</div>
<div class="row">
<label>uTorrent Password:</label>
<input type="text" name="utorrent_password" value="${config['utorrent_pass']}" size="30">
</div>
</fieldset>
<fieldset id="general_torrent_options">
<div class="row">
<label>Minimum seeders:</label>
<input type="text" name="numberofseeders" value="${config['numberofseeders']}" size="5">
<small>Number of minimum seeders a torrent must have to be accepted</small>
</div>
<div class="row">
<label>Music Download Directory</label>
<input type="text" name="download_torrent_dir" value="${config['download_torrent_dir']}" size="50">
<small>Full path where your torrent client downloads your music e.g. /Users/name/Downloads/music</small>
</div>
<div class="row checkbox">
<label>Keep Files for Seeding</label>
<input type="checkbox" name="keep_torrent_files" value="1" ${config['keep_torrent_files']}>
</div>
</fieldset>
</td>
</tr>
@@ -315,14 +355,18 @@
<td>
<fieldset>
<legend>Torrents</legend>
<div class="row checkbox">
<input type="checkbox" name="use_isohunt" value="1" ${config['use_isohunt']} /><label>Isohunt</label>
<div class="row checkbox">
<input type="checkbox" name="use_piratebay" value="1" ${config['use_piratebay']} /><label>The Pirate Bay</label>
</div>
<div class="row checkbox">
<input type="checkbox" name="use_isohunt" value="1" ${config['use_isohunt']} /><label>Isohunt</label>
</div>
<div class="row checkbox">
<input type="checkbox" name="use_mininova" value="1" ${config['use_mininova']} /><label>Mininova</label>
</div>
<div class="row checkbox">
<input type="checkbox" name="use_kat" value="1" ${config['use_kat']} /><label>Kick Ass Torrents</label></div>
<input type="checkbox" name="use_kat" value="1" ${config['use_kat']} /><label>Kick Ass Torrents</label>
</div>
<div class="row checkbox">
<input id="usewaffles" type="checkbox" name="waffles" onclick="initConfigCheckbox($(this));" value="1" ${config['use_waffles']} /><label>Waffles.fm</label>
</div>
@@ -1068,6 +1112,22 @@
$("#sabnzbd_options,#nzbget_options").hide();
$("#blackhole_options").show();
}
if ($("#torrent_downloader_blackhole").is(":checked"))
{
$("#transmission_options,#utorrent_options").hide();
$("#torrent_blackhole_options").show();
}
if ($("#torrent_downloader_transmission").is(":checked"))
{
$("#torrent_blackhole_options,#utorrent_options").hide();
$("#transmission_options").show();
}
if ($("#torrent_downloader_utorrent").is(":checked"))
{
$("#torrent_blackhole_options,#transmission_options").hide();
$("#utorrent_options").show();
}
$('input[type=radio]').change(function(){
if ($("#preferred_bitrate").is(":checked"))
@@ -1098,7 +1158,19 @@
{
$("#sabnzbd_options,#nzbget_options").fadeOut("fast", function() { $("#blackhole_options").fadeIn() });
}
});
if ($("#torrent_downloader_blackhole").is(":checked"))
{
$("#transmission_options,#utorrent_options").fadeOut("fast", function() { $("#torrent_blackhole_options").fadeIn() });
}
if ($("#torrent_downloader_transmission").is(":checked"))
{
$("#torrent_blackhole_options,#utorrent_options").fadeOut("fast", function() { $("#transmission_options").fadeIn() });
}
if ($("#torrent_downloader_utorrent").is(":checked"))
{
$("#torrent_blackhole_options,#transmission_options").fadeOut("fast", function() { $("#utorrent_options").fadeIn() });
}
});
$("#mirror").change(handleNewServerSelection);
handleNewServerSelection.apply($("#mirror"));

View File

@@ -109,7 +109,8 @@ ADD_ALBUM_ART = False
ALBUM_ART_FORMAT = None
EMBED_ALBUM_ART = False
EMBED_LYRICS = False
NZB_DOWNLOADER = None
NZB_DOWNLOADER = None # 0: sabnzbd, 1: nzbget, 2: blackhole
TORRENT_DOWNLOADER = None # 0: blackhole, 1: transmission, 2: utorrent
DOWNLOAD_DIR = None
BLACKHOLE = None
BLACKHOLE_DIR = None
@@ -138,9 +139,13 @@ NZBGET_HOST = None
HEADPHONES_INDEXER = False
NZBMATRIX = False
NZBMATRIX_USERNAME = None
NZBMATRIX_APIKEY = None
TRANSMISSION_HOST = None
TRANSMISSION_USERNAME = None
TRANSMISSION_PASSWORD = None
UTORRENT_HOST = None
UTORRENT_USERNAME = None
UTORRENT_PASSWORD = None
NEWZNAB = False
NEWZNAB_HOST = None
@@ -152,10 +157,6 @@ NZBSORG = False
NZBSORG_UID = None
NZBSORG_HASH = None
NEWZBIN = False
NEWZBIN_UID = None
NEWZBIN_PASSWORD = None
NZBSRUS = False
NZBSRUS_UID = None
NZBSRUS_APIKEY = None
@@ -177,6 +178,7 @@ NUMBEROFSEEDERS = 10
ISOHUNT = None
KAT = None
MININOVA = None
PIRATEBAY = None
WAFFLES = None
WAFFLES_UID = None
WAFFLES_PASSKEY = None
@@ -290,19 +292,18 @@ def initialize():
LOSSLESS_DESTINATION_DIR, PREFERRED_QUALITY, PREFERRED_BITRATE, DETECT_BITRATE, ADD_ARTISTS, CORRECT_METADATA, MOVE_FILES, \
RENAME_FILES, FOLDER_FORMAT, FILE_FORMAT, CLEANUP_FILES, INCLUDE_EXTRAS, EXTRAS, AUTOWANT_UPCOMING, AUTOWANT_ALL, KEEP_TORRENT_FILES, \
ADD_ALBUM_ART, ALBUM_ART_FORMAT, EMBED_ALBUM_ART, EMBED_LYRICS, DOWNLOAD_DIR, BLACKHOLE, BLACKHOLE_DIR, USENET_RETENTION, SEARCH_INTERVAL, \
TORRENTBLACKHOLE_DIR, NUMBEROFSEEDERS, ISOHUNT, KAT, MININOVA, WAFFLES, WAFFLES_UID, WAFFLES_PASSKEY, \
TORRENTBLACKHOLE_DIR, NUMBEROFSEEDERS, ISOHUNT, KAT, PIRATEBAY, MININOVA, WAFFLES, WAFFLES_UID, WAFFLES_PASSKEY, \
RUTRACKER, RUTRACKER_USER, RUTRACKER_PASSWORD, WHATCD, WHATCD_USERNAME, WHATCD_PASSWORD, DOWNLOAD_TORRENT_DIR, \
LIBRARYSCAN, LIBRARYSCAN_INTERVAL, DOWNLOAD_SCAN_INTERVAL, SAB_HOST, SAB_USERNAME, SAB_PASSWORD, SAB_APIKEY, SAB_CATEGORY, \
NZBGET_USERNAME, NZBGET_PASSWORD, NZBGET_CATEGORY, NZBGET_HOST, HEADPHONES_INDEXER, NZBMATRIX, NZBMATRIX_USERNAME, NZBMATRIX_APIKEY, NEWZNAB, NEWZNAB_HOST, NEWZNAB_APIKEY, NEWZNAB_ENABLED, EXTRA_NEWZNABS, \
NZBSORG, NZBSORG_UID, NZBSORG_HASH, NEWZBIN, NEWZBIN_UID, NEWZBIN_PASSWORD, NZBSRUS, NZBSRUS_UID, NZBSRUS_APIKEY, \
NZB_DOWNLOADER, PREFERRED_WORDS, REQUIRED_WORDS, IGNORED_WORDS, \
NZBGET_USERNAME, NZBGET_PASSWORD, NZBGET_CATEGORY, NZBGET_HOST, HEADPHONES_INDEXER, NZBMATRIX, TRANSMISSION_HOST, TRANSMISSION_USERNAME, TRANSMISSION_PASSWORD, \
UTORRENT_HOST, UTORRENT_USERNAME, UTORRENT_PASSWORD, NEWZNAB, NEWZNAB_HOST, NEWZNAB_APIKEY, NEWZNAB_ENABLED, EXTRA_NEWZNABS, \
NZBSORG, NZBSORG_UID, NZBSORG_HASH, NZBSRUS, NZBSRUS_UID, NZBSRUS_APIKEY, NZB_DOWNLOADER, TORRENT_DOWNLOADER, PREFERRED_WORDS, REQUIRED_WORDS, IGNORED_WORDS, \
LASTFM_USERNAME, INTERFACE, FOLDER_PERMISSIONS, ENCODERFOLDER, ENCODER_PATH, ENCODER, XLDPROFILE, BITRATE, SAMPLINGFREQUENCY, \
MUSIC_ENCODER, ADVANCEDENCODER, ENCODEROUTPUTFORMAT, ENCODERQUALITY, ENCODERVBRCBR, ENCODERLOSSLESS, DELETE_LOSSLESS_FILES, \
PROWL_ENABLED, PROWL_PRIORITY, PROWL_KEYS, PROWL_ONSNATCH, PUSHOVER_ENABLED, PUSHOVER_PRIORITY, PUSHOVER_KEYS, PUSHOVER_ONSNATCH, MIRRORLIST, \
MIRROR, CUSTOMHOST, CUSTOMPORT, CUSTOMSLEEP, HPUSER, HPPASS, XBMC_ENABLED, XBMC_HOST, XBMC_USERNAME, XBMC_PASSWORD, XBMC_UPDATE, \
XBMC_NOTIFY, NMA_ENABLED, NMA_APIKEY, NMA_PRIORITY, NMA_ONSNATCH, SYNOINDEX_ENABLED, ALBUM_COMPLETION_PCT, PREFERRED_BITRATE_HIGH_BUFFER, \
PREFERRED_BITRATE_LOW_BUFFER, PREFERRED_BITRATE_ALLOW_LOSSLESS, CACHE_SIZEMB, \
UMASK
PREFERRED_BITRATE_LOW_BUFFER, PREFERRED_BITRATE_ALLOW_LOSSLESS, CACHE_SIZEMB, UMASK
if __INITIALIZED__:
return False
@@ -311,12 +312,12 @@ def initialize():
CheckSection('General')
CheckSection('SABnzbd')
CheckSection('NZBget')
CheckSection('Transmission')
CheckSection('uTorrent')
CheckSection('Headphones')
CheckSection('NZBMatrix')
CheckSection('Newznab')
CheckSection('NZBsorg')
CheckSection('NZBsRus')
CheckSection('Newzbin')
CheckSection('Waffles')
CheckSection('Rutracker')
CheckSection('What.cd')
@@ -377,6 +378,7 @@ def initialize():
EMBED_ALBUM_ART = bool(check_setting_int(CFG, 'General', 'embed_album_art', 0))
EMBED_LYRICS = bool(check_setting_int(CFG, 'General', 'embed_lyrics', 0))
NZB_DOWNLOADER = check_setting_int(CFG, 'General', 'nzb_downloader', 0)
TORRENT_DOWNLOADER = check_setting_int(CFG, 'General', 'torrent_downloader', 0)
DOWNLOAD_DIR = check_setting_str(CFG, 'General', 'download_dir', '')
BLACKHOLE = bool(check_setting_int(CFG, 'General', 'blackhole', 0))
BLACKHOLE_DIR = check_setting_str(CFG, 'General', 'blackhole_dir', '')
@@ -396,6 +398,7 @@ def initialize():
NUMBEROFSEEDERS = check_setting_str(CFG, 'General', 'numberofseeders', '10')
ISOHUNT = bool(check_setting_int(CFG, 'General', 'isohunt', 0))
KAT = bool(check_setting_int(CFG, 'General', 'kat', 0))
PIRATEBAY = bool(check_setting_int(CFG, 'General', 'piratebay', 0))
MININOVA = bool(check_setting_int(CFG, 'General', 'mininova', 0))
DOWNLOAD_TORRENT_DIR = check_setting_str(CFG, 'General', 'download_torrent_dir', '')
@@ -424,9 +427,13 @@ def initialize():
HEADPHONES_INDEXER = bool(check_setting_int(CFG, 'Headphones', 'headphones_indexer', 0))
NZBMATRIX = bool(check_setting_int(CFG, 'NZBMatrix', 'nzbmatrix', 0))
NZBMATRIX_USERNAME = check_setting_str(CFG, 'NZBMatrix', 'nzbmatrix_username', '')
NZBMATRIX_APIKEY = check_setting_str(CFG, 'NZBMatrix', 'nzbmatrix_apikey', '')
TRANSMISSION_HOST = check_setting_str(CFG, 'Transmission', 'transmission_host', '')
TRANSMISSION_USERNAME = check_setting_str(CFG, 'Transmission', 'transmission_username', '')
TRANSMISSION_PASSWORD = check_setting_str(CFG, 'Transmission', 'transmission_password', '')
UTORRENT_HOST = check_setting_str(CFG, 'uTorrent', 'utorrent_host', '')
UTORRENT_USERNAME = check_setting_str(CFG, 'uTorrent', 'utorrent_username', '')
UTORRENT_PASSWORD = check_setting_str(CFG, 'uTorrent', 'utorrent_password', '')
NEWZNAB = bool(check_setting_int(CFG, 'Newznab', 'newznab', 0))
NEWZNAB_HOST = check_setting_str(CFG, 'Newznab', 'newznab_host', '')
@@ -441,10 +448,6 @@ def initialize():
NZBSORG_UID = check_setting_str(CFG, 'NZBsorg', 'nzbsorg_uid', '')
NZBSORG_HASH = check_setting_str(CFG, 'NZBsorg', 'nzbsorg_hash', '')
NEWZBIN = bool(check_setting_int(CFG, 'Newzbin', 'newzbin', 0))
NEWZBIN_UID = check_setting_str(CFG, 'Newzbin', 'newzbin_uid', '')
NEWZBIN_PASSWORD = check_setting_str(CFG, 'Newzbin', 'newzbin_password', '')
NZBSRUS = bool(check_setting_int(CFG, 'NZBsRus', 'nzbsrus', 0))
NZBSRUS_UID = check_setting_str(CFG, 'NZBsRus', 'nzbsrus_uid', '')
NZBSRUS_APIKEY = check_setting_str(CFG, 'NZBsRus', 'nzbsrus_apikey', '')
@@ -727,6 +730,7 @@ def config_write():
new_config['General']['embed_album_art'] = int(EMBED_ALBUM_ART)
new_config['General']['embed_lyrics'] = int(EMBED_LYRICS)
new_config['General']['nzb_downloader'] = NZB_DOWNLOADER
new_config['General']['torrent_downloader'] = TORRENT_DOWNLOADER
new_config['General']['download_dir'] = DOWNLOAD_DIR
new_config['General']['blackhole_dir'] = BLACKHOLE_DIR
new_config['General']['usenet_retention'] = USENET_RETENTION
@@ -741,6 +745,7 @@ def config_write():
new_config['General']['isohunt'] = int(ISOHUNT)
new_config['General']['kat'] = int(KAT)
new_config['General']['mininova'] = int(MININOVA)
new_config['General']['piratebay'] = int(PIRATEBAY)
new_config['General']['download_torrent_dir'] = DOWNLOAD_TORRENT_DIR
new_config['Waffles'] = {}
@@ -775,14 +780,19 @@ def config_write():
new_config['NZBget']['nzbget_password'] = NZBGET_PASSWORD
new_config['NZBget']['nzbget_category'] = NZBGET_CATEGORY
new_config['NZBget']['nzbget_host'] = NZBGET_HOST
new_config['Headphones'] = {}
new_config['Headphones']['headphones_indexer'] = int(HEADPHONES_INDEXER)
new_config['NZBMatrix'] = {}
new_config['NZBMatrix']['nzbmatrix'] = int(NZBMATRIX)
new_config['NZBMatrix']['nzbmatrix_username'] = NZBMATRIX_USERNAME
new_config['NZBMatrix']['nzbmatrix_apikey'] = NZBMATRIX_APIKEY
new_config['Transmission'] = {}
new_config['Transmission']['transmission_host'] = TRANSMISSION_HOST
new_config['Transmission']['transmission_username'] = TRANSMISSION_USERNAME
new_config['Transmission']['transmission_password'] = TRANSMISSION_PASSWORD
new_config['uTorrent'] = {}
new_config['uTorrent']['utorrent_host'] = UTORRENT_HOST
new_config['uTorrent']['utorrent_username'] = UTORRENT_USERNAME
new_config['uTorrent']['utorrent_password'] = UTORRENT_PASSWORD
new_config['Newznab'] = {}
new_config['Newznab']['newznab'] = int(NEWZNAB)
@@ -802,11 +812,6 @@ def config_write():
new_config['NZBsorg']['nzbsorg_uid'] = NZBSORG_UID
new_config['NZBsorg']['nzbsorg_hash'] = NZBSORG_HASH
new_config['Newzbin'] = {}
new_config['Newzbin']['newzbin'] = int(NEWZBIN)
new_config['Newzbin']['newzbin_uid'] = NEWZBIN_UID
new_config['Newzbin']['newzbin_password'] = NEWZBIN_PASSWORD
new_config['NZBsRus'] = {}
new_config['NZBsRus']['nzbsrus'] = int(NZBSRUS)
new_config['NZBsRus']['nzbsrus_uid'] = NZBSRUS_UID

View File

@@ -142,6 +142,23 @@ def mb_to_bytes(mb_str):
result = re.search('^(\d+(?:\.\d+)?)\s?(?:mb)?', mb_str, flags=re.I)
if result:
return int(float(result.group(1))*1048576)
def piratesize(size):
split = size.split(" ")
factor = float(split[0])
unit = split[1]
if unit == 'MiB':
size = factor * 1048576
elif unit == 'GiB':
size = factor * 1073741824
elif unit == 'KiB':
size = factor * 1024
elif unit == "B":
size = factor
else:
size = 0
return size
def replace_all(text, dic):

View File

@@ -28,7 +28,10 @@ def libraryScan(dir=None, append=False, ArtistID=None, ArtistName=None, cron=Fal
return
if not dir:
dir = headphones.MUSIC_DIR
if not headphones.MUSIC_DIR:
return
else:
dir = headphones.MUSIC_DIR
# If we're appending a dir, it's coming from the post processor which is
# already bytestring

View File

@@ -320,14 +320,28 @@ def doPostProcessing(albumid, albumpath, release, tracks, downloaded_track_list,
logger.info('Starting post-processing for: %s - %s' % (release['ArtistName'], release['AlbumTitle']))
# Check to see if we're preserving the torrent dir
if headphones.KEEP_TORRENT_FILES and Kind=="torrent":
new_folder = os.path.join(os.path.dirname(albumpath), ('temp' + release['AlbumTitle'][:8]).encode(headphones.SYS_ENCODING, 'replace'))
new_folder = new_folder.strip()
new_folder = os.path.join(albumpath, 'headphones-modified').encode(headphones.SYS_ENCODING, 'replace')
logger.info("Copying files to 'headphones-modified' subfolder to preserve downleaded files for seeding")
try:
shutil.copytree(albumpath, new_folder)
# Update the album path with the new location
albumpath = new_folder
except Exception, e:
logger.warn("Cannot copy/move files to temp folder: " + new_folder.decode(headphones.SYS_ENCODING, 'replace') + ". Not continuing. Error: " + str(e))
return
# Need to update the downloaded track list with the new location.
# Could probably just throw in the "headphones-modified" folder,
# but this is good to make sure we're not counting files that may have failed to move
downloaded_track_list = []
downloaded_cuecount = 0
for r,d,f in os.walk(albumpath):
for files in f:
if any(files.lower().endswith('.' + x.lower()) for x in headphones.MEDIA_FORMATS):
downloaded_track_list.append(os.path.join(r, files))
elif files.lower().endswith('.cue'):
downloaded_cuecount += 1
#start encoding
if headphones.MUSIC_ENCODER:
downloaded_track_list=music_encoder.encode(albumpath)
@@ -860,6 +874,9 @@ def forcePostProcess():
# Get a list of folders in the download_dir
folders = []
for download_dir in download_dirs:
if not os.path.isdir(download_dir):
logger.warn('Directory ' + download_dir.decode(headphones.SYS_ENCODING, 'replace') + ' does not exist. Skipping')
continue
for folder in os.listdir(download_dir):
path_to_folder = os.path.join(download_dir, folder)
if os.path.isdir(path_to_folder):

View File

@@ -17,6 +17,7 @@
import urllib, urllib2, urlparse, httplib
import lib.feedparser as feedparser
from bs4 import BeautifulSoup
from lib.pygazelle import api as gazelleapi
from lib.pygazelle import encoding as gazelleencoding
from lib.pygazelle import format as gazelleformat
@@ -32,6 +33,7 @@ import string
import headphones, exceptions
from headphones import logger, db, helpers, classes, sab, nzbget
from headphones import transmission
import lib.bencode as bencode
@@ -117,7 +119,7 @@ def searchforalbum(albumid=None, new=False, lossless=False):
else:
foundNZB = searchNZB(result['AlbumID'], new)
if (headphones.KAT or headphones.ISOHUNT or headphones.MININOVA or headphones.WAFFLES or headphones.RUTRACKER or headphones.WHATCD) and foundNZB == "none":
if (headphones.KAT or headphones.PIRATEBAY or headphones.ISOHUNT or headphones.MININOVA or headphones.WAFFLES or headphones.RUTRACKER or headphones.WHATCD) and foundNZB == "none":
if result['Status'] == "Wanted Lossless":
searchTorrent(result['AlbumID'], new, losslessOnly=True)
@@ -127,10 +129,11 @@ def searchforalbum(albumid=None, new=False, lossless=False):
else:
foundNZB = "none"
if (headphones.HEADPHONES_INDEXER or headphones.NEWZNAB or headphones.NZBSORG or headphones.NZBSRUS) and (headphones.SAB_HOST or headphones.BLACKHOLE_DIR or headphones.NZBGET_HOST):
foundNZB = searchNZB(albumid, new, lossless)
if (headphones.KAT or headphones.ISOHUNT or headphones.MININOVA or headphones.WAFFLES or headphones.RUTRACKER or headphones.WHATCD) and foundNZB == "none":
if (headphones.KAT or headphones.PIRATEBAY or headphones.ISOHUNT or headphones.MININOVA or headphones.WAFFLES or headphones.RUTRACKER or headphones.WHATCD) and foundNZB == "none":
searchTorrent(albumid, new, lossless)
def searchNZB(albumid=None, new=False, losslessOnly=False):
@@ -483,7 +486,8 @@ def searchNZB(albumid=None, new=False, losslessOnly=False):
for result in resultlist:
if high_size_limit and (result[1] > high_size_limit):
logger.info(result[0] + " is too large for this album - not considering it. (Size: " + helpers.bytes_to_mb(result[1]) + ", Maxsize: " + helpers.bytes_to_mb(high_size_limit))
logger.info(result[0] + " is too large for this album - not considering it. (Size: " + helpers.bytes_to_mb(result[1]) + ", Maxsize: " + helpers.bytes_to_mb(high_size_limit) + ")")
# Add lossless nzbs to the "flac list" which we can use if there are no good lossy matches
if 'flac' in result[0].lower():
@@ -492,7 +496,7 @@ def searchNZB(albumid=None, new=False, losslessOnly=False):
continue
if low_size_limit and (result[1] < low_size_limit):
logger.info(result[0] + " is too small for this album - not considering it. (Size: " + helpers.bytes_to_mb(result[1]) + ", Minsize: " + helpers.bytes_to_mb(low_size_limit))
logger.info(result[0] + " is too small for this album - not considering it. (Size: " + helpers.bytes_to_mb(result[1]) + ", Minsize: " + helpers.bytes_to_mb(low_size_limit) + ")")
continue
delta = abs(targetsize - result[1])
@@ -1068,6 +1072,58 @@ def searchTorrent(albumid=None, new=False, losslessOnly=False):
gazelle.generate_torrent_link(torrent.id),
provider))
# Pirate Bay
if headphones.PIRATEBAY and headphones.TORRENT_DOWNLOADER != 0:
provider = "The Pirate Bay"
providerurl = url_fix("http://thepiratebay.sx/search/" + term + "/0/99/")
if headphones.PREFERRED_QUALITY == 3 or losslessOnly:
category = '104' #flac
maxsize = 10000000000
elif headphones.PREFERRED_QUALITY:
category = '100' #audio cat
maxsize = 10000000000
else:
category = '101' #mp3
maxsize = 300000000
searchURL = providerurl + category
try:
data = urllib2.urlopen(searchURL, timeout=20).read()
except urllib2.URLError, e:
logger.warn('Error fetching data from The Pirate Bay: %s' % e)
data = False
if data:
logger.info(u'Parsing results from <a href="%s">The Pirate Bay</a>' % searchURL)
soup = BeautifulSoup(data)
table = soup.find('table')
rows = table.findAll('tr')
if len(rows) == '1':
logger.info(u"No results found from %s for %s" % (provider, term))
pass
else:
for item in rows[1:]:
try:
rightformat = True
title = ''.join(item.find("a", {"class" : "detLink"}))
seeds = int(''.join(item.find("td", {"align" : "right"})))
url = item.findAll("a")[3]['href']
formatted_size = re.search('Size (.*),', unicode(item)).group(1).replace(u'\xa0', ' ')
size = helpers.piratesize(formatted_size)
if size < maxsize and minimumseeders < seeds:
resultlist.append((title, size, url, provider))
logger.info('Found %s. Size: %s' % (title, formatted_size))
else:
logger.info('%s is larger than the maxsize or has too little seeders for this category, skipping. (Size: %i bytes, Seeders: %i)' % (title, size, int(seeds)))
except Exception, e:
logger.error(u"An unknown error occurred in the Pirate Bay parser: %s" % e)
if headphones.ISOHUNT:
provider = "isoHunt"
providerurl = url_fix("http://isohunt.com/js/rss/" + term)
@@ -1220,8 +1276,18 @@ def searchTorrent(albumid=None, new=False, losslessOnly=False):
resultlist[:] = [result for result in resultlist if verifyresult(result[0], artistterm, term, losslessOnly)]
if len(resultlist):
if headphones.PREFERRED_QUALITY == 2 and headphones.PREFERRED_BITRATE and not pre_sorted_results:
# Add a priority if it has any of the preferred words
temp_list = []
for result in resultlist:
if any(word.lower() in result[0].lower() for word in helpers.split_string(headphones.PREFERRED_WORDS)):
temp_list.append((result[0],result[1],result[2],result[3],1))
else:
temp_list.append((result[0],result[1],result[2],result[3],0))
resultlist = temp_list
if headphones.PREFERRED_QUALITY == 2 and headphones.PREFERRED_BITRATE:
logger.debug('Target bitrate: %s kbps' % headphones.PREFERRED_BITRATE)
@@ -1231,31 +1297,59 @@ def searchTorrent(albumid=None, new=False, losslessOnly=False):
albumlength = sum([pair[0] for pair in tracks])
targetsize = albumlength/1000 * int(headphones.PREFERRED_BITRATE) * 128
logger.info('Target size: %s' % helpers.bytes_to_mb(targetsize))
newlist = []
for result in resultlist:
delta = abs(targetsize - result[1])
newlist.append((result[0], result[1], result[2], result[3], delta))
torrentlist = sorted(newlist, key=lambda title: title[4])
if not targetsize:
logger.info('No track information for %s - %s. Defaulting to highest quality' % (albums[0], albums[1]))
torrentlist = sorted(resultlist, key=lambda title: (-title[4] , -title[1]))
else:
logger.info('Target size: %s' % helpers.bytes_to_mb(targetsize))
newlist = []
flac_list = []
if headphones.PREFERRED_BITRATE_HIGH_BUFFER:
high_size_limit = targetsize * int(headphones.PREFERRED_BITRATE_HIGH_BUFFER)/100
else:
high_size_limit = None
if headphones.PREFERRED_BITRATE_LOW_BUFFER:
low_size_limit = targetsize * int(headphones.PREFERRED_BITRATE_LOW_BUFFER)/100
else:
low_size_limit = None
for result in resultlist:
if high_size_limit and (result[1] > high_size_limit):
logger.info(result[0] + " is too large for this album - not considering it. (Size: " + helpers.bytes_to_mb(result[1]) + ", Maxsize: " + helpers.bytes_to_mb(high_size_limit) + ")")
# Add lossless nzbs to the "flac list" which we can use if there are no good lossy matches
if 'flac' in result[0].lower():
flac_list.append((result[0], result[1], result[2], result[3], result[4]))
continue
if low_size_limit and (result[1] < low_size_limit):
logger.info(result[0] + " is too small for this album - not considering it. (Size: " + helpers.bytes_to_mb(result[1]) + ", Minsize: " + helpers.bytes_to_mb(low_size_limit) + ")")
continue
delta = abs(targetsize - result[1])
newlist.append((result[0], result[1], result[2], result[3], result[4], delta))
torrentlist = sorted(newlist, key=lambda title: (-title[4], title[5]))
if not len(torrentlist) and len(flac_list) and headphones.PREFERRED_BITRATE_ALLOW_LOSSLESS:
logger.info("Since there were no appropriate lossy matches (and at least one lossless match), going to use lossless instead")
torrentlist = sorted(flac_list, key=lambda title: (-title[4], -title[1]))
except Exception, e:
logger.debug('Error: %s' % str(e))
logger.info('No track information for %s - %s. Defaulting to highest quality' % (albums[0], albums[1]))
torrentlist = sorted(resultlist, key=lambda title: title[1], reverse=True)
elif pre_sorted_results:
torrentlist = resultlist
torrentlist = sorted(resultlist, key=lambda title: (-title[4], -title[1]))
else:
torrentlist = sorted(resultlist, key=lambda title: title[1], reverse=True)
torrentlist = sorted(resultlist, key=lambda title: (-title[4], -title[1]))
if new:
@@ -1281,16 +1375,12 @@ def searchTorrent(albumid=None, new=False, losslessOnly=False):
if data and bestqual:
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])))
torrent_folder_name = '%s - %s [%s]' % (helpers.latinToAscii(albums[0]).encode('UTF-8').replace('/', '_'), helpers.latinToAscii(albums[1]).encode('UTF-8').replace('/', '_'), year)
if headphones.TORRENTBLACKHOLE_DIR == "sendtracker":
torrent = classes.TorrentDataSearchResult()
torrent.extraInfo.append(data)
torrent.name = torrent_folder_name
sab.sendTorrent(torrent)
elif headphones.TORRENTBLACKHOLE_DIR != "":
torrent_folder_name = '%s - %s [%s]' % (helpers.latinToAscii(albums[0]).encode('UTF-8').replace('/', '_'), helpers.latinToAscii(albums[1]).encode('UTF-8').replace('/', '_'), year)
# Blackhole
if headphones.TORRENT_DOWNLOADER == 0:
# Get torrent name from .torrent, this is usually used by the torrent client as the folder name
torrent_name = torrent_folder_name + '.torrent'
@@ -1318,6 +1408,11 @@ def searchTorrent(albumid=None, new=False, losslessOnly=False):
except Exception, e:
logger.error('Couldn\'t get name from Torrent file: %s' % e)
break
elif headphones.TORRENT_DOWNLOADER == 1:
logger.info("Sending torrent to Transmission")
torrentid = transmission.addTorrent(bestqual[2])
torrent_folder_name = transmission.getTorrentFolder(torrentid)
myDB.action('UPDATE albums SET status = "Snatched" WHERE AlbumID=?', [albums[2]])
myDB.action('INSERT INTO snatched VALUES( ?, ?, ?, ?, DATETIME("NOW", "localtime"), ?, ?, ?)', [albums[2], bestqual[0], bestqual[1], bestqual[2], "Snatched", torrent_folder_name, "torrent"])
@@ -1330,9 +1425,10 @@ def preprocesstorrent(resultlist, pre_sorted_list=False):
elif int(selresult[1]) < int(result[1]): # if size is lower than new result replace previous selected result (bigger size = better quality?)
selresult = result
# get outta here if rutracker
if selresult[3] == 'rutracker.org':
# get outta here if rutracker or piratebay, or if we're using Transmission or uTorrent
if selresult[3] == 'rutracker.org' or selresult[3] == 'The Pirate Bay':
return True, selresult
if headphones.TORRENT_DOWNLOADER != 0:
return True, selresult
if pre_sorted_list:

121
headphones/transmission.py Normal file
View File

@@ -0,0 +1,121 @@
# 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 headphones
from headphones import logger, notifiers
import urllib2
import lib.simplejson as json
import base64
import time
# This is just a simple script to send torrents to transmission. The
# intention is to turn this into a class where we can check the state
# of the download, set the download dir, etc.
# TODO: Store the session id so we don't need to make 2 calls
# Store torrent id so we can check up on it
def addTorrent(link):
method = 'torrent-add'
arguments = {'filename': link, 'download-dir':headphones.DOWNLOAD_TORRENT_DIR}
response = torrentAction(method,arguments)
if response['result'] == 'success':
name = response['arguments']['torrent-added']['name']
logger.info(u"Torrent sent to Transmission successfully")
if headphones.PROWL_ENABLED and headphones.PROWL_ONSNATCH:
logger.info(u"Sending Prowl notification")
prowl = notifiers.PROWL()
prowl.notify(name,"Download started")
if headphones.PUSHOVER_ENABLED and headphones.PUSHOVER_ONSNATCH:
logger.info(u"Sending Pushover notification")
prowl = notifiers.PUSHOVER()
prowl.notify(name,"Download started")
if headphones.NMA_ENABLED and headphones.NMA_ONSNATCH:
logger.debug(u"Sending NMA notification")
nma = notifiers.NMA()
nma.notify(snatched_nzb=name)
return response['arguments']['torrent-added']['id']
def getTorrentFolder(torrentid):
method = 'torrent-get'
arguments = { 'ids': torrentid, 'fields': ['name','percentDone']}
response = torrentAction(method, arguments)
percentdone = response['arguments']['torrents'][0]['percentDone']
torrent_folder_name = response['arguments']['torrents'][0]['name']
print torrent_folder_name
while percentdone == 0:
print "In the while loop"
time.sleep(5)
response = torrentAction(method, arguments)
percentdone = response['arguments']['torrents'][0]['percentDone']
print "Attempting to get folder name, percent done: " + str(percentdone)
torrent_folder_name = response['arguments']['torrents'][0]['name']
print torrent_folder_name + " updated and finished!"
return torrent_folder_name
def torrentAction(method, arguments):
host = headphones.TRANSMISSION_HOST
username = headphones.TRANSMISSION_USERNAME
password = headphones.TRANSMISSION_PASSWORD
sessionid = None
if not host.startswith('http'):
host = 'http://' + host
if host.endswith('/'):
host = host[:-1]
host = host + "/transmission/rpc"
request = urllib2.Request(host)
if username and password:
base64string = base64.encodestring('%s:%s' % (username, password)).replace('\n', '')
request.add_header("Authorization", "Basic %s" % base64string)
opener = urllib2.build_opener()
try:
data = opener.open(request).read()
except urllib2.HTTPError, e:
if e.code == 409:
sessionid = e.hdrs['x-transmission-session-id']
else:
logger.error('Could not connect to Transmission. Error: ' + str(e))
except Exception, e:
logger.error('Could not connect to Transmission. Error: ' + str(e))
if not sessionid:
logger.error("Error getting Session ID from Transmission")
return
request.add_header('x-transmission-session-id', sessionid)
postdata = json.dumps({ 'method': method,
'arguments': arguments })
request.add_data(postdata)
try:
response = json.loads(opener.open(request).read())
except Exception, e:
logger.error("Error sending torrent to Transmission: " + str(e))
return
return response

14
headphones/utorrent.py Normal file
View File

@@ -0,0 +1,14 @@
# 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/>.

View File

@@ -579,9 +579,18 @@ class WebInterface(object):
"nzbget_user" : headphones.NZBGET_USERNAME,
"nzbget_pass" : headphones.NZBGET_PASSWORD,
"nzbget_cat" : headphones.NZBGET_CATEGORY,
"transmission_host" : headphones.TRANSMISSION_HOST,
"transmission_user" : headphones.TRANSMISSION_USERNAME,
"transmission_pass" : headphones.TRANSMISSION_PASSWORD,
"utorrent_host" : headphones.UTORRENT_HOST,
"utorrent_user" : headphones.UTORRENT_USERNAME,
"utorrent_pass" : headphones.UTORRENT_PASSWORD,
"nzb_downloader_sabnzbd" : radio(headphones.NZB_DOWNLOADER, 0),
"nzb_downloader_nzbget" : radio(headphones.NZB_DOWNLOADER, 1),
"nzb_downloader_blackhole" : radio(headphones.NZB_DOWNLOADER, 2),
"torrent_downloader_blackhole" : radio(headphones.TORRENT_DOWNLOADER, 0),
"torrent_downloader_transmission" : radio(headphones.TORRENT_DOWNLOADER, 1),
"torrent_downloader_utorrent" : radio(headphones.TORRENT_DOWNLOADER, 2),
"download_dir" : headphones.DOWNLOAD_DIR,
"use_blackhole" : checked(headphones.BLACKHOLE),
"blackhole_dir" : headphones.BLACKHOLE_DIR,
@@ -606,6 +615,7 @@ class WebInterface(object):
"numberofseeders" : headphones.NUMBEROFSEEDERS,
"use_isohunt" : checked(headphones.ISOHUNT),
"use_kat" : checked(headphones.KAT),
"use_piratebay" : checked(headphones.PIRATEBAY),
"use_mininova" : checked(headphones.MININOVA),
"use_waffles" : checked(headphones.WAFFLES),
"waffles_uid" : headphones.WAFFLES_UID,
@@ -703,13 +713,14 @@ class WebInterface(object):
config.exposed = True
<<<<<<< HEAD
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, 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='nzbget', nzbget_password=None, nzbget_category=None, nzb_downloader=0, download_dir=None, blackhole=0, 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, nzbsrus=0, nzbsrus_uid=None, nzbsrus_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,
numberofseeders=10, use_isohunt=0, use_kat=0, use_mininova=0, waffles=0, waffles_uid=None, waffles_passkey=None, whatcd=0, whatcd_username=None, whatcd_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,
utorrent_host=None, utorrent_username=None, utorrent_password=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, nzbsrus=0, nzbsrus_uid=None, nzbsrus_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,
numberofseeders=None, use_piratebay=0, use_isohunt=0, use_kat=0, use_mininova=0, waffles=0, waffles_uid=None, waffles_passkey=None, whatcd=0, whatcd_username=None, whatcd_password=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,
destination_dir=None, lossless_destination_dir=None, folder_format=None, file_format=None, include_extras=0, single=0, ep=0, compilation=0, soundtrack=0, live=0,
remix=0, spokenword=0, audiobook=0, autowant_upcoming=False, autowant_all=False, keep_torrent_files=False, interface=None, log_dir=None, cache_dir=None, music_encoder=0, encoder=None, xldprofile=None,
@@ -738,7 +749,14 @@ class WebInterface(object):
headphones.NZBGET_USERNAME = nzbget_username
headphones.NZBGET_PASSWORD = nzbget_password
headphones.NZBGET_CATEGORY = nzbget_category
headphones.TRANSMISSION_HOST = transmission_host
headphones.TRANSMISSION_USERNAME = transmission_username
headphones.TRANSMISSION_PASSWORD = transmission_password
headphones.UTORRENT_HOST = utorrent_host
headphones.UTORRENT_USERNAME = utorrent_username
headphones.UTORRENT_PASSWORD = utorrent_password
headphones.NZB_DOWNLOADER = int(nzb_downloader)
headphones.TORRENT_DOWNLOADER = int(torrent_downloader)
headphones.DOWNLOAD_DIR = download_dir
headphones.BLACKHOLE = blackhole
headphones.BLACKHOLE_DIR = blackhole_dir
@@ -762,6 +780,7 @@ class WebInterface(object):
headphones.DOWNLOAD_TORRENT_DIR = download_torrent_dir
headphones.ISOHUNT = use_isohunt
headphones.KAT = use_kat
headphones.PIRATEBAY = use_piratebay
headphones.MININOVA = use_mininova
headphones.WAFFLES = waffles
headphones.WAFFLES_UID = waffles_uid