コード例 #1
0
ファイル: searcher.py プロジェクト: NeuralBlade/headphones
def preprocesstorrent(resultlist):
    selresult = ""
    for result in resultlist:
        if selresult == "":
            selresult = result
        elif int(selresult[1]) < int(result[1]): # if size is lower than new result replace previous selected result (bigger size = better quality?)
            selresult = result
            
    try:
        request = urllib2.Request(selresult[2])
        request.add_header('Accept-encoding', 'gzip')
        
        if selresult[3] == 'Kick Ass Torrent':
            request.add_header('Referer', 'http://kat.ph/')
            
        response = urllib2.urlopen(request)
        if response.info().get('Content-Encoding') == 'gzip':
            buf = StringIO(response.read())
            f = gzip.GzipFile(fileobj=buf)
            torrent = f.read()
        else:
            torrent = response.read()
    except ExpatError:
        logger.error('Unable to torrent %s' % selresult[2])
        
    return torrent, selresult
コード例 #2
0
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))
コード例 #3
0
ファイル: helpers.py プロジェクト: NovaXeros/headphones
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
        from lib.certgen import createKeyPair, createCertRequest, createCertificate, TYPE_RSA, serial
    except:
        logger.warn("pyOpenSSL module missing, please install to enable HTTPS")
        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 Exception, e:
        logger.error("Error creating SSL key and certificate: %s", e)
        return False
コード例 #4
0
 def musicScan(self, path, redirect=None):
   headphones.MUSIC_DIR = path
   headphones.config_write()
   try:
     threading.Thread(target=librarysync.libraryScan).start()
   except Exception, e:
     logger.error('Unable to complete the scan: %s' % e)
コード例 #5
0
ファイル: postprocessor.py プロジェクト: Kiger333/headphones
def embedLyrics(downloaded_track_list):
    logger.info('Adding lyrics')
    
    # TODO: If adding lyrics for flac & lossy, only fetch the lyrics once
    # and apply it to both files
    for downloaded_track in downloaded_track_list:
        
        try:
            f = MediaFile(downloaded_track)
        except:
            logger.error('Could not read %s. Not checking lyrics' % downloaded_track.decode(headphones.SYS_ENCODING, 'replace'))
            continue
            
        if f.albumartist and f.title:
            metalyrics = lyrics.getLyrics(f.albumartist, f.title)
        elif f.artist and f.title:
            metalyrics = lyrics.getLyrics(f.artist, f.title)
        else:
            logger.info('No artist/track metadata found for track: %s. Not fetching lyrics' % downloaded_track.decode(headphones.SYS_ENCODING, 'replace'))
            metalyrics = None
            
        if lyrics:
            logger.debug('Adding lyrics to: %s' % downloaded_track.decode(headphones.SYS_ENCODING, 'replace'))
            f.lyrics = metalyrics
            f.save()
コード例 #6
0
ファイル: _datamodel.py プロジェクト: maxkoryukov/headphones
    def set(self, value):
        # abbreviation. I am too lazy to write 'self._inikey', will use 'k'
        s = self._section   # section
        k = self._inikey    # key
        t = self._initype   # type

        if self._config_callback is None:
            msg = 'Option [{0}][{1}] was not binded/registered with config'.format(s, k)
            logger.error(msg)
            raise ConfigError(msg)

        config = self._config_callback()

        if s not in config:
            # create section:
            logger.debug('Section [{0}] for option [{0}][{1}] doesn\'t exists in config. Create empty.'.format(s, k))
            config[s] = {}

        if k not in config[s]:
            # debug about new config value:
            logger.debug('Option [{0}][{1}] doesn\'t exists in config. Set to default.'.format(s, k))

        # convert value to storable types:
        if value is None:
            value = ''
        elif not isinstance(value, _primitives):
            logger.debug('Value of option [{0}][{1}] is not primitive [{2}], will `str` it'.format(s, k, type(value)))
            value = str(value)
        else:
            value = t(value)

        config[s][k] = value
コード例 #7
0
ファイル: notifiers.py プロジェクト: rembo10/headphones
    def notify(self, message, event):
        if not headphones.CONFIG.JOIN_ENABLED or \
                not headphones.CONFIG.JOIN_APIKEY:
            return

        icon = "https://cdn.rawgit.com/Headphones/" \
               "headphones/develop/data/images/headphoneslogo.png"

        if not self.deviceid:
            self.deviceid = "group.all"
        l = [x.strip() for x in self.deviceid.split(',')]
        if len(l) > 1:
            self.url += '&deviceIds={deviceid}'
        else:
            self.url += '&deviceId={deviceid}'

        response = urllib2.urlopen(self.url.format(apikey=self.apikey,
                                                   title=quote_plus(event),
                                                   text=quote_plus(
                                                       message.encode(
                                                           "utf-8")),
                                                   icon=icon,
                                                   deviceid=self.deviceid))

        if response:
            logger.info(u"Join notifications sent.")
            return True
        else:
            logger.error(u"Join notification failed.")
            return False
コード例 #8
0
ファイル: music_encoder.py プロジェクト: Begall/headphones
def encode(albumPath):

    # Return if xld details not found
    if XLD:
        global xldProfile
        (xldProfile, xldFormat, xldBitrate) = getXldProfile.getXldProfile(headphones.XLDPROFILE)
        if not xldFormat:
            logger.error('Details for xld profile \'%s\' not found, files will not be re-encoded', xldProfile)
            return None

    tempDirEncode=os.path.join(albumPath,"temp")
    musicFiles=[]
    musicFinalFiles=[]
    musicTempFiles=[]
    encoder = ""

    # Create temporary directory, but remove the old one first.
    try:
        if os.path.exists(tempDirEncode):
            shutil.rmtree(tempDirEncode)
            time.sleep(1)

        os.mkdir(tempDirEncode)
    except Exception, e:
        logger.exception("Unable to create temporary directory")
        return None
コード例 #9
0
ファイル: notifiers.py プロジェクト: bennieb79/headphones
    def notify(self, artist=None, album=None, snatched=None):
        title = 'Headphones'
        api = headphones.NMA_APIKEY
        nma_priority = headphones.NMA_PRIORITY

        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
        else:
            event = artist + ' - ' + album + ' complete!'
            message = "Headphones has downloaded and postprocessed: " + artist + ' [' + album + ']'

        logger.debug(u"NMA event: " + event)
        logger.debug(u"NMA message: " + message)

        batch = False

        p = pynma.PyNMA()
        keys = api.split(',')
        p.addkey(keys)

        if len(keys) > 1: batch = True

        response = p.push(title, event, message, priority=nma_priority, batch_mode=batch)

        if not response[api][u'code'] == u'200':
            logger.error(u'Could not send notification to NotifyMyAndroid')
            return False
        else:
            return True
コード例 #10
0
ファイル: deluge.py プロジェクト: YipYup/headphones
def setTorrentPath(result):
    logger.debug('Deluge: Setting download path')
    if not any(delugeweb_auth):
        _get_auth()

    try:
        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,
                verify=deluge_verify_cert, headers=headers)

            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: %s directory doesn\'t exist, let\'s create it' % move_to)
                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,
                verify=deluge_verify_cert, headers=headers)

            return not json.loads(response.text)['error']

        return True
    except Exception as e:
        logger.error('Deluge: Setting torrent move-to directory failed: %s' % str(e))
        formatted_lines = traceback.format_exc().splitlines()
        logger.error('; '.join(formatted_lines))
        return None
コード例 #11
0
def moveFiles(albumpath, release, tracks):

	try:
		year = release['ReleaseDate'][:4]
	except TypeError:
		year = ''
		
	artist = release['ArtistName'].replace('/', '_')
	album = release['AlbumTitle'].replace('/', '_')
	releasetype = release['Type'].replace('/', '_')

	if release['ArtistName'].startswith('The '):
		sortname = release['ArtistName'][4:]
	else:
		sortname = release['ArtistName']
	
	if sortname.isdigit():
		firstchar = '0-9'
	else:
		firstchar = sortname[0]
		
	lowerfirst = firstchar.lower()
	

	values = {	'artist':	artist,
				'album':	album,
				'year':		year,
				'first':	firstchar,
				'lowerfirst':	lowerfirst,
                                'releasetype':  releasetype
			}
			
	
	folder = helpers.replace_all(headphones.FOLDER_FORMAT, values)
	folder = folder.replace('./', '_/').replace(':','_').replace('?','_')
	
	if folder.endswith('.'):
		folder = folder.replace(folder[len(folder)-1], '_')
	
	destination_path = os.path.normpath(os.path.join(headphones.DESTINATION_DIR, folder)).encode(headphones.SYS_ENCODING)
	
	if os.path.exists(destination_path):
		i = 1
		while True:
			newfolder = folder + '[%i]' % i
			destination_path = os.path.normpath(os.path.join(headphones.DESTINATION_DIR, newfolder)).encode(headphones.SYS_ENCODING)
			if os.path.exists(destination_path):
				i += 1
			else:
				folder = newfolder
				break

	logger.info('Moving files from %s to %s' % (unicode(albumpath, headphones.SYS_ENCODING, errors="replace"), unicode(destination_path, headphones.SYS_ENCODING, errors="replace")))
	
	try:
		os.makedirs(destination_path)
	
	except Exception, e:
		logger.error('Could not create folder for %s. Not moving: %s' % (release['AlbumTitle'], e))
		return albumpath
コード例 #12
0
ファイル: notifiers.py プロジェクト: ogroef/headphones
    def notify(self, artist, album, albumartpath):

        hosts = [x.strip() for x in self.hosts.split(",")]

        header = "Headphones"
        message = "%s - %s added to your library" % (artist, album)
        time = "3000"  # in ms

        for host in hosts:
            logger.info("Sending notification command to XMBC @ " + host)
            try:
                version = self._sendjson(host, "Application.GetProperties", {"properties": ["version"]})["version"][
                    "major"
                ]

                if version < 12:  # Eden
                    notification = header + "," + message + "," + time + "," + albumartpath
                    notifycommand = {"command": "ExecBuiltIn", "parameter": "Notification(" + notification + ")"}
                    request = self._sendhttp(host, notifycommand)

                else:  # Frodo
                    params = {"title": header, "message": message, "displaytime": int(time), "image": albumartpath}
                    request = self._sendjson(host, "GUI.ShowNotification", params)

                if not request:
                    raise Exception

            except Exception:
                logger.error("Error sending notification request to XBMC")
コード例 #13
0
ファイル: notifiers.py プロジェクト: rembo10/headphones
    def notify(self, artist, album, albumartpath):

        hosts = [x.strip() for x in self.hosts.split(',')]

        header = "Headphones"
        message = "%s - %s added to your library" % (artist, album)
        time = "3000"  # in ms

        for host in hosts:
            logger.info('Sending notification command to XMBC @ ' + host)
            try:
                version = self._sendjson(host, 'Application.GetProperties',
                                         {'properties': ['version']})[
                    'version']['major']

                if version < 12:  # Eden
                    notification = header + "," + message + "," + time + \
                                   "," + albumartpath
                    notifycommand = {'command': 'ExecBuiltIn',
                                     'parameter': 'Notification(' +
                                                  notification + ')'}
                    request = self._sendhttp(host, notifycommand)

                else:  # Frodo
                    params = {'title': header, 'message': message,
                              'displaytime': int(time),
                              'image': albumartpath}
                    request = self._sendjson(host, 'GUI.ShowNotification',
                                             params)

                if not request:
                    raise Exception

            except Exception:
                logger.error('Error sending notification request to XBMC')
コード例 #14
0
ファイル: sab.py プロジェクト: bennieb79/headphones
def sendNZB(nzb):

    params = {}

    if headphones.SAB_USERNAME:
        params['ma_username'] = headphones.SAB_USERNAME
    if headphones.SAB_PASSWORD:
        params['ma_password'] = headphones.SAB_PASSWORD
    if headphones.SAB_APIKEY:
        params['apikey'] = headphones.SAB_APIKEY
    if headphones.SAB_CATEGORY:
        params['cat'] = headphones.SAB_CATEGORY

    # if it's a normal result we just pass SAB the URL
    if nzb.resultType == "nzb":
        # for newzbin results send the ID to sab specifically
        if nzb.provider.getID() == 'newzbin':
            id = nzb.provider.getIDFromURL(nzb.url)
            if not id:
                logger.info("Unable to send NZB to sab, can't find ID in URL "+str(nzb.url))
                return False
            params['mode'] = 'addid'
            params['name'] = id
        else:
            params['mode'] = 'addurl'
            params['name'] = nzb.url

    # if we get a raw data result we want to upload it to SAB
    elif nzb.resultType == "nzbdata":
        # Sanitize the file a bit, since we can only use ascii chars with MultiPartPostHandler
        nzbdata = helpers.latinToAscii(nzb.extraInfo[0])
        params['mode'] = 'addfile'
        multiPartParams = {"nzbfile": (helpers.latinToAscii(nzb.name)+".nzb", nzbdata)}

    if not headphones.SAB_HOST.startswith('http'):
        headphones.SAB_HOST = 'http://' + headphones.SAB_HOST

    if headphones.SAB_HOST.endswith('/'):
        headphones.SAB_HOST = headphones.SAB_HOST[0:len(headphones.SAB_HOST)-1]

    url = headphones.SAB_HOST + "/" + "api?" + urllib.urlencode(params)

    try:

        if nzb.resultType == "nzb":
            f = urllib.urlopen(url)
        elif nzb.resultType == "nzbdata":
            cookies = cookielib.CookieJar()
            opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookies),
                                          MultipartPostHandler.MultipartPostHandler)

            req = urllib2.Request(url,
                                  multiPartParams,
                                  headers={'User-Agent': USER_AGENT})

            f = opener.open(req)

    except (EOFError, IOError), e:
        logger.error(u"Unable to connect to SAB with URL: %s" % url)
        return False
コード例 #15
0
ファイル: postprocessor.py プロジェクト: Begall/headphones
def addAlbumArt(artwork, albumpath, release):
    logger.info('Adding album art to folder')
    
    try:
        year = release['ReleaseDate'][:4]
    except TypeError:
        year = ''
    
    values = {  '$Artist':      release['ArtistName'],
                '$Album':       release['AlbumTitle'],
                '$Year':        year,
                '$artist':      release['ArtistName'].lower(),
                '$album':       release['AlbumTitle'].lower(),
                '$year':        year
                }
    
    album_art_name = helpers.replace_all(headphones.ALBUM_ART_FORMAT.strip(), values) + ".jpg"

    album_art_name = helpers.replace_illegal_chars(album_art_name).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, '_')

    try:
        file = open(os.path.join(albumpath, album_art_name), 'wb')
        file.write(artwork)
        file.close()
    except Exception, e:
        logger.error('Error saving album art: %s' % str(e))
        return
コード例 #16
0
ファイル: webserve.py プロジェクト: lgordon/headphones
	def musicScan(self, path):
		headphones.MUSIC_DIR = path
		headphones.config_write()
		try:	
			threading.Thread(target=importer.scanMusic, args=[path]).start()
		except Exception, e:
			logger.error('Unable to complete the scan: %s' % e)
コード例 #17
0
ファイル: utorrent.py プロジェクト: maxkoryukov/headphones
def getFolder(hash):

    # Get Active Directory from settings
    active_dir, completed_dir = getSettingsDirectories()

    if not active_dir:
        logger.error('Could not get "Put new downloads in:" directory from uTorrent settings, please ensure it is set')
        return None

    # Get Torrent Folder Name
    torrent_folder, cacheid = dirTorrent(hash)

    # If there's no folder yet then it's probably a magnet, try until folder is populated
    if torrent_folder == active_dir or not torrent_folder:
        tries = 1
        while (torrent_folder == active_dir or torrent_folder is None) and tries <= 10:
            tries += 1
            time.sleep(6)
            torrent_folder, cacheid = dirTorrent(hash, cacheid)

    if torrent_folder == active_dir or not torrent_folder:
        torrent_folder, cacheid = dirTorrent(hash, cacheid, return_name=True)
        return torrent_folder
    else:
        if headphones.SYS_PLATFORM != "win32":
            torrent_folder = torrent_folder.replace("\\", "/")
        return os.path.basename(os.path.normpath(torrent_folder))
コード例 #18
0
ファイル: lastfm.py プロジェクト: bennieb79/headphones
def request_lastfm(method, **kwargs):
    """
    Call a Last.FM API method. Automatically sets the method and API key. Method
    will return the result if no error occured.

    By default, this method will request the JSON format, since it is more
    lightweight than XML.
    """

    # Prepare request
    kwargs["method"] = method
    kwargs.setdefault("api_key", API_KEY)
    kwargs.setdefault("format", "json")

    # Send request
    logger.debug("Calling Last.FM method: %s", method)
    logger.debug("Last.FM call parameters: %s", kwargs)

    data = request.request_json(ENTRY_POINT, timeout=TIMEOUT, params=kwargs,
        rate_limit=(lock, REQUEST_LIMIT))

    # Parse response and check for errors.
    if not data:
        logger.error("Error calling Last.FM method: %s", method)
        return

    if "error" in data:
        logger.error("Last.FM returned an error: %s", data["message"])
        return

    return data
コード例 #19
0
ファイル: sab.py プロジェクト: DiGiTaLAnGeL92/headphones
def sab_api_call(request_type=None, params={}, **kwargs):
    if not headphones.CONFIG.SAB_HOST.startswith('http'):
        headphones.CONFIG.SAB_HOST = 'http://' + headphones.CONFIG.SAB_HOST

    if headphones.CONFIG.SAB_HOST.endswith('/'):
        headphones.CONFIG.SAB_HOST = headphones.CONFIG.SAB_HOST[
                                     0:len(headphones.CONFIG.SAB_HOST) - 1]

    url = headphones.CONFIG.SAB_HOST + "/" + "api?"

    if headphones.CONFIG.SAB_USERNAME:
        params['ma_username'] = headphones.CONFIG.SAB_USERNAME
    if headphones.CONFIG.SAB_PASSWORD:
        params['ma_password'] = headphones.CONFIG.SAB_PASSWORD
    if headphones.CONFIG.SAB_APIKEY:
        params['apikey'] = headphones.CONFIG.SAB_APIKEY

    if request_type == 'send_nzb' and headphones.CONFIG.SAB_CATEGORY:
        params['cat'] = headphones.CONFIG.SAB_CATEGORY

    params['output'] = 'json'

    response = request.request_json(url, params=params, **kwargs)

    if not response:
        logger.error("Error connecting to SABnzbd on url: %s" % headphones.CONFIG.SAB_HOST)
        return False
    else:
        logger.debug("Successfully connected to SABnzbd on url: %s" % headphones.CONFIG.SAB_HOST)
        return response
コード例 #20
0
ファイル: searcher.py プロジェクト: Geojim/headphones
def preprocess(resultlist):

    if not headphones.USENET_RETENTION:
        usenet_retention = 2000
    else:
        usenet_retention = int(headphones.USENET_RETENTION)
	
    for result in resultlist:
        nzb = getresultNZB(result)
        if nzb:
            try:    
                d = minidom.parseString(nzb)
                node = d.documentElement
                nzbfiles = d.getElementsByTagName("file")
                skipping = False
                for nzbfile in nzbfiles:
                    if int(nzbfile.getAttribute("date")) < (time.time() - usenet_retention * 86400):
                        logger.info('NZB contains a file out of your retention. Skipping.')
                        skipping = True
                        break
                if skipping:
                    continue

                    #TODO: Do we want rar checking in here to try to keep unknowns out?
                    #or at least the option to do so?
            except ExpatError:
                logger.error('Unable to parse the best result NZB. Skipping.')
                continue
            return nzb, result
        else:
            logger.error("Couldn't retrieve the best nzb. Skipping.")
    return (False, False)
コード例 #21
0
ファイル: rutracker.py プロジェクト: noam09/headphones
    def login(self):
        """
        Logs in user
        """

        loginpage = 'http://login.rutracker.org/forum/login.php'
        post_params = {
            'login_username': headphones.CONFIG.RUTRACKER_USER,
            'login_password': headphones.CONFIG.RUTRACKER_PASSWORD,
            'login': b'\xc2\xf5\xee\xe4'  # '%C2%F5%EE%E4'
        }

        logger.info("Attempting to log in to rutracker...")

        try:
            r = self.session.post(loginpage, data=post_params, timeout=self.timeout, allow_redirects=False)
            # try again
            if not self.has_bb_data_cookie(r):
                time.sleep(10)
                r = self.session.post(loginpage, data=post_params, timeout=self.timeout, allow_redirects=False)
            if self.has_bb_data_cookie(r):
                self.loggedin = True
                logger.info("Successfully logged in to rutracker")
            else:
                logger.error(
                    "Could not login to rutracker, credentials maybe incorrect, site is down or too many attempts. Try again later")
                self.loggedin = False
            return self.loggedin
        except Exception as e:
            logger.error("Unknown error logging in to rutracker: %s" % e)
            self.loggedin = False
            return self.loggedin
コード例 #22
0
ファイル: rutracker.py プロジェクト: noam09/headphones
    def utorrent_add_file(self, data):
        host = headphones.CONFIG.UTORRENT_HOST
        if not host.startswith('http'):
            host = 'http://' + host
        if host.endswith('/'):
            host = host[:-1]
        if host.endswith('/gui'):
            host = host[:-4]

        base_url = host
        url = base_url + '/gui/'
        self.session.auth = (headphones.CONFIG.UTORRENT_USERNAME, headphones.CONFIG.UTORRENT_PASSWORD)

        try:
            r = self.session.get(url + 'token.html')
        except Exception as e:
            logger.error('Error getting token: %s', e)
            return

        if r.status_code == 401:
            logger.debug('Error reaching utorrent')
            return

        regex = re.search(r'.+>([^<]+)</div></html>', r.text)
        if regex is None:
            logger.debug('Error reading token')
            return

        self.session.params = {'token': regex.group(1)}
        files = {'torrent_file': ("", data)}

        try:
            self.session.post(url, params={'action': 'add-file'}, files=files)
        except Exception as e:
            logger.exception('Error adding file to utorrent %s', e)
コード例 #23
0
ファイル: request.py プロジェクト: DiGiTaLAnGeL92/headphones
def request_json(url, **kwargs):
    """
    Wrapper for `request_response', which will decode the response as JSON
    object and return the result, if no exceptions are raised.

    As an option, a validator callback can be given, which should return True
    if the result is valid.
    """

    validator = kwargs.pop("validator", None)
    response = request_response(url, **kwargs)

    if response is not None:
        try:
            result = response.json()

            if validator and not validator(result):
                logger.error("JSON validation result failed")
            else:
                return result
        except ValueError:
            logger.error("Response returned invalid JSON data")

            # Debug response
            if headphones.VERBOSE:
                server_message(response)
コード例 #24
0
ファイル: helpers.py プロジェクト: MichaelB1105/filmreel
def create_https_certificates(ssl_cert, ssl_key):
    """
    Create a pair of self-signed HTTPS certificares and store in them in
    'ssl_cert' and 'ssl_key'. Method assumes pyOpenSSL is installed.

    This code is stolen from SickBeard (http://github.com/midgetspy/Sick-Beard).
    """

    from headphones import logger

    from OpenSSL import crypto
    from certgen import createKeyPair, createCertRequest, createCertificate, \
        TYPE_RSA, serial

    # Create the CA Certificate
    cakey = createKeyPair(TYPE_RSA, 2048)
    careq = createCertRequest(cakey, CN="Certificate Authority")
    cacert = createCertificate(careq, (careq, cakey), serial, (0, 60 * 60 * 24 * 365 * 10)) # ten years

    pkey = createKeyPair(TYPE_RSA, 2048)
    req = createCertRequest(pkey, CN="Headphones")
    cert = createCertificate(req, (cacert, cakey), serial, (0, 60 * 60 * 24 * 365 * 10)) # ten years

    # Save the key and certificate to disk
    try:
        with open(ssl_key, "w") as fp:
            fp.write(crypto.dump_privatekey(crypto.FILETYPE_PEM, pkey))
        with open(ssl_cert, "w") as fp:
            fp.write(crypto.dump_certificate(crypto.FILETYPE_PEM, cert))
    except IOError as e:
        logger.error("Error creating SSL key and certificate: %s", e)
        return False

    return True
コード例 #25
0
    def get_torrent(self, url, savelocation=None):

        torrent_id = dict([part.split('=') for part in urlparse(url)[4].split('&')])['t']
        self.cookiejar.set_cookie(cookielib.Cookie(version=0, name='bb_dl', value=torrent_id, port=None, port_specified=False, domain='.rutracker.org', domain_specified=False, domain_initial_dot=False, path='/', path_specified=True, secure=False, expires=None, discard=True, comment=None, comment_url=None, rest={'HttpOnly': None}, rfc2109=False))
        downloadurl = 'http://dl.rutracker.org/forum/dl.php?t=' + torrent_id
        torrent_name = torrent_id + '.torrent'

        try:
            prev = os.umask(headphones.UMASK)
            page = self.opener.open(downloadurl)
            torrent = page.read()
            decoded = bdecode(torrent)
            metainfo = decoded['info']
            tor_hash = sha1(bencode(metainfo)).hexdigest()
            if savelocation:
                download_path = os.path.join(savelocation, torrent_name)
            else:
                tempdir = mkdtemp(suffix='_rutracker_torrents')
                download_path = os.path.join(tempdir, torrent_name)
            fp = open (download_path, 'wb')
            fp.write (torrent)
            fp.close ()
            os.umask(prev)

            # Add file to utorrent
            if headphones.TORRENT_DOWNLOADER == 2:
                self.utorrent_add_file(download_path)

        except Exception, e:
            logger.error('Error getting torrent: %s' % e)
            return False
コード例 #26
0
ファイル: transmission.py プロジェクト: Hellowlol/headphones
def torrentAction(method, arguments):

    host = headphones.CONFIG.TRANSMISSION_HOST
    username = headphones.CONFIG.TRANSMISSION_USERNAME
    password = headphones.CONFIG.TRANSMISSION_PASSWORD

    if not host.startswith("http"):
        host = "http://" + host

    if host.endswith("/"):
        host = host[:-1]

    # Fix the URL. We assume that the user does not point to the RPC endpoint,
    # so add it if it is missing.
    parts = list(urlparse.urlparse(host))

    if not parts[0] in ("http", "https"):
        parts[0] = "http"

    if not parts[2].endswith("/rpc"):
        parts[2] += "/transmission/rpc"

    host = urlparse.urlunparse(parts)

    # Retrieve session id
    auth = (username, password) if username and password else None
    response = request.request_response(host, auth=auth, whitelist_status_code=[401, 409])

    if response is None:
        logger.error("Error gettings Transmission session ID")
        return

    # Parse response
    if response.status_code == 401:
        if auth:
            logger.error("Username and/or password not accepted by " "Transmission")
        else:
            logger.error("Transmission authorization required")

        return
    elif response.status_code == 409:
        session_id = response.headers["x-transmission-session-id"]

        if not session_id:
            logger.error("Expected a Session ID from Transmission")
            return

    # Prepare next request
    headers = {"x-transmission-session-id": session_id}
    data = {"method": method, "arguments": arguments}

    response = request.request_json(host, method="POST", data=json.dumps(data), headers=headers, auth=auth)

    print response

    if not response:
        logger.error("Error sending torrent to Transmission")
        return

    return response
コード例 #27
0
ファイル: utorrent.py プロジェクト: NateWickstrom/headphones
def addTorrent(link, hash):
    uTorrentClient = utorrentclient()

    # Get Active Directory from settings
    active_dir, completed_dir = getSettingsDirectories()

    if not active_dir or not completed_dir:
        logger.error('Could not get "Put new downloads in:" or "Move completed downloads to:" directories from uTorrent settings, please ensure they are set')
        return None

    uTorrentClient.add_url(link)

    # Get Torrent Folder Name
    torrent_folder, cacheid = dirTorrent(hash)

    # If there's no folder yet then it's probably a magnet, try until folder is populated
    if torrent_folder == active_dir or not torrent_folder:
        tries = 1
        while (torrent_folder == active_dir or torrent_folder == None) and tries <= 10:
            tries += 1
            time.sleep(6)
            torrent_folder, cacheid = dirTorrent(hash, cacheid)

    if torrent_folder == active_dir or not torrent_folder:
        torrent_folder, cacheid = dirTorrent(hash, cacheid, return_name=True)
        labelTorrent(hash)
        return torrent_folder
    else:
        labelTorrent(hash)
        return os.path.basename(os.path.normpath(torrent_folder))
コード例 #28
0
ファイル: deluge.py プロジェクト: YipYup/headphones
def setSeedRatio(result):
    logger.debug('Deluge: Setting seed ratio')
    if not any(delugeweb_auth):
        _get_auth()

    ratio = None
    if result['ratio']:
        ratio = result['ratio']

    try:
        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,
                verify=deluge_verify_cert, headers=headers)
            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,
                verify=deluge_verify_cert, headers=headers)

            return not json.loads(response.text)['error']

        return True
    except Exception as e:
        logger.error('Deluge: Setting seed ratio failed: %s' % str(e))
        formatted_lines = traceback.format_exc().splitlines()
        logger.error('; '.join(formatted_lines))
        return None
コード例 #29
0
ファイル: db.py プロジェクト: Christiedb46/headphones
    def action(self, query, args=None):
    
        with db_lock:

            if query == None:
                return
                
            sqlResult = None
            attempt = 0
            
            while attempt < 5:
                try:
                    if args == None:
                        #logger.debug(self.filename+": "+query)
                        sqlResult = self.connection.execute(query)
                    else:
                        #logger.debug(self.filename+": "+query+" with args "+str(args))
                        sqlResult = self.connection.execute(query, args)
                    self.connection.commit()
                    break
                except sqlite3.OperationalError, e:
                    if "unable to open database file" in e.message or "database is locked" in e.message:
                        logger.warn('Database Error: %s' % e)
                        attempt += 1
                        time.sleep(1)
                    else:
                        logger.error('Database error: %s' % e)
                        raise
                except sqlite3.DatabaseError, e:
                    logger.error('Fatal Error executing %s :: %s' % (query, e))
                    raise
コード例 #30
0
ファイル: searcher.py プロジェクト: Geojim/headphones
def preprocesstorrent(resultlist):
    selresult = ""
    for result in resultlist:
        try:
            if selresult == "":
                selresult = result
                request = urllib2.Request(result[2])
                request.add_header('Accept-encoding', 'gzip')
                response = urllib2.urlopen(request)
                if response.info().get('Content-Encoding') == 'gzip':
                    buf = StringIO( response.read())
                    f = gzip.GzipFile(fileobj=buf)
                    torrent = f.read()
                else:
                    torrent = response.read()
            elif int(selresult[1]) < int(result[1]):
                selresult = result
                request = urllib2.Request(result[2])
                request.add_header('Accept-encoding', 'gzip')
                response = urllib2.urlopen(request)
                if response.info().get('Content-Encoding') == 'gzip':
                    buf = StringIO( response.read())
                    f = gzip.GzipFile(fileobj=buf)
                    torrent = f.read()
                else:
                    torrent = response.read()
        except ExpatError:
            logger.error('Unable to torrent file. Skipping.')
            continue
    return torrent, selresult
コード例 #31
0
ファイル: __init__.py プロジェクト: aDarkling/headphones
def launch_browser(host, port, root):
    if host == '0.0.0.0':
        host = 'localhost'

    if CONFIG.ENABLE_HTTPS:
        protocol = 'https'
    else:
        protocol = 'http'

    try:
        webbrowser.open('%s://%s:%i%s' % (protocol, host, port, root))
    except Exception as e:
        logger.error('Could not launch browser: %s', e)
コード例 #32
0
ファイル: postprocessor.py プロジェクト: the0dude/headphones
def cleanupFiles(albumpath):
    logger.info('Cleaning up files')
    for r, d, f in os.walk(albumpath):
        for files in f:
            if not any(files.lower().endswith('.' + x.lower())
                       for x in headphones.MEDIA_FORMATS):
                logger.debug('Removing: %s' % files)
                try:
                    os.remove(os.path.join(r, files))
                except Exception, e:
                    logger.error(
                        u'Could not remove file: %s. Error: %s' %
                        (files.decode(headphones.SYS_ENCODING, 'replace'), e))
コード例 #33
0
def embedAlbumArt(artwork, downloaded_track_list):
    logger.info('Embedding album art')
    
    for downloaded_track in downloaded_track_list:
        try:
            f = MediaFile(downloaded_track)
        except:
            logger.error(u'Could not read %s. Not adding album art' % downloaded_track.decode(headphones.SYS_ENCODING, 'replace'))
            continue
            
        logger.debug('Adding album art to: %s' % downloaded_track)
        f.art = artwork
        f.save()
コード例 #34
0
ファイル: postprocessor.py プロジェクト: kiteboy/headphones
def embedAlbumArt(artwork, downloaded_track_list):
	logger.info('Embedding album art')
	
	for downloaded_track in downloaded_track_list:
		try:
			f = MediaFile(downloaded_track)
		except:
			logger.error('Could not read %s. Not adding album art' % downloaded_track)
			continue
			
		logger.debug('Adding album art to: %s' % downloaded_track)
		f.art = artwork
		f.save()
コード例 #35
0
    def login(self):
        """
        Logs in user
        """

        loginpage = 'http://rutracker.org/forum/login.php'
        post_params = {
            'login_username': headphones.CONFIG.RUTRACKER_USER,
            'login_password': headphones.CONFIG.RUTRACKER_PASSWORD,
            'login': b'\xc2\xf5\xee\xe4'  # '%C2%F5%EE%E4'
        }

        logger.info("Attempting to log in to rutracker...")

        try:
            r = self.session.post(loginpage,
                                  data=post_params,
                                  timeout=self.timeout,
                                  allow_redirects=False)
            # try again
            if not self.has_bb_session_cookie(r):
                time.sleep(10)
                if headphones.CONFIG.RUTRACKER_COOKIE:
                    logger.info(
                        "Attempting to log in using predefined cookie...")
                    r = self.session.post(
                        loginpage,
                        data=post_params,
                        timeout=self.timeout,
                        allow_redirects=False,
                        cookies={
                            'bb_session': headphones.CONFIG.RUTRACKER_COOKIE
                        })
                else:
                    r = self.session.post(loginpage,
                                          data=post_params,
                                          timeout=self.timeout,
                                          allow_redirects=False)
            if self.has_bb_session_cookie(r):
                self.loggedin = True
                logger.info("Successfully logged in to rutracker")
            else:
                logger.error(
                    "Could not login to rutracker, credentials maybe incorrect, site is down or too many attempts. Try again later"
                )
                self.loggedin = False
            return self.loggedin
        except Exception as e:
            logger.error("Unknown error logging in to rutracker: %s" % e)
            self.loggedin = False
            return self.loggedin
コード例 #36
0
ファイル: sab.py プロジェクト: raygunxd/headphones
def sendNZB(nzb):

    params = {}
    # if it's a normal result we just pass SAB the URL
    if nzb.resultType == "nzb":
        # for newzbin results send the ID to sab specifically
        if nzb.provider.getID() == 'newzbin':
            id = nzb.provider.getIDFromURL(nzb.url)
            if not id:
                logger.info(
                    "Unable to send NZB to sab, can't find ID in URL " +
                    str(nzb.url))
                return False
            params['mode'] = 'addid'
            params['name'] = id
        else:
            params['mode'] = 'addurl'
            params['name'] = nzb.url

    # if we get a raw data result we want to upload it to SAB
    elif nzb.resultType == "nzbdata":
        # Sanitize the file a bit, since we can only use ascii chars with MultiPartPostHandler
        nzbdata = helpers.latinToAscii(nzb.extraInfo[0])
        params['mode'] = 'addfile'
        files = {"nzbfile": (helpers.latinToAscii(nzb.name) + ".nzb", nzbdata)}
        headers = {'User-Agent': USER_AGENT}

    logger.info("Attempting to connect to SABnzbd on url: %s" %
                headphones.CONFIG.SAB_HOST)
    if nzb.resultType == "nzb":
        response = sab_api_call('send_nzb', params=params)
    elif nzb.resultType == "nzbdata":
        cookies = cookielib.CookieJar()
        response = sab_api_call('send_nzb',
                                params=params,
                                method="post",
                                files=files,
                                cookies=cookies,
                                headers=headers)

    if not response:
        logger.info(u"No data returned from SABnzbd, NZB not sent")
        return False

    if response['status']:
        logger.info(u"NZB sent to SABnzbd successfully")
        return True
    else:
        logger.error(u"Error sending NZB to SABnzbd: %s" % response['error'])
        return False
コード例 #37
0
ファイル: searcher.py プロジェクト: sevenone1/headphones
def preprocesstorrent(resultlist):
    selresult = ""
    for result in resultlist:
        try:
            if selresult == "":
                selresult = result
                torrent = urllib2.urlopen(result[2], timeout=30).read()
            elif int(selresult[1]) < int(result[1]):
                selresult = result
                torrent = urllib2.urlopen(result[2], timeout=30).read()
        except ExpatError:
            logger.error('Unable to torrent file. Skipping.')
            continue
    return torrent, selresult
コード例 #38
0
def sendNZB(nzb):

    addToTop = False
    nzbgetXMLrpc = "%(username)s:%(password)s@%(host)s/xmlrpc"

    if headphones.CONFIG.NZBGET_HOST is None:
        logger.error(u"No NZBget host found in configuration. Please configure it.")
        return False

    if headphones.CONFIG.NZBGET_HOST.startswith('https://'):
        nzbgetXMLrpc = 'https://' + nzbgetXMLrpc
        headphones.CONFIG.NZBGET_HOST.replace('https://', '', 1)
    else:
        nzbgetXMLrpc = 'http://' + nzbgetXMLrpc
        headphones.CONFIG.NZBGET_HOST.replace('http://', '', 1)

    url = nzbgetXMLrpc % {"host": headphones.CONFIG.NZBGET_HOST, "username": headphones.CONFIG.NZBGET_USERNAME, "password": headphones.CONFIG.NZBGET_PASSWORD}

    nzbGetRPC = xmlrpclib.ServerProxy(url)
    try:
        if nzbGetRPC.writelog("INFO", "headphones connected to drop of %s any moment now." % (nzb.name + ".nzb")):
            logger.debug(u"Successfully connected to NZBget")
        else:
            logger.info(u"Successfully connected to NZBget, but unable to send a message" % (nzb.name + ".nzb"))

    except httplib.socket.error:
        logger.error(u"Please check your NZBget host and port (if it is running). NZBget is not responding to this combination")
        return False

    except xmlrpclib.ProtocolError, e:
        if (e.errmsg == "Unauthorized"):
            logger.error(u"NZBget password is incorrect.")
        else:
            logger.error(u"Protocol Error: " + e.errmsg)
        return False
コード例 #39
0
def setTorrentPath(result):
    logger.debug('Deluge: Setting download path')
    if not any(delugeweb_auth):
        _get_auth()

    try:
        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,
                                     verify=deluge_verify_cert,
                                     headers=headers)

            if headphones.CONFIG.DELUGE_DONE_DIRECTORY:
                move_to = headphones.CONFIG.DELUGE_DONE_DIRECTORY
            else:
                move_to = headphones.CONFIG.DOWNLOAD_TORRENT_DIR

            # If Deluge host is remote, disable path checks for now
            if headphones.CONFIG.DELUGE_FOREIGN != 1:
                if not os.path.exists(move_to):
                    logger.debug(
                        'Deluge: %s directory doesn\'t exist, let\'s create it'
                        % move_to)
                    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,
                                     verify=deluge_verify_cert,
                                     headers=headers)

            return not json.loads(response.text)['error']

        return True
    except Exception as e:
        logger.error('Deluge: Setting torrent move-to directory failed: %s' %
                     str(e))
        formatted_lines = traceback.format_exc().splitlines()
        logger.error('; '.join(formatted_lines))
        return None
コード例 #40
0
def getXldProfile(xldProfile):
    xldProfileNotFound = xldProfile

    expanded = os.path.expanduser('~/Library/Preferences/jp.tmkk.XLD.plist')
    if not os.path.isfile(expanded):
        logger.warn("Could not find xld preferences at: %s", expanded)
        return (xldProfileNotFound, None, None)

    # Get xld preferences plist
    try:
        preferences = biplist.readPlist(expanded)
    except (biplist.InvalidPlistException, biplist.NotBinaryPlistException), e:
        logger.error("Error reading xld preferences plist: %s", e)
        return (xldProfileNotFound, None, None)
コード例 #41
0
def removeTorrent(torrentid, remove_data=False):
    logger.debug('Deluge: Remove torrent %s' % torrentid)
    if not any(delugeweb_auth):
        _get_auth()

    try:
        logger.debug('Deluge: Checking if torrent %s finished seeding' % str(torrentid))
        post_data = json.dumps({"method": "web.get_torrent_status",
                                "params": [
                                    torrentid,
                                    [
                                        "name",
                                        "ratio",
                                        "state"
                                    ]
                                ],
                                "id": 26})

        response = requests.post(delugeweb_url, data=post_data.encode('utf-8'), cookies=delugeweb_auth,
            verify=deluge_verify_cert, headers=headers)

        try:
            state = json.loads(response.text)['result']['state']
        except KeyError as e:
            logger.debug('Deluge: "state" KeyError when trying to remove torrent %s' % str(torrentid))
            return False

        not_finished = ["queued", "seeding", "downloading", "checking", "error"]
        result = False
        if state.lower() in not_finished:
            logger.debug('Deluge: Torrent %s is either queued or seeding, not removing yet' % str(torrentid))
            return False
        else:
            logger.debug('Deluge: Removing torrent %s' % str(torrentid))
            post_data = json.dumps({"method": "core.remove_torrent",
                                    "params": [
                                        torrentid,
                                        remove_data
                                        ],
                                    "id": 25})
            response = requests.post(delugeweb_url, data=post_data.encode('utf-8'), cookies=delugeweb_auth,
                verify=deluge_verify_cert, headers=headers)
            result = json.loads(response.text)['result']

            return result
    except Exception as e:
        logger.error('Deluge: Removing torrent failed: %s' % str(e))
        formatted_lines = traceback.format_exc().splitlines()
        logger.error('; '.join(formatted_lines))
        return None
コード例 #42
0
ファイル: versioncheck.py プロジェクト: virusx/headphones
def getVersion():

    if version.HEADPHONES_VERSION.startswith('win32build'):
        headphones.INSTALL_TYPE = 'win'

        # Don't have a way to update exe yet, but don't want to set VERSION to None
        return 'Windows Install', 'master'

    elif os.path.isdir(os.path.join(headphones.PROG_DIR, '.git')):

        headphones.INSTALL_TYPE = 'git'
        output, err = runGit('rev-parse HEAD')

        if not output:
            logger.error('Couldn\'t find latest installed version.')
            cur_commit_hash = None

        cur_commit_hash = str(output)

        if not re.match('^[a-z0-9]+$', cur_commit_hash):
            logger.error('Output doesn\'t look like a hash, not using it')
            cur_commit_hash = None

        if headphones.DO_NOT_OVERRIDE_GIT_BRANCH and headphones.GIT_BRANCH:
            branch_name = headphones.GIT_BRANCH

        else:
            branch_name, err = runGit('rev-parse --abbrev-ref HEAD')
            branch_name = branch_name

            if not branch_name and headphones.GIT_BRANCH:
                logger.error(
                    'Could not retrieve branch name from git. Falling back to %s'
                    % headphones.GIT_BRANCH)
                branch_name = headphones.GIT_BRANCH
            if not branch_name:
                logger.error(
                    'Could not retrieve branch name from git. Defaulting to master'
                )
                branch_name = 'master'

        return cur_commit_hash, branch_name

    else:

        headphones.INSTALL_TYPE = 'source'

        version_file = os.path.join(headphones.PROG_DIR, 'version.txt')

        if not os.path.isfile(version_file):
            return None, 'master'

        with open(version_file, 'r') as f:
            current_version = f.read().strip(' \n\r')

        if current_version:
            return current_version, headphones.GIT_BRANCH
        else:
            return None, 'master'
コード例 #43
0
ファイル: deluge.py プロジェクト: repoarchiver/headphones
def _add_torrent_file(result):
    logger.debug('Deluge: Adding file')
    if not any(delugeweb_auth):
        _get_auth()
    try:
        # content is torrent file contents that needs to be encoded to base64
        post_data = json.dumps({
            "method":
            "core.add_torrent_file",
            "params": [
                result['name'] + '.torrent',
                b64encode(result['content'].encode('utf8')), {}
            ],
            "id":
            2
        })
        response = requests.post(delugeweb_url,
                                 data=post_data.encode('utf-8'),
                                 cookies=delugeweb_auth,
                                 verify=deluge_verify_cert)
        result['hash'] = json.loads(response.text)['result']
        logger.debug('Deluge: Response was %s' %
                     str(json.loads(response.text)))
        return json.loads(response.text)['result']
    except UnicodeDecodeError:
        try:
            # content is torrent file contents that needs to be encoded to base64
            # this time let's try leaving the encoding as is
            logger.debug(
                'Deluge: There was a decoding issue, let\'s try again')
            post_data = json.dumps({
                "method":
                "core.add_torrent_file",
                "params": [
                    result['name'] + '.torrent',
                    b64encode(result['content']), {}
                ],
                "id":
                22
            })
            response = requests.post(delugeweb_url,
                                     data=post_data.encode('utf-8'),
                                     cookies=delugeweb_auth,
                                     verify=deluge_verify_cert)
            result['hash'] = json.loads(response.text)['result']
            logger.debug('Deluge: Response was %s' %
                         str(json.loads(response.text)))
            return json.loads(response.text)['result']
        except Exception as e:
            logger.error(
                'Deluge: Adding torrent file failed after decode: %s' % str(e))
            formatted_lines = traceback.format_exc().splitlines()
            logger.error('; '.join(formatted_lines))
            return False
    except Exception as e:
        logger.error('Deluge: Adding torrent file failed: %s' % str(e))
        formatted_lines = traceback.format_exc().splitlines()
        logger.error('; '.join(formatted_lines))
        return False
コード例 #44
0
def updateFilePermissions(albumpaths):

    for folder in albumpaths:
        logger.info("Updating file permissions in " +
                    folder.decode(headphones.SYS_ENCODING, 'replace'))
        for r, d, f in os.walk(folder):
            for files in f:
                full_path = os.path.join(r, files)
                try:
                    os.chmod(full_path, int(headphones.FILE_PERMISSIONS, 8))
                except:
                    logger.error(
                        "Could not change permissions for file: " +
                        full_path.decode(headphones.SYS_ENCODING, 'replace'))
                    continue
コード例 #45
0
 def get_torrent_data(self, url):
     """
     return the .torrent data
     """
     torrent_id = dict([part.split('=') for part in urlparse(url)[4].split('&')])['t']
     downloadurl = 'http://rutracker.org/forum/dl.php?t=' + torrent_id
     cookie = {'bb_dl': torrent_id}
     try:
         headers = {'Referer': url}
         r = self.session.post(url=downloadurl, cookies=cookie, headers=headers,
                               timeout=self.timeout)
         return r.content
     except Exception as e:
         logger.error('Error getting torrent: %s', e)
         return False
コード例 #46
0
def _add_torrent_file(result):
    logger.debug('Deluge: Adding file')

    options = {}

    if headphones.CONFIG.DELUGE_DOWNLOAD_DIRECTORY:
        options['download_location'] = headphones.CONFIG.DELUGE_DOWNLOAD_DIRECTORY

    if headphones.CONFIG.DELUGE_DONE_DIRECTORY or headphones.CONFIG.DOWNLOAD_TORRENT_DIR:
        options['move_completed'] = 1
        if headphones.CONFIG.DELUGE_DONE_DIRECTORY:
            options['move_completed_path'] = headphones.CONFIG.DELUGE_DONE_DIRECTORY
        else:
            options['move_completed_path'] = headphones.CONFIG.DOWNLOAD_TORRENT_DIR

    if headphones.CONFIG.DELUGE_PAUSED:
        options['add_paused'] = headphones.CONFIG.DELUGE_PAUSED

    if not any(delugeweb_auth):
        _get_auth()
    try:
        # content is torrent file contents that needs to be encoded to base64
        post_data = json.dumps({"method": "core.add_torrent_file",
                                "params": [result['name'] + '.torrent',
                                b64encode(result['content'].encode('utf8')),
                                options],
                                "id": 2})
        response = requests.post(delugeweb_url, data=post_data.encode('utf-8'), cookies=delugeweb_auth,
            verify=deluge_verify_cert, headers=headers)
        result['hash'] = json.loads(response.text)['result']
        logger.debug('Deluge: Response was %s' % str(json.loads(response.text)))
        return json.loads(response.text)['result']
    except UnicodeDecodeError:
        try:
            # content is torrent file contents that needs to be encoded to base64
            # this time let's try leaving the encoding as is
            logger.debug('Deluge: There was a decoding issue, let\'s try again')
            post_data = json.dumps({"method": "core.add_torrent_file",
                                    "params": [result['name'].decode('utf8') + '.torrent',
                                    b64encode(result['content']),
                                    options],
                                    "id": 22})
            response = requests.post(delugeweb_url, data=post_data.encode('utf-8'), cookies=delugeweb_auth,
                verify=deluge_verify_cert, headers=headers)
            result['hash'] = json.loads(response.text)['result']
            logger.debug('Deluge: Response was %s' % str(json.loads(response.text)))
            return json.loads(response.text)['result']
        except Exception as e:
            logger.error('Deluge: Adding torrent file failed after decode: %s' % str(e))
            formatted_lines = traceback.format_exc().splitlines()
            logger.error('; '.join(formatted_lines))
            return False
    except Exception as e:
        logger.error('Deluge: Adding torrent file failed: %s' % str(e))
        formatted_lines = traceback.format_exc().splitlines()
        logger.error('; '.join(formatted_lines))
        return False
コード例 #47
0
def _add_torrent_url(result):
    logger.debug('Deluge: Adding URL')
    if not any(delugeweb_auth):
        _get_auth()
    try:
        post_data = json.dumps({"method": "web.download_torrent_from_url",
                                "params": [result['url'], {}],
                                "id": 32})
        response = requests.post(delugeweb_url, data=post_data.encode('utf-8'), cookies=delugeweb_auth,
            verify=deluge_verify_cert, headers=headers)
        result['location'] = json.loads(response.text)['result']
        logger.debug('Deluge: Response was %s' % str(json.loads(response.text)))
        return json.loads(response.text)['result']
    except Exception as e:
        logger.error('Deluge: Adding torrent URL failed: %s' % str(e))
        formatted_lines = traceback.format_exc().splitlines()
        logger.error('; '.join(formatted_lines))
        return False
コード例 #48
0
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]

    # Either the host ends with a port, or some directory, or rpc
    # If it ends with /rpc we don't have to do anything
    # If it ends with a port we add /transmission/rpc
    # anything else we just add rpc
    if not host.endswith('/rpc'):
        # Check if it ends in a port number
        i = host.rfind(':')
        if i >= 0:
            possible_port = host[i + 1:]
            try:
                port = int(possible_port)
                host = host + "/transmission/rpc"
            except ValueError:
                host = host + "/rpc"
        else:
            logger.error('Transmission port missing')
            return

    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))
コード例 #49
0
ファイル: request.py プロジェクト: TinyHTPC/xbmc-dev-repo
def request_response(url, method="get", auto_raise=True, whitelist_status_code=None, **kwargs):
    """
    Convenient wrapper for `requests.get', which will capture the exceptions and
    log them. On success, the Response object is returned. In case of a
    exception, None is returned.
    """

    # Convert whitelist_status_code to a list if needed
    if whitelist_status_code and type(whitelist_status_code) != list:
        whitelist_status_code = [whitelist_status_code]

    # Disable verification of SSL certificates if requested. Note: this could
    # pose a security issue!
    kwargs["verify"] = headphones.VERIFY_SSL_CERT

    # Map method to the request.XXX method. This is a simple hack, but it allows
    # requests to apply more magic per method. See lib/requests/api.py.
    request_method = getattr(requests, method.lower())

    try:
        # Request the URL
        logger.debug("Requesting URL via %s method: %s", method.upper(), url)
        response = request_method(url, **kwargs)

        # If status code != OK, then raise exception, except if the status code
        # is white listed.
        if whitelist_status_code and auto_raise:
            if response.status_code not in whitelist_status_code:
                try:
                    response.raise_for_status()
                except:
                    logger.debug("Response status code %d is not white listed, raised exception", response.status_code)
                    raise
        elif auto_raise:
            response.raise_for_status()

        return response
    except requests.ConnectionError:
        logger.error("Unable to connect to remote host.")
    except requests.Timeout:
        logger.error("Request timed out.")
    except requests.HTTPError, e:
        if e.response is not None:
            if e.response.status_code >= 500:
                cause = "remote server error"
            elif e.response.status_code >= 400:
                cause = "local request error"
            else:
                # I don't think we will end up here, but for completeness
                cause = "unknown"

            logger.error("Request raise HTTP error with status code %d (%s).", e.response.status_code, cause)
        else:
            logger.error("Request raised HTTP error.")
コード例 #50
0
ファイル: versioncheck.py プロジェクト: virusx/headphones
def runGit(args):

    if headphones.GIT_PATH:
        git_locations = ['"' + headphones.GIT_PATH + '"']
    else:
        git_locations = ['git']

    if platform.system().lower() == 'darwin':
        git_locations.append('/usr/local/git/bin/git')

    output = err = None

    for cur_git in git_locations:
        cmd = cur_git + ' ' + args

        try:
            logger.debug('Trying to execute: "' + cmd + '" with shell in ' +
                         headphones.PROG_DIR)
            p = subprocess.Popen(cmd,
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.STDOUT,
                                 shell=True,
                                 cwd=headphones.PROG_DIR)
            output, err = p.communicate()
            output = output.strip()

            logger.debug('Git output: ' + output)
        except OSError:
            logger.debug('Command failed: %s', cmd)
            continue

        if 'not found' in output or "not recognized as an internal or external command" in output:
            logger.debug('Unable to find git with command ' + cmd)
            output = None
        elif 'fatal:' in output or err:
            logger.error(
                'Git returned bad info. Are you sure this is a git installation?'
            )
            output = None
        elif output:
            break

    return (output, err)
コード例 #51
0
ファイル: pg.py プロジェクト: ebonharme/images
    def select(self, query, args=None):

        logger.info("select Query is " + query)

        #sqlResults = self.action(query, args).fetchall()
        try:
            with self.connection.cursor() as c:
                if args is None:
                    logger.debug("select Args are None")
                    c.execute(query)
                    sqlResults = c.fetchall()
                else:
                    logger.debug("select Args are " + args)
                    c.execute(query, args)
                    sqlResults = c.fetchall()

        except psycopg2.OperationalError, e:
            logger.error('Database error: %s', e)
            raise
コード例 #52
0
def _add_torrent_magnet(result):
    logger.debug('Deluge: Adding magnet')
    if not any(delugeweb_auth):
        _get_auth()
    try:
        post_data = json.dumps({
            "method": "core.add_torrent_magnet",
            "params": [result['url'], {}],
            "id": 2
        })
        response = requests.post(delugeweb_url,
                                 data=post_data.encode('utf-8'),
                                 cookies=delugeweb_auth)
        result['hash'] = json.loads(response.text)['result']
        logger.debug('Deluge: Response was %s' %
                     str(json.loads(response.text)['result']))
        return json.loads(response.text)['result']
    except Exception as e:
        logger.error('Deluge: Adding torrent magnet failed: %s' % str(e))
コード例 #53
0
ファイル: versioncheck.py プロジェクト: sevenone1/headphones
def getVersion():

	if version.HEADPHONES_VERSION.startswith('build '):
		
		headphones.INSTALL_TYPE = 'win'
		
		# Don't have a way to update exe yet, but don't want to set VERSION to None
		return 'Windows Install'
	
	elif os.path.isdir(os.path.join(headphones.PROG_DIR, '.git')):
	
		headphones.INSTALL_TYPE = 'git'
		output, err = runGit('rev-parse HEAD')
		
		if not output:
			logger.error('Couldn\'t find latest installed version.')
			return None
			
		cur_commit_hash = output.strip()
		
		if not re.match('^[a-z0-9]+$', cur_commit_hash):
			logger.error('Output doesn\'t look like a hash, not using it')
			return None
			
		return cur_commit_hash
		
	else:
		
		headphones.INSTALL_TYPE = 'source'
		
		version_file = os.path.join(headphones.PROG_DIR, 'version.txt')
		
		if not os.path.isfile(version_file):
			return None
	
		fp = open(version_file, 'r')
		current_version = fp.read().strip(' \n\r')
		fp.close()
		
		if current_version:
			return current_version
		else:
			return None
コード例 #54
0
    def notify(self, artist, album, albumartpath):

        hosts = [x.strip() for x in self.client_hosts.split(',')]

        header = "Headphones"
        message = "%s - %s added to your library" % (artist, album)
        time = "3000"  # in ms

        for host in hosts:
            logger.info('Sending notification command to Plex client @ ' +
                        host)
            try:
                version = self._sendjson(
                    host, 'Application.GetProperties',
                    {'properties': ['version']})['version']['major']

                if version < 12:  # Eden
                    notification = header + "," + message + "," + time + \
                                   "," + albumartpath
                    notifycommand = {
                        'command': 'ExecBuiltIn',
                        'parameter': 'Notification(' + notification + ')'
                    }
                    request = self._sendhttp(host, notifycommand)

                else:  # Frodo
                    params = {
                        'title': header,
                        'message': message,
                        'displaytime': int(time),
                        'image': albumartpath
                    }
                    request = self._sendjson(host, 'GUI.ShowNotification',
                                             params)

                if not request:
                    raise Exception

            except Exception:
                logger.error(
                    'Error sending notification request to Plex client @ ' +
                    host)
コード例 #55
0
def correctMetadata(albumid, release, downloaded_track_list):
    
    logger.info('Preparing to write metadata to tracks....')
    lossy_items = []
    lossless_items = []
    
    # Process lossless & lossy media formats separately
    for downloaded_track in downloaded_track_list:
        
        try:

            if any(downloaded_track.lower().endswith('.' + x.lower()) for x in headphones.LOSSLESS_MEDIA_FORMATS):
                lossless_items.append(beets.library.Item.from_path(downloaded_track))
            elif any(downloaded_track.lower().endswith('.' + x.lower()) for x in headphones.LOSSY_MEDIA_FORMATS):
                lossy_items.append(beets.library.Item.from_path(downloaded_track))
            else:
                logger.warn("Skipping: " + downloaded_track.decode(headphones.SYS_ENCODING, 'replace') + " because it is not a mutagen friendly file format")
        except Exception, e:
            
            logger.error("Beets couldn't create an Item from: " + downloaded_track.decode(headphones.SYS_ENCODING, 'replace') + " - not a media file?" + str(e))
コード例 #56
0
    def action(self, query, args=None):

        if query == None:
            return

        sqlResult = None

        try:
            with self.connection as c:
                if args == None:
                    sqlResult = c.execute(query)
                else:
                    sqlResult = c.execute(query, args)

        except sqlite3.OperationalError, e:
            if "unable to open database file" in e.message or "database is locked" in e.message:
                logger.warn('Database Error: %s', e)
            else:
                logger.error('Database error: %s', e)
                raise
コード例 #57
0
def split_baby(split_file, split_cmd):
    '''Let's split baby'''
    logger.info('Splitting %s...',
                split_file.decode(headphones.SYS_ENCODING, 'replace'))
    logger.debug(subprocess.list2cmdline(split_cmd))

    # Prevent Windows from opening a terminal window
    startupinfo = None

    if headphones.SYS_PLATFORM == "win32":
        startupinfo = subprocess.STARTUPINFO()
        try:
            startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
        except AttributeError:
            startupinfo.dwFlags |= subprocess._subprocess.STARTF_USESHOWWINDOW

    env = os.environ.copy()
    if 'xld' in split_cmd:
        env['PATH'] += os.pathsep + '/Applications'
    elif headphones.CONFIG.CUE_SPLIT_FLAC_PATH:
        env['PATH'] += os.pathsep + headphones.CONFIG.CUE_SPLIT_FLAC_PATH

    process = subprocess.Popen(split_cmd,
                               startupinfo=startupinfo,
                               stdin=open(os.devnull, 'rb'),
                               stdout=subprocess.PIPE,
                               stderr=subprocess.PIPE,
                               env=env)
    stdout, stderr = process.communicate()

    if process.returncode:
        logger.error('Split failed for %s',
                     split_file.decode(headphones.SYS_ENCODING, 'replace'))
        out = stdout if stdout else stderr
        logger.error('Error details: %s',
                     out.decode(headphones.SYS_ENCODING, 'replace'))
        return False
    else:
        logger.info('Split success %s',
                    split_file.decode(headphones.SYS_ENCODING, 'replace'))
        return True
コード例 #58
0
    def get_torrent(self, url, savelocation=None):

        torrent_id = dict(
            [part.split('=') for part in urlparse(url)[4].split('&')])['t']
        self.cookiejar.set_cookie(
            cookielib.Cookie(version=0,
                             name='bb_dl',
                             value=torrent_id,
                             port=None,
                             port_specified=False,
                             domain='.rutracker.org',
                             domain_specified=False,
                             domain_initial_dot=False,
                             path='/',
                             path_specified=True,
                             secure=False,
                             expires=None,
                             discard=True,
                             comment=None,
                             comment_url=None,
                             rest={'HttpOnly': None},
                             rfc2109=False))
        downloadurl = 'http://dl.rutracker.org/forum/dl.php?t=' + torrent_id
        torrent_name = torrent_id + '.torrent'

        try:
            prev = os.umask(headphones.UMASK)
            page = self.opener.open(downloadurl)
            torrent = page.read()
            if savelocation:
                download_path = os.path.join(savelocation, torrent_name)
            else:
                tempdir = mkdtemp(suffix='_rutracker_torrents')
                download_path = os.path.join(tempdir, torrent_name)
            fp = open(download_path, 'wb')
            fp.write(torrent)
            fp.close()
            os.umask(prev)
        except Exception, e:
            logger.error('Error getting torrent: %s' % e)
            return False
コード例 #59
0
ファイル: lastfm.py プロジェクト: unorthodoxdoc/headphones-1
def getArtists():

    myDB = db.DBConnection()
    results = myDB.select('SELECT ArtistID from artists')

    if not headphones.LASTFM_USERNAME:
        return

    else:
        username = headphones.LASTFM_USERNAME

    url = 'http://ws.audioscrobbler.com/2.0/?method=library.getartists&limit=10000&api_key=%s&user=%s' % (
        api_key, username)
    data = urllib2.urlopen(url, timeout=20).read()

    try:
        d = minidom.parseString(data)
    except:
        logger.error("Could not parse artist list from last.fm data")
        return

    artists = d.getElementsByTagName("artist")

    artistlist = []

    for artist in artists:
        mbidnode = artist.getElementsByTagName("mbid")[0].childNodes

        for node in mbidnode:
            artist_mbid = node.data

        try:
            if not any(artist_mbid in x for x in results):
                artistlist.append(artist_mbid)
        except:
            continue

    from headphones import importer

    for artistid in artistlist:
        importer.addArtisttoDB(artistid)
コード例 #60
0
ファイル: pg.py プロジェクト: ebonharme/images
    def action(self, query, args=None):

        if query is None:
            return

        sqlResult = None

        logger.info("Query is " + query)

        try:
            with self.connection.cursor() as c:
                if args is None:
                    logger.debug("action Args are None")
                    sqlResult = c.execute(query)
                else:
                    logger.debug("action Args are " + args)
                    sqlResult = c.execute(query, args)

        except psycopg2.OperationalError, e:
            logger.error('Database error: %s', e)
            raise