mirror of
https://github.com/rembo10/headphones.git
synced 2026-05-16 00:25:31 +01:00
Added Deluge (Downloader) and Telegram (Notifier) Support
**Features:** - - Added the ability to use Deluge as a torrent downloader (http://deluge-torrent.org/) - - Added the ability to use Telegram messenger for download notifications using Telegram's Bot API (https://core.telegram.org/bots) **Issues:** - - Post-processor doesn't look for the right directory when scanning for completed downloads, it looks for the torrent's official name and not the actually directory it was saved to
This commit is contained in:
@@ -311,6 +311,7 @@
|
||||
<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 (Beta)
|
||||
<input type="radio" name="torrent_downloader" id="torrent_downloader_deluge" value="3" ${config['torrent_downloader_deluge']}> Deluge (Beta)
|
||||
</fieldset>
|
||||
<fieldset id="torrent_blackhole_options">
|
||||
<div class="row">
|
||||
@@ -385,6 +386,35 @@
|
||||
<input type="text" name="utorrent_label" value="${config['utorrent_label']}" size="30">
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset id="deluge_options">
|
||||
<div class="row">
|
||||
<label>Deluge WebUI Host and Port</label>
|
||||
<input type="text" name="deluge_host" value="${config['deluge_host']}" size="30">
|
||||
<small>Usually http://localhost:8112 (requires WebUI plugin)</small>
|
||||
</div>
|
||||
<div class="row">
|
||||
<label>Deluge Password</label>
|
||||
<input type="password" name="deluge_password" value="${config['deluge_password']}" size="30">
|
||||
</div>
|
||||
<div class="row">
|
||||
<small>Note: With Deluge, you can specify a different download directory for downloads sent from Headphones.
|
||||
Set it in the Music Download Directory below</small>
|
||||
</div>
|
||||
<div class="row">
|
||||
<label>Deluge Label</label>
|
||||
<input type="text" name="deluge_label" value="${config['deluge_label']}" size="30">
|
||||
<small>Labels shouldn't contain spaces (requires Label plugin)</small>
|
||||
</div>
|
||||
<div class="row">
|
||||
<label>Move When Completed</label>
|
||||
<input type="text" name="deluge_done_directory" value="${config['deluge_done_directory']}" size="30">
|
||||
<small>Directory where Deluge should move completed downloads</small>
|
||||
</div>
|
||||
<div class="row checkbox">
|
||||
<label>Add Torrent Paused</label>
|
||||
<input type="checkbox" name="deluge_paused" value="1" ${config['deluge_paused']}>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset id="general_torrent_options">
|
||||
<div class="row">
|
||||
<label>Minimum seeders</label>
|
||||
@@ -1222,6 +1252,23 @@
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
<div class="row checkbox left">
|
||||
<input type="checkbox" class="bigcheck" name="telegram_enabled" id="telegram" value="1" ${config['telegram_enabled']} /><label for="telegram"><span class="option">Telegram</span></label>
|
||||
</div>
|
||||
<div id="telegramoptions">
|
||||
<div class="row">
|
||||
<label>Bot Token</label><input type="text" name="telegram_token" value="${config['telegram_token']}" size="50"><small>Contact <a href="http://telegram.me/BotFather">@BotFather</a> to create a bot and get its token</small>
|
||||
</div>
|
||||
<div class="row">
|
||||
<label>User ID</label><input type="text" name="telegram_userid" value="${config['telegram_userid']}" size="50"><small>Contact <a href="http://telegram.me/myidbot">@myidbot</a> to get your user ID</small>
|
||||
</div>
|
||||
<div class="row checkbox">
|
||||
<input type="checkbox" name="telegram_onsnatch" value="1" ${config['telegram_onsnatch']} /><label>Notify on snatch?</label>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@@ -2003,6 +2050,26 @@
|
||||
}
|
||||
});
|
||||
|
||||
if ($("#telegram").is(":checked"))
|
||||
{
|
||||
$("#telegramoptions").show();
|
||||
}
|
||||
else
|
||||
{
|
||||
$("#telegramoptions").hide();
|
||||
}
|
||||
|
||||
$("#telegram").click(function(){
|
||||
if ($("#telegram").is(":checked"))
|
||||
{
|
||||
$("#telegramoptions").slideDown();
|
||||
}
|
||||
else
|
||||
{
|
||||
$("#telegramoptions").slideUp();
|
||||
}
|
||||
});
|
||||
|
||||
if ($("#osx_notify").is(":checked"))
|
||||
{
|
||||
$("#osx_notify_options").show();
|
||||
@@ -2159,19 +2226,25 @@
|
||||
|
||||
if ($("#torrent_downloader_blackhole").is(":checked"))
|
||||
{
|
||||
$("#transmission_options,#utorrent_options").hide();
|
||||
$("#transmission_options,#utorrent_options,#deluge_options").hide();
|
||||
$("#torrent_blackhole_options").show();
|
||||
}
|
||||
if ($("#torrent_downloader_transmission").is(":checked"))
|
||||
{
|
||||
$("#torrent_blackhole_options,#utorrent_options").hide();
|
||||
$("#torrent_blackhole_options,#utorrent_options,#deluge_options").hide();
|
||||
$("#transmission_options").show();
|
||||
}
|
||||
if ($("#torrent_downloader_utorrent").is(":checked"))
|
||||
{
|
||||
$("#torrent_blackhole_options,#transmission_options").hide();
|
||||
$("#torrent_blackhole_options,#transmission_options,#deluge_options").hide();
|
||||
$("#utorrent_options").show();
|
||||
}
|
||||
if ($("#torrent_downloader_deluge").is(":checked"))
|
||||
{
|
||||
$("#torrent_blackhole_options,#transmission_options,#utorrent_options").hide();
|
||||
$("#deluge_options").show();
|
||||
}
|
||||
|
||||
|
||||
$('input[type=radio]').change(function(){
|
||||
if ($("#preferred_bitrate").is(":checked"))
|
||||
@@ -2208,15 +2281,19 @@
|
||||
}
|
||||
if ($("#torrent_downloader_blackhole").is(":checked"))
|
||||
{
|
||||
$("#transmission_options,#utorrent_options").fadeOut("fast", function() { $("#torrent_blackhole_options").fadeIn() });
|
||||
$("#transmission_options,#utorrent_options,#deluge_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() });
|
||||
$("#torrent_blackhole_options,#utorrent_options,#deluge_options").fadeOut("fast", function() { $("#transmission_options").fadeIn() });
|
||||
}
|
||||
if ($("#torrent_downloader_utorrent").is(":checked"))
|
||||
{
|
||||
$("#torrent_blackhole_options,#transmission_options").fadeOut("fast", function() { $("#utorrent_options").fadeIn() });
|
||||
$("#torrent_blackhole_options,#transmission_options,#deluge_options").fadeOut("fast", function() { $("#utorrent_options").fadeIn() });
|
||||
}
|
||||
if ($("#torrent_downloader_deluge").is(":checked"))
|
||||
{
|
||||
$("#torrent_blackhole_options,#utorrent_options,#transmission_options").fadeOut("fast", function() { $("#deluge_options").fadeIn() });
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -53,6 +53,12 @@ _CONFIG_DEFINITIONS = {
|
||||
'CUSTOMSLEEP': (int, 'General', 1),
|
||||
'CUSTOMUSER': (str, 'General', ''),
|
||||
'DELETE_LOSSLESS_FILES': (int, 'General', 1),
|
||||
'DELUGE_HOST': (str, 'Deluge', ''),
|
||||
'DELUGE_PASSWORD': (str, 'Deluge', ''),
|
||||
'DELUGE_USERNAME': (str, 'Deluge', ''),
|
||||
'DELUGE_LABEL': (str, 'Deluge', ''),
|
||||
'DELUGE_DONE_DIRECTORY': (str, 'Deluge', ''),
|
||||
'DELUGE_PAUSED': (int, 'Deluge', 0),
|
||||
'DESTINATION_DIR': (str, 'General', ''),
|
||||
'DETECT_BITRATE': (int, 'General', 0),
|
||||
'DO_NOT_PROCESS_UNMATCHED': (int, 'General', 0),
|
||||
@@ -234,6 +240,10 @@ _CONFIG_DEFINITIONS = {
|
||||
'SUBSONIC_PASSWORD': (str, 'Subsonic', ''),
|
||||
'SUBSONIC_USERNAME': (str, 'Subsonic', ''),
|
||||
'SYNOINDEX_ENABLED': (int, 'Synoindex', 0),
|
||||
'TELEGRAM_TOKEN': (str, 'Telegram', ''),
|
||||
'TELEGRAM_USERID': (str, 'Telegram', ''),
|
||||
'TELEGRAM_ENABLED': (int, 'Telegram', 0),
|
||||
'TELEGRAM_ONSNATCH': (int, 'Telegram', 0),
|
||||
'TORRENTBLACKHOLE_DIR': (str, 'General', ''),
|
||||
'TORRENT_DOWNLOADER': (int, 'General', 0),
|
||||
'TORRENT_REMOVAL_INTERVAL': (int, 'General', 720),
|
||||
|
||||
397
headphones/deluge.py
Normal file
397
headphones/deluge.py
Normal file
@@ -0,0 +1,397 @@
|
||||
# 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/>.
|
||||
|
||||
# Parts of this file are a part of SickRage.
|
||||
# Author: echel0n <sickrage.tv@gmail.com>
|
||||
# URL: http://www.github.com/sickragetv/sickrage/
|
||||
#
|
||||
# Adapted for Headphones by <noamgit@gmail.com>
|
||||
#
|
||||
# SickRage 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.
|
||||
#
|
||||
# SickRage 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 SickRage. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from headphones import logger, request
|
||||
|
||||
import time
|
||||
import re
|
||||
import os
|
||||
import json
|
||||
import base64
|
||||
import urlparse
|
||||
import headphones
|
||||
import requests
|
||||
|
||||
from base64 import b64encode
|
||||
|
||||
delugeweb_auth = {}
|
||||
delugeweb_url = ''
|
||||
|
||||
def add_torrent(link, data=None):
|
||||
try:
|
||||
result = {}
|
||||
retid = False
|
||||
if link.endswith('.torrent') or data:
|
||||
# .torrent? for torcache links
|
||||
# or '.torrent?' in link
|
||||
if data:
|
||||
metainfo = str(base64.b64encode(data))
|
||||
# before I found out HP handles the downloads
|
||||
#elif link.startswith('http://') or link.startswith('https://'):
|
||||
# user_agent = 'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.1546.111 Safari/582.36'
|
||||
# headers = { 'User-Agent': user_agent }
|
||||
# torrentfile = ''
|
||||
# r = requests.get(link, headers=headers)
|
||||
# if r.status_code == 200:
|
||||
# for chunk in r.iter_content(chunk_size=1024):
|
||||
# if chunk: # filter out keep-alive new chunks
|
||||
# torrent_file = torrentfile + chunk
|
||||
# metainfo = str(base64.b64encode(torrentfile.decode('utf-8')))
|
||||
else:
|
||||
with open(link, 'rb') as f:
|
||||
metainfo = str(base64.b64encode(f.read()))
|
||||
# Extract torrent name from .torrent
|
||||
name_length = int( re.findall( 'name([0-9]*)\:.*?\:', base64.b64encode(metainfo) )[0] )
|
||||
name = re.findall('name[0-9]*\:(.*?)\:', base64.b64encode(metainfo) )[0][:size]
|
||||
result = {
|
||||
'type' : 'torrent',
|
||||
'name' : name,
|
||||
'content' : metainfo,
|
||||
}
|
||||
retid = add_torrent_file(result)
|
||||
|
||||
elif link.startswith('magnet:'):
|
||||
result = {
|
||||
'type' : 'magnet',
|
||||
'url' : link,
|
||||
}
|
||||
retid = add_torrent_uri(result)
|
||||
else:
|
||||
logger.error('Deluge: Unknown file type - ' + str(link))
|
||||
|
||||
if retid:
|
||||
logger.info(u"Torrent sent to Deluge successfully")
|
||||
return retid
|
||||
else:
|
||||
logger.info('Deluge returned status %s' % retid)
|
||||
return False
|
||||
|
||||
except Exception, e:
|
||||
logger.error( str(e) )
|
||||
|
||||
def get_torrent_folder(result):
|
||||
|
||||
if not any(delugeweb_auth):
|
||||
get_auth()
|
||||
|
||||
post_data = json.dumps({
|
||||
"method": "web.get_torrent_status",
|
||||
"params": [
|
||||
result['hash'],
|
||||
[ "total_done" ]
|
||||
],
|
||||
"id": 22
|
||||
})
|
||||
|
||||
response = requests.post(delugeweb_url, data=post_data.encode('utf-8'), cookies=delugeweb_auth)
|
||||
result['total_done'] = json.loads(response.text)['result']['total_done']
|
||||
|
||||
tries = 0
|
||||
while result['total_done'] == 0 and tries < 10:
|
||||
tries += 1
|
||||
time.sleep(5)
|
||||
response = requests.post(delugeweb_url, data=post_data.encode('utf-8'), cookies=delugeweb_auth)
|
||||
result['total_done'] = json.loads(response.text)['result']['total_done']
|
||||
|
||||
post_data = json.dumps({
|
||||
"method": "web.get_torrent_status",
|
||||
"params": [
|
||||
result['hash'],
|
||||
[
|
||||
"name",
|
||||
"save_path",
|
||||
"total_size",
|
||||
"num_files",
|
||||
"message",
|
||||
"tracker",
|
||||
"comment"
|
||||
]
|
||||
],
|
||||
"id": 23
|
||||
})
|
||||
|
||||
response = requests.post(delugeweb_url, data=post_data.encode('utf-8'), cookies=delugeweb_auth)
|
||||
|
||||
result['save_path'] = json.loads(response.text)['result']['save_path']
|
||||
result['name'] = json.loads(response.text)['result']['name']
|
||||
|
||||
return json.loads(response.text)['result']['name']
|
||||
|
||||
def remove_torrent(torrentid, remove_data=False):
|
||||
'''
|
||||
todo
|
||||
'''
|
||||
return
|
||||
|
||||
def get_auth():
|
||||
|
||||
global delugeweb_auth, delugeweb_url
|
||||
delugeweb_auth = {}
|
||||
|
||||
delugeweb_host = headphones.CONFIG.DELUGE_HOST
|
||||
delugeweb_username = headphones.CONFIG.DELUGE_USERNAME
|
||||
delugeweb_password = headphones.CONFIG.DELUGE_PASSWORD
|
||||
|
||||
if not delugeweb_host.startswith('http'):
|
||||
delugeweb_host = 'http://' + delugeweb_host
|
||||
|
||||
if delugeweb_host.endswith('/'):
|
||||
delugeweb_host = delugeweb_host[:-1]
|
||||
|
||||
delugeweb_url = delugeweb_host + '/json'
|
||||
|
||||
post_data = json.dumps({"method": "auth.login",
|
||||
"params": [delugeweb_password],
|
||||
"id": 1})
|
||||
try:
|
||||
response = requests.post(delugeweb_url, data=post_data.encode('utf-8'), cookies=delugeweb_auth )
|
||||
# , verify=TORRENT_VERIFY_CERT)
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
auth = json.loads(response.text)["result"]
|
||||
delugeweb_auth = response.cookies
|
||||
|
||||
post_data = json.dumps({"method": "web.connected",
|
||||
"params": [],
|
||||
"id": 10})
|
||||
try:
|
||||
response = requests.post(delugeweb_url, data=post_data.encode('utf-8'), cookies=delugeweb_auth )
|
||||
# , verify=TORRENT_VERIFY_CERT)
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
connected = json.loads(response.text)['result']
|
||||
|
||||
if not connected:
|
||||
post_data = json.dumps({"method": "web.get_delugeweb_hosts",
|
||||
"params": [],
|
||||
"id": 11})
|
||||
try:
|
||||
response = requests.post(delugeweb_url, data=post_data.encode('utf-8'), cookies=delugeweb_auth )
|
||||
# , verify=TORRENT_VERIFY_CERT)
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
delugeweb_hosts = json.loads(response.text)['result']
|
||||
if len(delugeweb_hosts) == 0:
|
||||
logger.error('Deluge: WebUI does not contain daemons')
|
||||
return None
|
||||
|
||||
post_data = json.dumps({"method": "web.connect",
|
||||
"params": [delugeweb_hosts[0][0]],
|
||||
"id": 11})
|
||||
|
||||
try:
|
||||
response = requests.post(delugeweb_url, data=post_data.encode('utf-8'), cookies=delugeweb_auth )
|
||||
# , verify=TORRENT_VERIFY_CERT)
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
post_data = json.dumps({"method": "web.connected",
|
||||
"params": [],
|
||||
"id": 10})
|
||||
|
||||
try:
|
||||
response = requests.post(delugeweb_url, data=post_data.encode('utf-8'), cookies=delugeweb_auth )
|
||||
# , verify=TORRENT_VERIFY_CERT)
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
connected = json.loads(response.text)['result']
|
||||
|
||||
if not connected:
|
||||
logger.error('Deluge: WebUI could not connect to daemon')
|
||||
return None
|
||||
|
||||
return auth
|
||||
|
||||
def add_torrent_uri(result):
|
||||
|
||||
if not any(delugeweb_auth):
|
||||
get_auth()
|
||||
|
||||
post_data = json.dumps({"method": "core.add_torrent_magnet",
|
||||
"params": [result['url'], {}],
|
||||
"id": 2})
|
||||
|
||||
'''
|
||||
# This method doesn't return hash
|
||||
post_data = json.dumps({
|
||||
"method": "web.add_torrents",
|
||||
"params": [
|
||||
[
|
||||
{
|
||||
"path": result['url'],
|
||||
"options": {
|
||||
"add_paused": headphones.CONFIG.DELUGE_PAUSED,
|
||||
#"download_location": headphones.CONFIG.DOWNLOAD_TORRENT_DIR,
|
||||
#"move_completed": true,
|
||||
#"move_completed_path": headphones.CONFIG.DELUGE_DONE_DIRECTORY,
|
||||
}
|
||||
}
|
||||
]
|
||||
],
|
||||
"id": 2
|
||||
})
|
||||
'''
|
||||
|
||||
response = requests.post(delugeweb_url, data=post_data.encode('utf-8'), cookies=delugeweb_auth)
|
||||
|
||||
result['hash'] = json.loads(response.text)['result']
|
||||
|
||||
return json.loads(response.text)['result']
|
||||
|
||||
def add_torrent_file(result):
|
||||
|
||||
if not any(delugeweb_auth):
|
||||
get_auth()
|
||||
|
||||
post_data = json.dumps({"method": "core.add_torrent_file",
|
||||
"params": [result['name'] + '.torrent', b64encode(result['content']), {}],
|
||||
"id": 2})
|
||||
|
||||
response = requests.post(delugeweb_url, data=post_data.encode('utf-8'), cookies=delugeweb_auth)
|
||||
|
||||
result['hash'] = json.loads(response.text)['result']
|
||||
|
||||
return json.loads(response.text)['result']
|
||||
|
||||
def set_torrent_label(result):
|
||||
|
||||
label = headphones.CONFIG.DELUGE_LABEL
|
||||
|
||||
if not any(delugeweb_auth):
|
||||
get_auth()
|
||||
|
||||
if ' ' in label:
|
||||
logger.error('Deluge: Invalid label. Label must not contain a space - replacing with underscores')
|
||||
label = label.replace(' ', '_')
|
||||
if label:
|
||||
# check if label already exists and create it if not
|
||||
post_data = json.dumps({"method": 'label.get_labels',
|
||||
"params": [],
|
||||
"id": 3})
|
||||
response = requests.post(delugeweb_url, data=post_data.encode('utf-8'), cookies=delugeweb_auth)
|
||||
labels = json.loads(response.text)['result']
|
||||
|
||||
if labels is not None:
|
||||
if label not in labels:
|
||||
logger.debug('Deluge: ' + label + " label does not exist in Deluge we must add it")
|
||||
post_data = json.dumps({"method": 'label.add',
|
||||
"params": [label],
|
||||
"id": 4})
|
||||
response = requests.post(delugeweb_url, data=post_data.encode('utf-8'), cookies=delugeweb_auth)
|
||||
logger.debug('Deluge: ' + label + " label added to Deluge")
|
||||
|
||||
# add label to torrent
|
||||
post_data = json.dumps({"method": 'label.set_torrent',
|
||||
"params": [result['hash'], label],
|
||||
"id": 5})
|
||||
response = requests.post(delugeweb_url, data=post_data.encode('utf-8'), cookies=delugeweb_auth)
|
||||
logger.debug('Deluge: ' + label + " label added to torrent")
|
||||
else:
|
||||
logger.debug('Deluge: ' + "label plugin not detected")
|
||||
return False
|
||||
|
||||
return not json.loads(response.text)['error']
|
||||
|
||||
def set_torrent_ratio(result):
|
||||
|
||||
if not any(delugeweb_auth):
|
||||
get_auth()
|
||||
|
||||
ratio = None
|
||||
if result['ratio']:
|
||||
ratio = result['ratio']
|
||||
|
||||
if ratio:
|
||||
post_data = json.dumps({"method": "core.set_torrent_stop_at_ratio",
|
||||
"params": [result['hash'], True],
|
||||
"id": 5})
|
||||
response = requests.post(delugeweb_url, data=post_data.encode('utf-8'), cookies=delugeweb_auth)
|
||||
post_data = json.dumps({"method": "core.set_torrent_stop_ratio",
|
||||
"params": [result['hash'], float(ratio)],
|
||||
"id": 6})
|
||||
response = requests.post(delugeweb_url, data=post_data.encode('utf-8'), cookies=delugeweb_auth)
|
||||
|
||||
return not json.loads(response.text)['error']
|
||||
|
||||
return True
|
||||
|
||||
def set_torrent_path(result):
|
||||
|
||||
if not any(delugeweb_auth):
|
||||
get_auth()
|
||||
|
||||
if headphones.CONFIG.DELUGE_DONE_DIRECTORY or headphones.CONFIG.DOWNLOAD_TORRENT_DIR:
|
||||
post_data = json.dumps({"method": "core.set_torrent_move_completed",
|
||||
"params": [result['hash'], True],
|
||||
"id": 7})
|
||||
response = requests.post(delugeweb_url, data=post_data.encode('utf-8'), cookies=delugeweb_auth)
|
||||
|
||||
if headphones.CONFIG.DELUGE_DONE_DIRECTORY:
|
||||
move_to = headphones.CONFIG.DELUGE_DONE_DIRECTORY
|
||||
else:
|
||||
move_to = headphones.CONFIG.DOWNLOAD_TORRENT_DIR
|
||||
|
||||
if not os.path.exists(move_to):
|
||||
logger.debug("Deluge: " + move_to + " directory doesn't exist, let's create it")
|
||||
os.makedirs(move_to)
|
||||
post_data = json.dumps({"method": "core.set_torrent_move_completed_path",
|
||||
"params": [result['hash'], move_to],
|
||||
"id": 8})
|
||||
response = requests.post(delugeweb_url, data=post_data.encode('utf-8'), cookies=delugeweb_auth)
|
||||
|
||||
return not json.loads(response.text)['error']
|
||||
|
||||
return True
|
||||
|
||||
def set_torrent_pause(result):
|
||||
|
||||
if not any(delugeweb_auth):
|
||||
get_auth()
|
||||
|
||||
if headphones.CONFIG.DELUGE_PAUSED:
|
||||
post_data = json.dumps({"method": "core.pause_torrent",
|
||||
"params": [[ result['hash'] ]],
|
||||
"id": 9})
|
||||
response = requests.post(delugeweb_url, data=post_data.encode('utf-8'), cookies=delugeweb_auth)
|
||||
|
||||
return not json.loads(response.text)['error']
|
||||
|
||||
return True
|
||||
|
||||
@@ -856,3 +856,36 @@ class Email(object):
|
||||
except Exception, e:
|
||||
logger.warn('Error sending Email: %s' % e)
|
||||
return False
|
||||
|
||||
|
||||
class TELEGRAM(object):
|
||||
|
||||
def notify(self, message, status):
|
||||
if not headphones.CONFIG.TELEGRAM_ENABLED:
|
||||
return
|
||||
|
||||
import requests
|
||||
|
||||
TELEGRAM_API = "https://api.telegram.org/bot%s/%s"
|
||||
|
||||
# Get configuration data
|
||||
token = headphones.CONFIG.TELEGRAM_TOKEN
|
||||
userid = headphones.CONFIG.TELEGRAM_USERID
|
||||
|
||||
# Construct message
|
||||
payload = {'chat_id': userid, 'text': status + ': ' + message }
|
||||
|
||||
# Send message to user using Telegram's Bot API
|
||||
try:
|
||||
response = requests.post(TELEGRAM_API % (token, "sendMessage"), data=payload)
|
||||
except Exception, e:
|
||||
logger.info(u'Telegram notify failed: ' + str(e) )
|
||||
|
||||
# Error logging
|
||||
sent_successfuly = True
|
||||
if not response.status_code == 200:
|
||||
logger.info(u'Could not send notification to TelegramBot (token=%s). Response: [%s]', (token, response.text))
|
||||
sent_successfuly = False
|
||||
|
||||
logger.info(u"Telegram notifications sent.")
|
||||
return sent_successfuly
|
||||
|
||||
@@ -27,7 +27,7 @@ from beets import autotag
|
||||
from beets import config as beetsconfig
|
||||
from beets.mediafile import MediaFile, FileTypeError, UnreadableFileError
|
||||
from beetsplug import lyrics as beetslyrics
|
||||
from headphones import notifiers, utorrent, transmission
|
||||
from headphones import notifiers, utorrent, transmission, deluge
|
||||
from headphones import db, albumart, librarysync
|
||||
from headphones import logger, helpers, request, mb, music_encoder
|
||||
|
||||
@@ -46,7 +46,10 @@ def checkFolder():
|
||||
if album['Kind'] == 'nzb':
|
||||
download_dir = headphones.CONFIG.DOWNLOAD_DIR
|
||||
else:
|
||||
download_dir = headphones.CONFIG.DOWNLOAD_TORRENT_DIR
|
||||
if headphones.CONFIG.DELUGE_DONE_DIRECTORY:
|
||||
download_dir = headphones.CONFIG.DELUGE_DONE_DIRECTORY
|
||||
else:
|
||||
download_dir = headphones.CONFIG.DOWNLOAD_TORRENT_DIR
|
||||
|
||||
album_path = os.path.join(download_dir, album['FolderName']).encode(
|
||||
headphones.SYS_ENCODING, 'replace')
|
||||
@@ -532,6 +535,11 @@ def doPostProcessing(albumid, albumpath, release, tracks, downloaded_track_list,
|
||||
pushbullet = notifiers.PUSHBULLET()
|
||||
pushbullet.notify(pushmessage, statusmessage)
|
||||
|
||||
if headphones.CONFIG.TELEGRAM_ENABLED:
|
||||
logger.info(u"Telegram request")
|
||||
telegram = notifiers.TELEGRAM()
|
||||
telegram.notify(pushmessage, statusmessage)
|
||||
|
||||
if headphones.CONFIG.TWITTER_ENABLED:
|
||||
logger.info(u"Sending Twitter notification")
|
||||
twitter = notifiers.TwitterNotifier()
|
||||
|
||||
@@ -33,7 +33,7 @@ from pygazelle import format as gazelleformat
|
||||
import headphones
|
||||
from headphones.common import USER_AGENT
|
||||
from headphones import logger, db, helpers, classes, sab, nzbget, request
|
||||
from headphones import utorrent, transmission, notifiers, rutracker
|
||||
from headphones import utorrent, transmission, notifiers, rutracker, deluge
|
||||
from bencode import bencode, bdecode
|
||||
|
||||
|
||||
@@ -851,7 +851,7 @@ def send_to_downloader(data, bestqual, album):
|
||||
else:
|
||||
logger.error("Cannot save magnet link in blackhole. " \
|
||||
"Please switch your torrent downloader to " \
|
||||
"Transmission or uTorrent, or allow Headphones " \
|
||||
"Transmission, uTorrent or Deluge, or allow Headphones " \
|
||||
"to open or convert magnet links")
|
||||
return
|
||||
else:
|
||||
@@ -889,6 +889,54 @@ def send_to_downloader(data, bestqual, album):
|
||||
if seed_ratio is not None:
|
||||
transmission.setSeedRatio(torrentid, seed_ratio)
|
||||
|
||||
elif headphones.CONFIG.TORRENT_DOWNLOADER == 3: # Deluge
|
||||
logger.info("Sending torrent to Deluge")
|
||||
|
||||
try:
|
||||
# Add torrent
|
||||
if bestqual[3] == 'rutracker.org':
|
||||
torrentid = deluge.add_torrent('', data)
|
||||
else:
|
||||
torrentid = deluge.add_torrent(bestqual[2])
|
||||
|
||||
if not torrentid:
|
||||
logger.error("Error sending torrent to Deluge. Are you sure it's running? Maybe the torrent already exists?")
|
||||
return
|
||||
|
||||
# This isn't really necessary for an "Add Paused" mode,
|
||||
# but it's a bit different than the built-in "Add Paused"
|
||||
# because it pauses the torrent a moment after it has already been added.
|
||||
# May be useful in the future
|
||||
if headphones.CONFIG.DELUGE_PAUSED:
|
||||
deluge.set_torrent_pause({'hash': torrentid})
|
||||
|
||||
# Set Label
|
||||
if headphones.CONFIG.DELUGE_LABEL:
|
||||
deluge.set_torrent_label({'hash': torrentid})
|
||||
|
||||
# Set Seed Ratio
|
||||
seed_ratio = get_seed_ratio(bestqual[3])
|
||||
if seed_ratio is not None:
|
||||
deluge.set_torrent_ratio({'hash': torrentid, 'ratio': seed_ratio})
|
||||
|
||||
# Set move-to directory
|
||||
if headphones.CONFIG.DELUGE_DONE_DIRECTORY:
|
||||
deluge.set_torrent_path({'hash': torrentid})
|
||||
|
||||
# I only just realized this function is useless...
|
||||
folder_name = deluge.get_torrent_folder({'hash': torrentid})
|
||||
if folder_name:
|
||||
logger.info('Torrent folder name: %s' % folder_name)
|
||||
else:
|
||||
logger.error('Torrent folder name could not be determined')
|
||||
return
|
||||
|
||||
except Exception as e:
|
||||
#exc_type, exc_obj, exc_tb = sys.exc_info()
|
||||
#fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
|
||||
#print(exc_type, fname, exc_tb.tb_lineno)
|
||||
logger.error( str(e) )
|
||||
|
||||
else: # if headphones.CONFIG.TORRENT_DOWNLOADER == 2:
|
||||
logger.info("Sending torrent to uTorrent")
|
||||
|
||||
@@ -960,6 +1008,10 @@ def send_to_downloader(data, bestqual, album):
|
||||
logger.info(u"Sending PushBullet notification")
|
||||
pushbullet = notifiers.PUSHBULLET()
|
||||
pushbullet.notify(name, "Download started")
|
||||
if headphones.CONFIG.TELEGRAM_ENABLED and headphones.CONFIG.TELEGRAM_ONSNATCH:
|
||||
logger.info(u"Sending Telegram notification")
|
||||
telegram = notifiers.TELEGRAM()
|
||||
telegram.notify(name, "Download started")
|
||||
if headphones.CONFIG.TWITTER_ENABLED and headphones.CONFIG.TWITTER_ONSNATCH:
|
||||
logger.info(u"Sending Twitter notification")
|
||||
twitter = notifiers.TwitterNotifier()
|
||||
|
||||
@@ -1156,6 +1156,12 @@ class WebInterface(object):
|
||||
"transmission_host": headphones.CONFIG.TRANSMISSION_HOST,
|
||||
"transmission_username": headphones.CONFIG.TRANSMISSION_USERNAME,
|
||||
"transmission_password": headphones.CONFIG.TRANSMISSION_PASSWORD,
|
||||
"deluge_host": headphones.CONFIG.DELUGE_HOST,
|
||||
"deluge_username": headphones.CONFIG.DELUGE_USERNAME,
|
||||
"deluge_password": headphones.CONFIG.DELUGE_PASSWORD,
|
||||
"deluge_label": headphones.CONFIG.DELUGE_LABEL,
|
||||
"deluge_done_directory": headphones.CONFIG.DELUGE_DONE_DIRECTORY,
|
||||
"deluge_paused": checked(headphones.CONFIG.DELUGE_PAUSED),
|
||||
"utorrent_host": headphones.CONFIG.UTORRENT_HOST,
|
||||
"utorrent_username": headphones.CONFIG.UTORRENT_USERNAME,
|
||||
"utorrent_password": headphones.CONFIG.UTORRENT_PASSWORD,
|
||||
@@ -1166,6 +1172,7 @@ class WebInterface(object):
|
||||
"torrent_downloader_blackhole": radio(headphones.CONFIG.TORRENT_DOWNLOADER, 0),
|
||||
"torrent_downloader_transmission": radio(headphones.CONFIG.TORRENT_DOWNLOADER, 1),
|
||||
"torrent_downloader_utorrent": radio(headphones.CONFIG.TORRENT_DOWNLOADER, 2),
|
||||
"torrent_downloader_deluge": radio(headphones.CONFIG.TORRENT_DOWNLOADER, 3),
|
||||
"download_dir": headphones.CONFIG.DOWNLOAD_DIR,
|
||||
"use_blackhole": checked(headphones.CONFIG.BLACKHOLE),
|
||||
"blackhole_dir": headphones.CONFIG.BLACKHOLE_DIR,
|
||||
@@ -1324,6 +1331,10 @@ class WebInterface(object):
|
||||
"pushbullet_onsnatch": checked(headphones.CONFIG.PUSHBULLET_ONSNATCH),
|
||||
"pushbullet_apikey": headphones.CONFIG.PUSHBULLET_APIKEY,
|
||||
"pushbullet_deviceid": headphones.CONFIG.PUSHBULLET_DEVICEID,
|
||||
"telegram_enabled": checked(headphones.CONFIG.TELEGRAM_ENABLED),
|
||||
"telegram_onsnatch": checked(headphones.CONFIG.TELEGRAM_ONSNATCH),
|
||||
"telegram_token": headphones.CONFIG.TELEGRAM_TOKEN,
|
||||
"telegram_userid": headphones.CONFIG.TELEGRAM_USERID,
|
||||
"subsonic_enabled": checked(headphones.CONFIG.SUBSONIC_ENABLED),
|
||||
"subsonic_host": headphones.CONFIG.SUBSONIC_HOST,
|
||||
"subsonic_username": headphones.CONFIG.SUBSONIC_USERNAME,
|
||||
@@ -1420,10 +1431,11 @@ class WebInterface(object):
|
||||
"synoindex_enabled", "pushover_enabled",
|
||||
"pushover_onsnatch", "pushbullet_enabled", "pushbullet_onsnatch", "subsonic_enabled",
|
||||
"twitter_enabled", "twitter_onsnatch",
|
||||
"telegram_enabled", "telegram_onsnatch",
|
||||
"osx_notify_enabled", "osx_notify_onsnatch", "boxcar_enabled", "boxcar_onsnatch",
|
||||
"songkick_enabled", "songkick_filter_enabled",
|
||||
"mpc_enabled", "email_enabled", "email_ssl", "email_tls", "email_onsnatch",
|
||||
"customauth", "idtag"
|
||||
"customauth", "idtag", "deluge_paused"
|
||||
]
|
||||
for checked_config in checked_configs:
|
||||
if checked_config not in kwargs:
|
||||
@@ -1673,6 +1685,11 @@ class WebInterface(object):
|
||||
pushbullet = notifiers.PUSHBULLET()
|
||||
pushbullet.notify("it works!", "Test message")
|
||||
|
||||
@cherrypy.expose
|
||||
def testTelegram(self):
|
||||
logger.info("Testing Telegram notifications")
|
||||
telegram = notifiers.TELEGRAM()
|
||||
telegram.notify("it works!", "lazers pew pew")
|
||||
|
||||
class Artwork(object):
|
||||
@cherrypy.expose
|
||||
|
||||
Reference in New Issue
Block a user