mirror of
https://github.com/rembo10/headphones.git
synced 2026-05-24 12:27:45 +01:00
Bug fixes, added HTTPS support, music encoder fix, sanity checking for
transmission, piratebay torrage support
This commit is contained in:
@@ -15,6 +15,11 @@
|
||||
logs/*
|
||||
cache/*
|
||||
|
||||
# HTTPS Cert/Key #
|
||||
##################
|
||||
*.crt
|
||||
*.key
|
||||
|
||||
# OS generated files #
|
||||
######################
|
||||
.DS_Store?
|
||||
|
||||
+4
-3
@@ -142,7 +142,7 @@ def main():
|
||||
# Force the http port if neccessary
|
||||
if args.port:
|
||||
http_port = args.port
|
||||
logger.info('Starting Headphones on forced port: %i' % http_port)
|
||||
logger.info('Using forced port: %i' % http_port)
|
||||
else:
|
||||
http_port = int(headphones.HTTP_PORT)
|
||||
|
||||
@@ -152,12 +152,13 @@ def main():
|
||||
'http_host': headphones.HTTP_HOST,
|
||||
'http_root': headphones.HTTP_ROOT,
|
||||
'http_proxy': headphones.HTTP_PROXY,
|
||||
'enable_https': headphones.ENABLE_HTTPS,
|
||||
'https_cert': headphones.HTTPS_CERT,
|
||||
'https_key': headphones.HTTPS_KEY,
|
||||
'http_username': headphones.HTTP_USERNAME,
|
||||
'http_password': headphones.HTTP_PASSWORD,
|
||||
})
|
||||
|
||||
logger.info('Starting Headphones on port: %i' % http_port)
|
||||
|
||||
if headphones.LAUNCH_BROWSER and not args.nolaunch:
|
||||
headphones.launch_browser(headphones.HTTP_HOST, http_port, headphones.HTTP_ROOT)
|
||||
|
||||
|
||||
@@ -54,6 +54,19 @@
|
||||
<div class="row checkbox">
|
||||
<input type="checkbox" name="launch_browser" value="1" ${config['launch_browser']} /> <label>Launch Browser on Startup</label>
|
||||
</div>
|
||||
<div class="row checkbox">
|
||||
<input type="checkbox" name="enable_https" id="enable_https" value="1" ${config['enable_https']} /> <label>Enable HTTPS</label>
|
||||
</div>
|
||||
<div id="https_options">
|
||||
<div class="row">
|
||||
<label>HTTPS Cert</label>
|
||||
<input type="text" name="https_cert" value="${config['https_cert']}" size="30">
|
||||
</div>
|
||||
<div class="row">
|
||||
<label>HTTPS Key</label>
|
||||
<input type="text" name="https_key" value="${config['https_key']}" size="30">
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</td>
|
||||
<td>
|
||||
@@ -367,7 +380,7 @@
|
||||
</div>
|
||||
<div class="row">
|
||||
<label>Waffles Passkey: </label>
|
||||
<input type="text" name="waffles_passkey" value="${config['waffles_passkey']}" size="36">
|
||||
<input type="password" name="waffles_passkey" value="${config['waffles_passkey']}" size="36">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row checkbox">
|
||||
@@ -498,6 +511,9 @@
|
||||
<input type="text" name="file_format" value="${config['file_format']}" size="43">
|
||||
<small>Use: $Disc/$disc (disc #), $Track/$track (track #), $Title/$title, $Artist/$artist, $Album/$album and $Year/$year</small>
|
||||
</div>
|
||||
<div class="checkbox row clearfix">
|
||||
<input type="checkbox" name="file_underscores" id="file_underscores" value="1" ${config['file_underscores']}/><label>Use underscores instead of spaces</label>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
@@ -945,6 +961,25 @@
|
||||
$('#api_key').val(data);
|
||||
});
|
||||
});
|
||||
if ($("#enable_https").is(":checked"))
|
||||
{
|
||||
$("#https_options").show();
|
||||
}
|
||||
else
|
||||
{
|
||||
$("#https_options").hide();
|
||||
}
|
||||
|
||||
$("#enable_https").click(function(){
|
||||
if ($("#enable_https").is(":checked"))
|
||||
{
|
||||
$("#https_options").slideDown();
|
||||
}
|
||||
else
|
||||
{
|
||||
$("#https_options").slideUp();
|
||||
}
|
||||
});
|
||||
if ($("#music_encoder").is(":checked"))
|
||||
{
|
||||
$("#encoderoptions").show();
|
||||
@@ -1214,6 +1249,7 @@
|
||||
initConfigCheckbox("#userutracker");
|
||||
initConfigCheckbox("#usewhatcd");
|
||||
initConfigCheckbox("#useapi");
|
||||
initConfigCheckbox("#enable_https");
|
||||
}
|
||||
$(document).ready(function() {
|
||||
initThisPage();
|
||||
|
||||
+21
-3
@@ -73,6 +73,10 @@ HTTP_ROOT = None
|
||||
HTTP_PROXY = False
|
||||
LAUNCH_BROWSER = False
|
||||
|
||||
ENABLE_HTTPS = False
|
||||
HTTPS_CERT = None
|
||||
HTTPS_KEY = None
|
||||
|
||||
API_ENABLED = False
|
||||
API_KEY = None
|
||||
|
||||
@@ -93,6 +97,7 @@ DESTINATION_DIR = None
|
||||
LOSSLESS_DESTINATION_DIR = None
|
||||
FOLDER_FORMAT = None
|
||||
FILE_FORMAT = None
|
||||
FILE_UNDERSCORES = False
|
||||
PATH_TO_XML = None
|
||||
PREFERRED_QUALITY = None
|
||||
PREFERRED_BITRATE = None
|
||||
@@ -291,7 +296,7 @@ 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, \
|
||||
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, \
|
||||
RENAME_FILES, FOLDER_FORMAT, FILE_FORMAT, CLEANUP_FILES, INCLUDE_EXTRAS, EXTRAS, AUTOWANT_UPCOMING, AUTOWANT_ALL, KEEP_TORRENT_FILES, \
|
||||
RENAME_FILES, FOLDER_FORMAT, FILE_FORMAT, FILE_UNDERSCORES, 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, PIRATEBAY, MININOVA, WAFFLES, WAFFLES_UID, WAFFLES_PASSKEY, \
|
||||
RUTRACKER, RUTRACKER_USER, RUTRACKER_PASSWORD, WHATCD, WHATCD_USERNAME, WHATCD_PASSWORD, DOWNLOAD_TORRENT_DIR, \
|
||||
@@ -304,7 +309,7 @@ def initialize():
|
||||
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, JOURNAL_MODE, UMASK
|
||||
PREFERRED_BITRATE_LOW_BUFFER, PREFERRED_BITRATE_ALLOW_LOSSLESS, CACHE_SIZEMB, JOURNAL_MODE, UMASK, ENABLE_HTTPS, HTTPS_CERT, HTTPS_KEY
|
||||
|
||||
if __INITIALIZED__:
|
||||
return False
|
||||
@@ -345,6 +350,9 @@ def initialize():
|
||||
HTTP_PASSWORD = check_setting_str(CFG, 'General', 'http_password', '')
|
||||
HTTP_ROOT = check_setting_str(CFG, 'General', 'http_root', '/')
|
||||
HTTP_PROXY = bool(check_setting_int(CFG, 'General', 'http_proxy', 0))
|
||||
ENABLE_HTTPS = bool(check_setting_int(CFG, 'General', 'enable_https', 0))
|
||||
HTTPS_CERT = check_setting_str(CFG, 'General', 'https_cert', os.path.join(DATA_DIR, 'server.crt'))
|
||||
HTTPS_KEY = check_setting_str(CFG, 'General', 'https_key', os.path.join(DATA_DIR, 'server.key'))
|
||||
LAUNCH_BROWSER = bool(check_setting_int(CFG, 'General', 'launch_browser', 1))
|
||||
API_ENABLED = bool(check_setting_int(CFG, 'General', 'api_enabled', 0))
|
||||
API_KEY = check_setting_str(CFG, 'General', 'api_key', '')
|
||||
@@ -373,6 +381,7 @@ def initialize():
|
||||
RENAME_FILES = bool(check_setting_int(CFG, 'General', 'rename_files', 0))
|
||||
FOLDER_FORMAT = check_setting_str(CFG, 'General', 'folder_format', 'Artist/Album [Year]')
|
||||
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))
|
||||
CLEANUP_FILES = bool(check_setting_int(CFG, 'General', 'cleanup_files', 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')
|
||||
@@ -679,9 +688,14 @@ def launch_browser(host, port, root):
|
||||
|
||||
if host == '0.0.0.0':
|
||||
host = 'localhost'
|
||||
|
||||
if ENABLE_HTTPS:
|
||||
protocol = 'https'
|
||||
else:
|
||||
protocol = 'http'
|
||||
|
||||
try:
|
||||
webbrowser.open('http://%s:%i%s' % (host, port, root))
|
||||
webbrowser.open('%s://%s:%i%s' % (protocol, host, port, root))
|
||||
except Exception, e:
|
||||
logger.error('Could not launch browser: %s' % e)
|
||||
|
||||
@@ -698,6 +712,9 @@ def config_write():
|
||||
new_config['General']['http_password'] = HTTP_PASSWORD
|
||||
new_config['General']['http_root'] = HTTP_ROOT
|
||||
new_config['General']['http_proxy'] = int(HTTP_PROXY)
|
||||
new_config['General']['enable_https'] = int(ENABLE_HTTPS)
|
||||
new_config['General']['https_cert'] = HTTPS_CERT
|
||||
new_config['General']['https_key'] = HTTPS_KEY
|
||||
new_config['General']['launch_browser'] = int(LAUNCH_BROWSER)
|
||||
new_config['General']['api_enabled'] = int(API_ENABLED)
|
||||
new_config['General']['api_key'] = API_KEY
|
||||
@@ -726,6 +743,7 @@ def config_write():
|
||||
new_config['General']['rename_files'] = int(RENAME_FILES)
|
||||
new_config['General']['folder_format'] = FOLDER_FORMAT
|
||||
new_config['General']['file_format'] = FILE_FORMAT
|
||||
new_config['General']['file_underscores'] = int(FILE_UNDERSCORES)
|
||||
new_config['General']['cleanup_files'] = int(CLEANUP_FILES)
|
||||
new_config['General']['add_album_art'] = int(ADD_ALBUM_ART)
|
||||
new_config['General']['album_art_format'] = ALBUM_ART_FORMAT
|
||||
|
||||
@@ -345,3 +345,37 @@ def split_string(mystring):
|
||||
for each_word in mystring.split(','):
|
||||
mylist.append(each_word.strip())
|
||||
return mylist
|
||||
|
||||
def create_https_certificates(ssl_cert, ssl_key):
|
||||
"""
|
||||
Stolen from SickBeard (http://github.com/midgetspy/Sick-Beard):
|
||||
Create self-signed HTTPS certificares and store in paths 'ssl_cert' and 'ssl_key'
|
||||
"""
|
||||
from headphones import logger
|
||||
|
||||
try:
|
||||
from OpenSSL import crypto #@UnresolvedImport
|
||||
from lib.certgen import createKeyPair, createCertRequest, createCertificate, TYPE_RSA, serial #@UnresolvedImport
|
||||
except:
|
||||
logger.warn(u"pyopenssl module missing, please install for https access")
|
||||
return False
|
||||
|
||||
# Create the CA Certificate
|
||||
cakey = createKeyPair(TYPE_RSA, 1024)
|
||||
careq = createCertRequest(cakey, CN='Certificate Authority')
|
||||
cacert = createCertificate(careq, (careq, cakey), serial, (0, 60*60*24*365*10)) # ten years
|
||||
|
||||
cname = 'Headphones'
|
||||
pkey = createKeyPair(TYPE_RSA, 1024)
|
||||
req = createCertRequest(pkey, CN=cname)
|
||||
cert = createCertificate(req, (cacert, cakey), serial, (0, 60*60*24*365*10)) # ten years
|
||||
|
||||
# Save the key and certificate to disk
|
||||
try:
|
||||
open(ssl_key, 'w').write(crypto.dump_privatekey(crypto.FILETYPE_PEM, pkey))
|
||||
open(ssl_cert, 'w').write(crypto.dump_certificate(crypto.FILETYPE_PEM, cert))
|
||||
except:
|
||||
logger.error(u"Error creating SSL key and certificate")
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
@@ -224,9 +224,9 @@ def command(encoder,musicSource,musicDest,albumPath):
|
||||
opts = []
|
||||
if headphones.ADVANCEDENCODER =='':
|
||||
if headphones.ENCODEROUTPUTFORMAT=='ogg':
|
||||
opts.extend(['-acodec libvorbis'])
|
||||
opts.extend(['-acodec', 'libvorbis'])
|
||||
if headphones.ENCODEROUTPUTFORMAT=='m4a':
|
||||
opts.extend(['-strict experimental'])
|
||||
opts.extend(['-strict', 'experimental'])
|
||||
if headphones.ENCODERVBRCBR=='cbr':
|
||||
opts.extend(['-ar', str(headphones.SAMPLINGFREQUENCY), '-ab', str(headphones.BITRATE) + 'k'])
|
||||
elif headphones.ENCODERVBRCBR=='vbr':
|
||||
|
||||
+32
-19
@@ -43,28 +43,31 @@ def checkFolder():
|
||||
|
||||
if album['FolderName']:
|
||||
|
||||
# We're now checking sab config options after sending to determine renaming - but we'll keep the
|
||||
# iterations in just in case we can't read the config for some reason
|
||||
if album['Kind'] == 'nzb':
|
||||
# We're now checking sab config options after sending to determine renaming - but we'll keep the
|
||||
# iterations in just in case we can't read the config for some reason
|
||||
|
||||
nzb_album_possibilities = [ album['FolderName'],
|
||||
sab_replace_dots(album['FolderName']),
|
||||
sab_replace_spaces(album['FolderName']),
|
||||
sab_replace_spaces(sab_replace_dots(album['FolderName']))
|
||||
nzb_album_possibilities = [ album['FolderName'],
|
||||
sab_replace_dots(album['FolderName']),
|
||||
sab_replace_spaces(album['FolderName']),
|
||||
sab_replace_spaces(sab_replace_dots(album['FolderName']))
|
||||
]
|
||||
|
||||
torrent_album_path = os.path.join(headphones.DOWNLOAD_TORRENT_DIR, album['FolderName']).encode(headphones.SYS_ENCODING,'replace')
|
||||
|
||||
for nzb_folder_name in nzb_album_possibilities:
|
||||
|
||||
nzb_album_path = os.path.join(headphones.DOWNLOAD_DIR, nzb_folder_name).encode(headphones.SYS_ENCODING, 'replace')
|
||||
for nzb_folder_name in nzb_album_possibilities:
|
||||
|
||||
nzb_album_path = os.path.join(headphones.DOWNLOAD_DIR, nzb_folder_name).encode(headphones.SYS_ENCODING, 'replace')
|
||||
|
||||
if os.path.exists(nzb_album_path):
|
||||
logger.debug('Found %s in NZB download folder. Verifying....' % album['FolderName'])
|
||||
verify(album['AlbumID'], nzb_album_path, 'nzb')
|
||||
|
||||
if album['Kind'] == 'torrent':
|
||||
|
||||
if os.path.exists(nzb_album_path):
|
||||
logger.debug('Found %s in NZB download folder. Verifying....' % album['FolderName'])
|
||||
verify(album['AlbumID'], nzb_album_path, album['Kind'])
|
||||
|
||||
if os.path.exists(torrent_album_path):
|
||||
logger.debug('Found %s in torrent download folder. Verifying....' % album['FolderName'])
|
||||
verify(album['AlbumID'], torrent_album_path, album['Kind'])
|
||||
torrent_album_path = os.path.join(headphones.DOWNLOAD_TORRENT_DIR, album['FolderName']).encode(headphones.SYS_ENCODING,'replace')
|
||||
|
||||
if os.path.exists(torrent_album_path):
|
||||
logger.debug('Found %s in torrent download folder. Verifying....' % album['FolderName'])
|
||||
verify(album['AlbumID'], torrent_album_path, 'torrent')
|
||||
|
||||
def verify(albumid, albumpath, Kind=None, forced=False):
|
||||
|
||||
@@ -325,7 +328,7 @@ 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(albumpath, 'headphones-modified').encode(headphones.SYS_ENCODING, 'replace')
|
||||
new_folder = os.path.join(albumpath, 'headphones-modified'.encode(headphones.SYS_ENCODING, 'replace'))
|
||||
logger.info("Copying files to 'headphones-modified' subfolder to preserve downloaded files for seeding")
|
||||
try:
|
||||
shutil.copytree(albumpath, new_folder)
|
||||
@@ -464,6 +467,9 @@ def addAlbumArt(artwork, albumpath, release):
|
||||
|
||||
album_art_name = album_art_name.replace('?','_').replace(':', '_').encode(headphones.SYS_ENCODING, 'replace')
|
||||
|
||||
if headphones.FILE_UNDERSCORES:
|
||||
album_art_name = album_art_name.replace(' ', '_')
|
||||
|
||||
if album_art_name.startswith('.'):
|
||||
album_art_name = album_art_name.replace(0, '_')
|
||||
|
||||
@@ -493,6 +499,10 @@ def moveFiles(albumpath, release, tracks):
|
||||
|
||||
artist = release['ArtistName'].replace('/', '_')
|
||||
album = release['AlbumTitle'].replace('/', '_')
|
||||
if headphones.FILE_UNDERSCORES:
|
||||
artist = artist.replace(' ', '_')
|
||||
album = album.replace(' ', '_')
|
||||
|
||||
releasetype = release['Type'].replace('/', '_')
|
||||
|
||||
if release['ArtistName'].startswith('The '):
|
||||
@@ -832,6 +842,9 @@ def renameFiles(albumpath, downloaded_track_list, release):
|
||||
|
||||
new_file_name = new_file_name.replace('?','_').replace(':', '_').encode(headphones.SYS_ENCODING, 'replace')
|
||||
|
||||
if headphones.FILE_UNDERSCORES:
|
||||
new_file_name = new_file_name.replace(' ', '_')
|
||||
|
||||
if new_file_name.startswith('.'):
|
||||
new_file_name = new_file_name.replace(0, '_')
|
||||
|
||||
|
||||
+17
-5
@@ -1073,9 +1073,7 @@ def searchTorrent(albumid=None, new=False, losslessOnly=False):
|
||||
provider))
|
||||
|
||||
# Pirate Bay
|
||||
if headphones.PIRATEBAY and headphones.TORRENT_DOWNLOADER == 0:
|
||||
logger.warn("Cannot search Pirate Bay with Blackhole option set")
|
||||
if headphones.PIRATEBAY and headphones.TORRENT_DOWNLOADER != 0:
|
||||
if headphones.PIRATEBAY:
|
||||
provider = "The Pirate Bay"
|
||||
providerurl = url_fix("http://thepiratebay.sx/search/" + term + "/0/99/")
|
||||
if headphones.PREFERRED_QUALITY == 3 or losslessOnly:
|
||||
@@ -1117,9 +1115,15 @@ def searchTorrent(albumid=None, new=False, losslessOnly=False):
|
||||
title = ''.join(item.find("a", {"class" : "detLink"}))
|
||||
seeds = int(''.join(item.find("td", {"align" : "right"})))
|
||||
url = item.findAll("a")[3]['href']
|
||||
if headphones.TORRENT_DOWNLOADER == 0:
|
||||
tor_hash = re.findall("urn:btih:(.*?)&", url)
|
||||
if len(tor_hash) > 0:
|
||||
url = "http://torrage.com/torrent/"+str(tor_hash[0]).upper()+".torrent"
|
||||
else:
|
||||
url = None
|
||||
formatted_size = re.search('Size (.*),', unicode(item)).group(1).replace(u'\xa0', ' ')
|
||||
size = helpers.piratesize(formatted_size)
|
||||
if size < maxsize and minimumseeders < seeds:
|
||||
if size < maxsize and minimumseeders < seeds and url != None:
|
||||
resultlist.append((title, size, url, provider))
|
||||
logger.info('Found %s. Size: %s' % (title, formatted_size))
|
||||
else:
|
||||
@@ -1193,6 +1197,9 @@ def searchTorrent(albumid=None, new=False, losslessOnly=False):
|
||||
rightformat = False
|
||||
except Exception, e:
|
||||
rightformat = False
|
||||
for findterm in term.split(" "):
|
||||
if not findterm in title:
|
||||
rightformat = False
|
||||
if rightformat == True and size < maxsize and minimumseeders < seeds:
|
||||
resultlist.append((title, size, url, provider))
|
||||
logger.info('Found %s. Size: %s' % (title, helpers.bytes_to_mb(size)))
|
||||
@@ -1427,6 +1434,11 @@ def searchTorrent(albumid=None, new=False, losslessOnly=False):
|
||||
file_or_url = bestqual[2]
|
||||
|
||||
torrentid = transmission.addTorrent(file_or_url)
|
||||
|
||||
if not torrentid:
|
||||
logger.error("Error sending torrent to Transmission. Are you sure it's running?")
|
||||
return
|
||||
|
||||
torrent_folder_name = transmission.getTorrentFolder(torrentid)
|
||||
logger.info('Torrent folder name: %s' % torrent_folder_name)
|
||||
|
||||
@@ -1449,7 +1461,7 @@ def preprocesstorrent(resultlist, pre_sorted_list=False):
|
||||
for result in resultlist:
|
||||
|
||||
# get outta here if rutracker or piratebay
|
||||
if result[3] == 'rutracker.org' or result[3] == 'The Pirate Bay':
|
||||
if result[3] == 'rutracker.org':
|
||||
return True, result
|
||||
|
||||
try:
|
||||
|
||||
@@ -32,8 +32,10 @@ def addTorrent(link):
|
||||
arguments = {'filename': link, 'download-dir':headphones.DOWNLOAD_TORRENT_DIR}
|
||||
|
||||
response = torrentAction(method,arguments)
|
||||
|
||||
|
||||
if not response:
|
||||
return False
|
||||
|
||||
if response['result'] == 'success':
|
||||
name = response['arguments']['torrent-added']['name']
|
||||
logger.info(u"Torrent sent to Transmission successfully")
|
||||
|
||||
+11
-2
@@ -565,6 +565,9 @@ class WebInterface(object):
|
||||
"http_port" : headphones.HTTP_PORT,
|
||||
"http_pass" : headphones.HTTP_PASSWORD,
|
||||
"launch_browser" : checked(headphones.LAUNCH_BROWSER),
|
||||
"enable_https" : checked(headphones.ENABLE_HTTPS),
|
||||
"https_cert" : headphones.HTTPS_CERT,
|
||||
"https_key" : headphones.HTTPS_KEY,
|
||||
"api_enabled" : checked(headphones.API_ENABLED),
|
||||
"api_key" : headphones.API_KEY,
|
||||
"download_scan_interval" : headphones.DOWNLOAD_SCAN_INTERVAL,
|
||||
@@ -647,6 +650,7 @@ class WebInterface(object):
|
||||
"lossless_dest_dir" : headphones.LOSSLESS_DESTINATION_DIR,
|
||||
"folder_format" : headphones.FOLDER_FORMAT,
|
||||
"file_format" : headphones.FILE_FORMAT,
|
||||
"file_underscores" : checked(headphones.FILE_UNDERSCORES),
|
||||
"include_extras" : checked(headphones.INCLUDE_EXTRAS),
|
||||
"autowant_upcoming" : checked(headphones.AUTOWANT_UPCOMING),
|
||||
"autowant_all" : checked(headphones.AUTOWANT_ALL),
|
||||
@@ -720,19 +724,23 @@ class WebInterface(object):
|
||||
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,
|
||||
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, 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,
|
||||
bitrate=None, samplingfrequency=None, encoderfolder=None, advancedencoder=None, encoderoutputformat=None, encodervbrcbr=None, encoderquality=None, encoderlossless=0,
|
||||
delete_lossless_files=0, prowl_enabled=0, prowl_onsnatch=0, prowl_keys=None, prowl_priority=0, xbmc_enabled=0, xbmc_host=None, xbmc_username=None, xbmc_password=None,
|
||||
xbmc_update=0, xbmc_notify=0, nma_enabled=False, nma_apikey=None, nma_priority=0, nma_onsnatch=0, synoindex_enabled=False,
|
||||
pushover_enabled=0, pushover_onsnatch=0, pushover_keys=None, pushover_priority=0, mirror=None, customhost=None, customport=None,
|
||||
customsleep=None, hpuser=None, hppass=None, preferred_bitrate_high_buffer=None, preferred_bitrate_low_buffer=None, preferred_bitrate_allow_lossless=0, cache_sizemb=None, **kwargs):
|
||||
customsleep=None, hpuser=None, hppass=None, preferred_bitrate_high_buffer=None, preferred_bitrate_low_buffer=None, preferred_bitrate_allow_lossless=0, cache_sizemb=None,
|
||||
enable_https=0, https_cert=None, https_key=None, **kwargs):
|
||||
|
||||
headphones.HTTP_HOST = http_host
|
||||
headphones.HTTP_PORT = http_port
|
||||
headphones.HTTP_USERNAME = http_username
|
||||
headphones.HTTP_PASSWORD = http_password
|
||||
headphones.LAUNCH_BROWSER = launch_browser
|
||||
headphones.ENABLE_HTTPS = enable_https
|
||||
headphones.HTTPS_CERT = https_cert
|
||||
headphones.HTTPS_KEY = https_key
|
||||
headphones.API_ENABLED = api_enabled
|
||||
headphones.API_KEY = api_key
|
||||
headphones.DOWNLOAD_SCAN_INTERVAL = download_scan_interval
|
||||
@@ -806,6 +814,7 @@ class WebInterface(object):
|
||||
headphones.LOSSLESS_DESTINATION_DIR = lossless_destination_dir
|
||||
headphones.FOLDER_FORMAT = folder_format
|
||||
headphones.FILE_FORMAT = file_format
|
||||
headphones.FILE_UNDERSCORES = file_underscores
|
||||
headphones.INCLUDE_EXTRAS = include_extras
|
||||
headphones.AUTOWANT_UPCOMING = autowant_upcoming
|
||||
headphones.AUTOWANT_ALL = autowant_all
|
||||
|
||||
+31
-2
@@ -20,12 +20,31 @@ import cherrypy
|
||||
|
||||
import headphones
|
||||
|
||||
from headphones import logger
|
||||
from headphones.webserve import WebInterface
|
||||
from headphones.helpers import create_https_certificates
|
||||
|
||||
def initialize(options={}):
|
||||
|
||||
#HTTPS stuff stolen from sickbeard
|
||||
enable_https = options['enable_https']
|
||||
https_cert = options['https_cert']
|
||||
https_key = options['https_key']
|
||||
|
||||
cherrypy.config.update({
|
||||
if enable_https:
|
||||
# If either the HTTPS certificate or key do not exist, make some self-signed ones.
|
||||
if not (https_cert and os.path.exists(https_cert)) or not (https_key and os.path.exists(https_key)):
|
||||
if not create_https_certificates(https_cert, https_key):
|
||||
logger.warn(u"Unable to create cert/key files, disabling HTTPS")
|
||||
headphones.ENABLE_HTTPS = False
|
||||
enable_https = False
|
||||
|
||||
if not (os.path.exists(https_cert) and os.path.exists(https_key)):
|
||||
logger.warn(u"Disabled HTTPS because of missing CERT and KEY files")
|
||||
headphones.ENABLE_HTTPS = False
|
||||
enable_https = False
|
||||
|
||||
options_dict = {
|
||||
'log.screen': False,
|
||||
'server.thread_pool': 10,
|
||||
'server.socket_port': options['http_port'],
|
||||
@@ -34,7 +53,17 @@ def initialize(options={}):
|
||||
'tools.encode.on' : True,
|
||||
'tools.encode.encoding' : 'utf-8',
|
||||
'tools.decode.on' : True,
|
||||
})
|
||||
}
|
||||
|
||||
if enable_https:
|
||||
options_dict['server.ssl_certificate'] = https_cert
|
||||
options_dict['server.ssl_private_key'] = https_key
|
||||
protocol = "https"
|
||||
else:
|
||||
protocol = "http"
|
||||
|
||||
logger.info(u"Starting Headphones on " + protocol + "://" + str(options['http_host']) + ":" + str(options['http_port']) + "/")
|
||||
cherrypy.config.update(options_dict)
|
||||
|
||||
conf = {
|
||||
'/': {
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
# -*- coding: latin-1 -*-
|
||||
#
|
||||
# Copyright (C) Martin Sjögren and AB Strakt 2001, All rights reserved
|
||||
# Copyright (C) Jean-Paul Calderone 2008, All rights reserved
|
||||
# This file is licenced under the GNU LESSER GENERAL PUBLIC LICENSE Version 2.1 or later (aka LGPL v2.1)
|
||||
# Please see LGPL2.1.txt for more information
|
||||
"""
|
||||
Certificate generation module.
|
||||
"""
|
||||
|
||||
from OpenSSL import crypto
|
||||
import time
|
||||
|
||||
TYPE_RSA = crypto.TYPE_RSA
|
||||
TYPE_DSA = crypto.TYPE_DSA
|
||||
|
||||
serial = int(time.time())
|
||||
|
||||
|
||||
def createKeyPair(type, bits):
|
||||
"""
|
||||
Create a public/private key pair.
|
||||
|
||||
Arguments: type - Key type, must be one of TYPE_RSA and TYPE_DSA
|
||||
bits - Number of bits to use in the key
|
||||
Returns: The public/private key pair in a PKey object
|
||||
"""
|
||||
pkey = crypto.PKey()
|
||||
pkey.generate_key(type, bits)
|
||||
return pkey
|
||||
|
||||
def createCertRequest(pkey, digest="md5", **name):
|
||||
"""
|
||||
Create a certificate request.
|
||||
|
||||
Arguments: pkey - The key to associate with the request
|
||||
digest - Digestion method to use for signing, default is md5
|
||||
**name - The name of the subject of the request, possible
|
||||
arguments are:
|
||||
C - Country name
|
||||
ST - State or province name
|
||||
L - Locality name
|
||||
O - Organization name
|
||||
OU - Organizational unit name
|
||||
CN - Common name
|
||||
emailAddress - E-mail address
|
||||
Returns: The certificate request in an X509Req object
|
||||
"""
|
||||
req = crypto.X509Req()
|
||||
subj = req.get_subject()
|
||||
|
||||
for (key,value) in name.items():
|
||||
setattr(subj, key, value)
|
||||
|
||||
req.set_pubkey(pkey)
|
||||
req.sign(pkey, digest)
|
||||
return req
|
||||
|
||||
def createCertificate(req, (issuerCert, issuerKey), serial, (notBefore, notAfter), digest="md5"):
|
||||
"""
|
||||
Generate a certificate given a certificate request.
|
||||
|
||||
Arguments: req - Certificate reqeust to use
|
||||
issuerCert - The certificate of the issuer
|
||||
issuerKey - The private key of the issuer
|
||||
serial - Serial number for the certificate
|
||||
notBefore - Timestamp (relative to now) when the certificate
|
||||
starts being valid
|
||||
notAfter - Timestamp (relative to now) when the certificate
|
||||
stops being valid
|
||||
digest - Digest method to use for signing, default is md5
|
||||
Returns: The signed certificate in an X509 object
|
||||
"""
|
||||
cert = crypto.X509()
|
||||
cert.set_serial_number(serial)
|
||||
cert.gmtime_adj_notBefore(notBefore)
|
||||
cert.gmtime_adj_notAfter(notAfter)
|
||||
cert.set_issuer(issuerCert.get_subject())
|
||||
cert.set_subject(req.get_subject())
|
||||
cert.set_pubkey(req.get_pubkey())
|
||||
cert.sign(issuerKey, digest)
|
||||
return cert
|
||||
Reference in New Issue
Block a user