mirror of
https://github.com/rembo10/headphones.git
synced 2026-05-19 18:15:31 +01:00
Merge remote-tracking branch 'delphiactual/develop' into develop
This commit is contained in:
@@ -388,6 +388,7 @@ class NMA:
|
||||
logger.debug(u"NMA title: " + title)
|
||||
logger.debug(u"NMA API: " + api)
|
||||
logger.debug(u"NMA Priority: " + str(nma_priority))
|
||||
|
||||
if snatched:
|
||||
event = snatched + " snatched!"
|
||||
message = "Headphones has snatched: " + snatched
|
||||
@@ -395,7 +396,6 @@ class NMA:
|
||||
event = artist + ' - ' + album + ' complete!'
|
||||
message = "Headphones has downloaded and postprocessed: " + artist + ' [' + album + ']'
|
||||
|
||||
|
||||
logger.debug(u"NMA event: " + event)
|
||||
logger.debug(u"NMA message: " + message)
|
||||
|
||||
|
||||
@@ -699,7 +699,7 @@ def send_to_downloader(data, bestqual, album):
|
||||
except Exception, e:
|
||||
logger.exception("Unhandled exception")
|
||||
|
||||
elif headphones.TORRENT_DOWNLOADER == 2:
|
||||
else:# if headphones.TORRENT_DOWNLOADER == 2:
|
||||
logger.info("Sending torrent to uTorrent")
|
||||
|
||||
# rutracker needs cookies to be set, pass the .torrent file instead of url
|
||||
@@ -725,32 +725,6 @@ def send_to_downloader(data, bestqual, album):
|
||||
except Exception, e:
|
||||
logger.exception("Unhandled exception")
|
||||
|
||||
else:
|
||||
logger.info("Sending torrent to DownloadStation")
|
||||
|
||||
# rutracker needs cookies to be set, pass the .torrent file instead of url
|
||||
if bestqual[3] == 'rutracker.org':
|
||||
file_or_url = rutracker.get_torrent(bestqual[2])
|
||||
else:
|
||||
file_or_url = bestqual[2]
|
||||
|
||||
_hash = CalculateTorrentHash(file_or_url, data)
|
||||
|
||||
folder_name = download_station.addTorrent(file_or_url)
|
||||
|
||||
if folder_name:
|
||||
logger.info('Torrent folder name: %s' % folder_name)
|
||||
else:
|
||||
logger.error('Torrent folder name could not be determined')
|
||||
return
|
||||
|
||||
# remove temp .torrent file created above
|
||||
if bestqual[3] == 'rutracker.org':
|
||||
try:
|
||||
shutil.rmtree(os.path.split(file_or_url)[0])
|
||||
except Exception, e:
|
||||
logger.exception("Unhandled exception")
|
||||
|
||||
myDB = db.DBConnection()
|
||||
myDB.action('UPDATE albums SET status = "Snatched" WHERE AlbumID=?', [album['AlbumID']])
|
||||
myDB.action('INSERT INTO snatched VALUES( ?, ?, ?, ?, DATETIME("NOW", "localtime"), ?, ?, ?)', [album['AlbumID'], bestqual[0], bestqual[1], bestqual[2], "Snatched", folder_name, kind])
|
||||
@@ -1431,7 +1405,7 @@ def preprocess(resultlist):
|
||||
for result in resultlist:
|
||||
|
||||
if result[4] == 'torrent':
|
||||
#Get out of here if we're using Transmission or uTorrent
|
||||
#Get out of here if we're using Transmission
|
||||
if headphones.TORRENT_DOWNLOADER == 1: ## if not a magnet link still need the .torrent to generate hash... uTorrent support labeling
|
||||
return True, result
|
||||
# get outta here if rutracker
|
||||
@@ -1495,6 +1469,6 @@ def CalculateTorrentHash(link, data):
|
||||
info = bdecode(data)["info"]
|
||||
tor_hash = sha1(bencode(info)).hexdigest()
|
||||
|
||||
logger.info('Torrent Hash: ' + str(tor_hash))
|
||||
logger.debug('Torrent Hash: ' + str(tor_hash))
|
||||
|
||||
return tor_hash
|
||||
@@ -13,17 +13,12 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Headphones. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import urllib
|
||||
import urllib2
|
||||
import urlparse
|
||||
import cookielib
|
||||
import json
|
||||
import re
|
||||
import os
|
||||
import time
|
||||
import urllib, urllib2, urlparse, cookielib
|
||||
import json, re, os, time
|
||||
|
||||
import headphones
|
||||
|
||||
from headphones import logger, notifiers
|
||||
from headphones import logger
|
||||
|
||||
class utorrentclient(object):
|
||||
TOKEN_REGEX = "<div id='token' style='display:none;'>([^<>]+)</div>"
|
||||
@@ -77,7 +72,7 @@ class utorrentclient(object):
|
||||
return self._action(params)
|
||||
|
||||
def add_url(self, url):
|
||||
#can recieve magnet or normal .torrent link
|
||||
#can receive magnet or normal .torrent link
|
||||
params = [('action', 'add-url'), ('s', url)]
|
||||
return self._action(params)
|
||||
|
||||
@@ -141,16 +136,31 @@ class utorrentclient(object):
|
||||
logger.debug('URL: ' + str(url))
|
||||
logger.debug('uTorrent webUI raised the following error: ' + str(err))
|
||||
|
||||
def addTorrent(link, hash):
|
||||
|
||||
def labelTorrent(hash):
|
||||
label = headphones.UTORRENT_LABEL
|
||||
uTorrentClient = utorrentclient()
|
||||
uTorrentClient.add_url(link)
|
||||
time.sleep(1) #need to ensure file is loaded uTorrent...
|
||||
uTorrentClient.setprops(hash,'label', label)
|
||||
settinglabel = True
|
||||
while settinglabel:
|
||||
torrentList = uTorrentClient.list()
|
||||
for torrent in torrentList[1].get('torrents'):
|
||||
if (torrent[0].lower() == hash):
|
||||
uTorrentClient.setprops(hash,'label',label)
|
||||
settinglabel = False
|
||||
return True
|
||||
|
||||
|
||||
def dirTorrent(hash):
|
||||
uTorrentClient = utorrentclient()
|
||||
torrentList = uTorrentClient.list()
|
||||
for torrent in torrentList[1].get('torrents'):
|
||||
if (torrent[0].lower()==hash):
|
||||
if (torrent[0].lower() == hash):
|
||||
return torrent[26]
|
||||
return False
|
||||
|
||||
return False
|
||||
|
||||
def addTorrent(link, hash):
|
||||
uTorrentClient = utorrentclient()
|
||||
uTorrentClient.add_url(link)
|
||||
labelTorrent(hash)
|
||||
return dirTorrent(hash)
|
||||
|
||||
4
lib/pynma/__init__.py
Normal file
4
lib/pynma/__init__.py
Normal file
@@ -0,0 +1,4 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
from pynma import PyNMA
|
||||
|
||||
137
lib/pynma/pynma.py
Normal file
137
lib/pynma/pynma.py
Normal file
@@ -0,0 +1,137 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
from xml.dom.minidom import parseString
|
||||
from httplib import HTTPSConnection
|
||||
from urllib import urlencode
|
||||
|
||||
__version__ = "0.1"
|
||||
|
||||
API_SERVER = 'nma.usk.bz'
|
||||
ADD_PATH = '/publicapi/notify'
|
||||
|
||||
USER_AGENT="PyNMA/v%s"%__version__
|
||||
|
||||
def uniq_preserve(seq): # Dave Kirby
|
||||
# Order preserving
|
||||
seen = set()
|
||||
return [x for x in seq if x not in seen and not seen.add(x)]
|
||||
|
||||
def uniq(seq):
|
||||
# Not order preserving
|
||||
return {}.fromkeys(seq).keys()
|
||||
|
||||
class PyNMA(object):
|
||||
"""PyNMA(apikey=[], developerkey=None)
|
||||
takes 2 optional arguments:
|
||||
- (opt) apykey: might me a string containing 1 key or an array of keys
|
||||
- (opt) developerkey: where you can store your developer key
|
||||
"""
|
||||
|
||||
def __init__(self, apikey=[], developerkey=None):
|
||||
self._developerkey = None
|
||||
self.developerkey(developerkey)
|
||||
if apikey:
|
||||
if type(apikey) == str:
|
||||
apikey = [apikey]
|
||||
self._apikey = uniq(apikey)
|
||||
|
||||
def addkey(self, key):
|
||||
"Add a key (register ?)"
|
||||
if type(key) == str:
|
||||
if not key in self._apikey:
|
||||
self._apikey.append(key)
|
||||
elif type(key) == list:
|
||||
for k in key:
|
||||
if not k in self._apikey:
|
||||
self._apikey.append(k)
|
||||
|
||||
def delkey(self, key):
|
||||
"Removes a key (unregister ?)"
|
||||
if type(key) == str:
|
||||
if key in self._apikey:
|
||||
self._apikey.remove(key)
|
||||
elif type(key) == list:
|
||||
for k in key:
|
||||
if key in self._apikey:
|
||||
self._apikey.remove(k)
|
||||
|
||||
def developerkey(self, developerkey):
|
||||
"Sets the developer key (and check it has the good length)"
|
||||
if type(developerkey) == str and len(developerkey) == 48:
|
||||
self._developerkey = developerkey
|
||||
|
||||
def push(self, application="", event="", description="", url="", priority=0, batch_mode=False):
|
||||
"""Pushes a message on the registered API keys.
|
||||
takes 5 arguments:
|
||||
- (req) application: application name [256]
|
||||
- (req) event: event name [1000]
|
||||
- (req) description: description [10000]
|
||||
- (opt) url: url [512]
|
||||
- (opt) priority: from -2 (lowest) to 2 (highest) (def:0)
|
||||
- (opt) batch_mode: call API 5 by 5 (def:False)
|
||||
|
||||
Warning: using batch_mode will return error only if all API keys are bad
|
||||
cf: http://nma.usk.bz/api.php
|
||||
"""
|
||||
datas = {
|
||||
'application': application[:256].encode('utf8'),
|
||||
'event': event[:1024].encode('utf8'),
|
||||
'description': description[:10000].encode('utf8'),
|
||||
'priority': priority
|
||||
}
|
||||
|
||||
if url:
|
||||
datas['url'] = url[:512]
|
||||
|
||||
if self._developerkey:
|
||||
datas['developerkey'] = self._developerkey
|
||||
|
||||
results = {}
|
||||
|
||||
if not batch_mode:
|
||||
for key in self._apikey:
|
||||
datas['apikey'] = key
|
||||
res = self.callapi('POST', ADD_PATH, datas)
|
||||
results[key] = res
|
||||
else:
|
||||
for i in range(0, len(self._apikey), 5):
|
||||
datas['apikey'] = ",".join(self._apikey[i:i+5])
|
||||
res = self.callapi('POST', ADD_PATH, datas)
|
||||
results[datas['apikey']] = res
|
||||
return results
|
||||
|
||||
def callapi(self, method, path, args):
|
||||
headers = { 'User-Agent': USER_AGENT }
|
||||
if method == "POST":
|
||||
headers['Content-type'] = "application/x-www-form-urlencoded"
|
||||
http_handler = HTTPSConnection(API_SERVER)
|
||||
http_handler.request(method, path, urlencode(args), headers)
|
||||
resp = http_handler.getresponse()
|
||||
|
||||
try:
|
||||
res = self._parse_reponse(resp.read())
|
||||
except Exception, e:
|
||||
res = {'type': "pynmaerror",
|
||||
'code': 600,
|
||||
'message': str(e)
|
||||
}
|
||||
pass
|
||||
|
||||
return res
|
||||
|
||||
def _parse_reponse(self, response):
|
||||
root = parseString(response).firstChild
|
||||
for elem in root.childNodes:
|
||||
if elem.nodeType == elem.TEXT_NODE: continue
|
||||
if elem.tagName == 'success':
|
||||
res = dict(elem.attributes.items())
|
||||
res['message'] = ""
|
||||
res['type'] = elem.tagName
|
||||
return res
|
||||
if elem.tagName == 'error':
|
||||
res = dict(elem.attributes.items())
|
||||
res['message'] = elem.firstChild.nodeValue
|
||||
res['type'] = elem.tagName
|
||||
return res
|
||||
|
||||
|
||||
Reference in New Issue
Block a user