Пример #1
0
    def connect(self):
        # Load host from config and split out port.
        host = clean_host(self.conf('host'), protocol=False).split(':')

        if not is_int(host[1]):
            log.error('Config properties are not filled in correctly, port is missing.')
            return False

        # This is where v4 and v5 begin to differ
        if(self.conf('version') == 'v4'):
            if not self.conf('api_key'):
                log.error('Config properties are not filled in correctly, API key is missing.')
                return False

            url = 'http://' + str(host[0]) + ':' + str(host[1]) + '/jsonrpc'
            client = JsonRpcClient(url, 'Token ' + self.conf('api_key'))
            self.hadouken_api = HadoukenAPIv4(client)

            return True
        else:
            auth_type = self.conf('auth_type')
            header = None

            if auth_type == 'api_key':
                header = 'Token ' + self.conf('api_key')
            elif auth_type == 'user_pass':
                header = 'Basic ' + b64encode(self.conf('auth_user') + ':' + self.conf('auth_pass'))

            url = 'http://' + str(host[0]) + ':' + str(host[1]) + '/api'
            client = JsonRpcClient(url, header)
            self.hadouken_api = HadoukenAPIv5(client)

            return True

        return False
Пример #2
0
    def getAuthorizationUrl(self, host=None, **kwargs):

        callback_url = clean_host(host) + '%snotify.%s.credentials/' % (
            Env.get('api_base').lstrip('/'), self.getName().lower())

        oauth_consumer = oauth2.Consumer(self.consumer_key,
                                         self.consumer_secret)
        oauth_client = oauth2.Client(oauth_consumer)

        resp, content = oauth_client.request(
            self.urls['request'],
            'POST',
            body=try_url_encode({'oauth_callback': callback_url}))

        if resp['status'] != '200':
            log.error(
                'Invalid response from Twitter requesting temp token: %s',
                resp['status'])
            return {
                'success': False,
            }
        else:
            self.request_token = dict(parse_qsl(content))

            auth_url = self.urls['authorize'] + (
                "?oauth_token=%s" % self.request_token['oauth_token'])

            log.info('Redirecting to "%s"', auth_url)
            return {
                'success': True,
                'url': auth_url,
            }
Пример #3
0
    def connect(self, reconnect = False):
        # Already connected?
        if not reconnect and self.rt is not None:
            return self.rt

        url = clean_host(self.conf('host'), protocol=True, ssl=self.conf('ssl'))

        # Automatically add '+https' to 'httprpc' protocol if SSL is enabled
        if self.conf('ssl') and url.startswith('httprpc://'):
            url = url.replace('httprpc://', 'httprpc+https://')

        parsed = urlparse(url)

        # rpc_url is only used on http/https scgi pass-through
        if parsed.scheme in ['http', 'https']:
            url += self.conf('rpc_url')

        # Construct client
        self.rt = RTorrent(
            url, self.get_auth(),
            verify_ssl=self.get_verify_ssl()
        )

        self.error_msg = ''
        try:
            self.rt.connection.verify()
        except AssertionError as e:
            self.error_msg = e.message
            self.rt = None

        return self.rt
Пример #4
0
    def test(self, **kwargs):
        host = self.conf('host')
        apikey = self.conf('apikey')
        message = self.test_message

        host = clean_host(host)
        url = '%semby/Notifications/Admin' % (host)
        values = {
            'Name':
            'CouchPotato',
            'Description':
            message,
            'ImageUrl':
            'https://raw.githubusercontent.com/CouchPotato/CouchPotatoServer/master/couchpotato/static/images/notify.couch.small.png'
        }
        data = json.dumps(values)

        try:
            req = urllib.request.Request(url, data)
            req.add_header('X-MediaBrowser-Token', apikey)
            req.add_header('Content-Type', 'application/json')

            response = urllib.request.urlopen(req)
            result = response.read()
            response.close()
            return {'success': True}

        except (urllib.error.URLError, IOError) as e:
            return False
Пример #5
0
    def connect(self, reconnect=False):
        """ Connect to the delugeRPC, re-use connection when already available
        :param reconnect: force reconnect
        :return: DelugeRPC instance
        """

        # Load host from config and split out port.
        host = clean_host(self.conf('host'), protocol=False).split(':')

        # Force host assignment
        if len(host) == 1:
            host.append(80)

        if not is_int(host[1]):
            log.error(
                'Config properties are not filled in correctly, port is missing.'
            )
            return False

        if not self.drpc or reconnect:
            self.drpc = DelugeRPC(host[0],
                                  port=host[1],
                                  username=self.conf('username'),
                                  password=self.conf('password'))

        return self.drpc
Пример #6
0
    def create_base_url(self):
        host = Env.setting('host')
        if host == '0.0.0.0' or host == '':
            host = 'localhost'
        port = Env.setting('port')
        ssl = Env.setting('ssl_cert') and Env.setting('ssl_key')

        return '%s:%d%s' % (clean_host(
            host, ssl=ssl).rstrip('/'), int(port), Env.get('web_base'))
Пример #7
0
    def createHost(self, host, port = None):

        h = clean_host(host)
        p = urlparse(h)
        h = h.rstrip('/')

        if port and not p.port:
            h += ':%s' % port

        return h
Пример #8
0
    def getAuthorizationUrl(self, host=None, **kwargs):
        callback_url = clean_host(host) + '%sautomation.trakt.credentials/' % (
            Env.get('api_base').lstrip('/'))
        log.debug('callback_url is %s', callback_url)

        target_url = self.urls['oauth'] + "?target=" + callback_url
        log.debug('target_url is %s', target_url)

        return {
            'success': True,
            'url': target_url,
        }
Пример #9
0
    def getAuthorizationUrl(self, host=None, **kwargs):

        callback_url = clean_host(host) + '%sdownloader.putio.credentials/' % (
            Env.get('api_base').lstrip('/'))
        log.debug('callback_url is %s', callback_url)

        target_url = self.oauth_authenticate + "?target=" + callback_url
        log.debug('target_url is %s', target_url)

        return {
            'success': True,
            'url': target_url,
        }
Пример #10
0
    def download(self, data=None, media=None, filedata=None):
        """
        Send a torrent/nzb file to the downloader

        :param data: dict returned from provider
            Contains the release information
        :param media: media dict with information
            Used for creating the filename when possible
        :param filedata: downloaded torrent/nzb filedata
            The file gets downloaded in the searcher and send to this function
            This is done to have fail checking before using the downloader, so the downloader
            doesn't need to worry about that
        :return: boolean
            One fail returns false, but the downloader should log his own errors
        """

        if not media: media = {}
        if not data: data = {}

        response = False
        log.info('Sending "%s" (%s) to Synology.',
                 (data['name'], data['protocol']))

        # Load host from config and split out port.
        host = clean_host(self.conf('host'), protocol=False).split(':')
        if not is_int(host[1]):
            log.error(
                'Config properties are not filled in correctly, port is missing.'
            )
            return False

        try:
            # Send request to Synology
            srpc = SynologyRPC(host[0], host[1], self.conf('username'),
                               self.conf('password'), self.conf('destination'))
            if data['protocol'] == 'torrent_magnet':
                log.info('Adding torrent URL %s', data['url'])
                response = srpc.create_task(url=data['url'])
            elif data['protocol'] in ['nzb', 'torrent']:
                log.info('Adding %s' % data['protocol'])
                if not filedata:
                    log.error('No %s data found', data['protocol'])
                else:
                    filename = data['name'] + '.' + data['protocol']
                    response = srpc.create_task(filename=filename,
                                                filedata=filedata)
        except:
            log.error('Exception while adding torrent: %s',
                      traceback.format_exc())
        finally:
            return self.download_return_id('') if response else False
Пример #11
0
    def test(self):
        """ Check if connection works
        :return: bool
        """

        host = clean_host(self.conf('host'), protocol=False).split(':')
        try:
            srpc = SynologyRPC(host[0], host[1], self.conf('username'),
                               self.conf('password'))
            test_result = srpc.test()
        except:
            return False

        return test_result
Пример #12
0
    def connect(self):
        if self.qb is not None:
            self.qb.logout()

        url = clean_host(self.conf('host'), protocol=True, ssl=False)

        if self.conf('username') and self.conf('password'):
            self.qb = Client(url)
            self.qb.login(username=self.conf('username'),
                          password=self.conf('password'))
        else:
            self.qb = Client(url)

        return self.qb._is_authenticated
Пример #13
0
    def getDomain(self, url=''):

        forced_domain = self.conf('domain')
        if forced_domain:
            return clean_host(forced_domain).rstrip('/') + url

        if not self.proxy_domain:
            for proxy in self.proxy_list:

                prop_name = 'proxy.%s' % proxy
                last_check = float(Env.prop(prop_name, default=0))

                if last_check > time.time() - 86400:
                    continue

                data = ''
                try:
                    data = self.urlopen(proxy, timeout=3, show_error=False)
                except:
                    log.debug('Failed %s proxy %s: %s',
                              (self.getName(), proxy, traceback.format_exc()))

                if self.correctProxy(data):
                    log.debug('Using proxy for %s: %s',
                              (self.getName(), proxy))
                    self.proxy_domain = proxy
                    break

                Env.prop(prop_name, time.time())

        if not self.proxy_domain:
            log.error(
                'No %s proxies left, please add one in settings, or let us know which one to add on the forum.',
                self.getName())
            return None

        return clean_host(self.proxy_domain).rstrip('/') + url
Пример #14
0
    def call(self,
             call,
             parameters=None,
             is_repeat=False,
             auth=True,
             *args,
             **kwargs):

        # Login first
        if not parameters: parameters = {}
        if not self.session_id and auth:
            self.login()

        # Always add session id to request
        if self.session_id:
            parameters['sessionid'] = self.session_id

        params = try_url_encode(parameters)

        url = clean_host(self.conf('host')) + 'api/' + call

        try:
            data = self.getJsonData('%s%s' %
                                    (url, '?' + params if params else ''),
                                    *args,
                                    cache_timeout=0,
                                    show_error=False,
                                    **kwargs)

            if data:
                return data
        except HTTPError as e:
            sc = e.response.status_code
            if sc == 403:
                # Try login and do again
                if not is_repeat:
                    self.login()
                    return self.call(call,
                                     parameters=parameters,
                                     is_repeat=True,
                                     **kwargs)

            log.error('Failed to parsing %s: %s',
                      (self.getName(), traceback.format_exc()))
        except:
            log.error('Failed to parsing %s: %s',
                      (self.getName(), traceback.format_exc()))

        return {}
Пример #15
0
    def connect(self):
        # Load host from config and split out port.
        host = clean_host(self.conf('host'), protocol=False).split(':')
        if not is_int(host[1]):
            log.error(
                'Config properties are not filled in correctly, port is missing.'
            )
            return False

        self.utorrent_api = uTorrentAPI(host[0],
                                        port=host[1],
                                        username=self.conf('username'),
                                        password=self.conf('password'))

        return self.utorrent_api
Пример #16
0
    def connect(self):
        # Load host from config and split out port.
        host = clean_host(self.conf('host')).rstrip('/').rsplit(':', 1)
        if not is_int(host[1]):
            log.error(
                'Config properties are not filled in correctly, port is missing.'
            )
            return False

        self.trpc = TransmissionRPC(host[0],
                                    port=host[1],
                                    rpc_url=self.conf('rpc_url').strip('/ '),
                                    username=self.conf('username'),
                                    password=self.conf('password'))
        return self.trpc
Пример #17
0
    def notify(self, message='', data=None, listener=None):
        host = self.conf('host')
        apikey = self.conf('apikey')

        host = clean_host(host)
        url = '%semby/Library/Movies/Updated' % (host)
        values = {}
        data = urllib.parse.urlencode(values)

        try:
            req = urllib.request.Request(url, data)
            req.add_header('X-MediaBrowser-Token', apikey)

            response = urllib.request.urlopen(req)
            result = response.read()
            response.close()
            return True

        except (urllib.error.URLError, IOError) as e:
            return False
Пример #18
0
    def call(self, request_params, use_json=True, **kwargs):

        url = clean_host(self.conf('host'),
                         ssl=self.conf('ssl')) + 'api?' + try_url_encode(
                             merge_dictionaries(request_params, {
                                 'apikey': self.conf('api_key'),
                                 'output': 'json'
                             }))

        data = self.urlopen(url,
                            timeout=60,
                            show_error=False,
                            headers={'User-Agent': Env.getIdentifier()},
                            **kwargs)
        if use_json:
            d = json.loads(data)
            if d.get('error'):
                log.error('Error getting data from SABNZBd: %s',
                          d.get('error'))
                return {}

            return d.get(request_params['mode']) or d
        else:
            return data
Пример #19
0
 def get_rpc(self):
     url = clean_host(host=self.conf('host'),
                      ssl=self.conf('ssl'),
                      username=self.conf('username'),
                      password=self.conf('password')) + self.rpc
     return xmlrpc.client.ServerProxy(url)
Пример #20
0
    def _searchOnHost(self, host, media, quality, results):

        query = self.buildUrl(media, host)
        url = '%s%s' % (self.getUrl(host['host']), query)
        nzbs = self.getRSSData(url,
                               cache_timeout=1800,
                               headers={'User-Agent': Env.getIdentifier()})

        for nzb in nzbs:

            date = None
            spotter = None
            for item in nzb:
                if date and spotter:
                    break
                if item.attrib.get('name') == 'usenetdate':
                    date = item.attrib.get('value')
                    break

                # Get the name of the person who posts the spot
                if item.attrib.get('name') == 'poster':
                    if "@spot.net" in item.attrib.get('value'):
                        spotter = item.attrib.get('value').split("@")[0]
                        continue

            if not date:
                date = self.get_text_element(nzb, 'pubDate')

            name = self.get_text_element(nzb, 'title')
            detail_url = self.get_text_element(nzb, 'guid')
            nzb_id = detail_url.split('/')[-1:].pop()

            try:
                link = self.get_element(nzb, 'enclosure').attrib['url']
            except:
                link = self.get_text_element(nzb, 'link')

            if '://' not in detail_url:
                detail_url = (clean_host(host['host']) +
                              self.urls['detail']) % try_url_encode(nzb_id)

            if not link:
                link = ((self.getUrl(host['host']) + self.urls['download']) %
                        try_url_encode(nzb_id)) + self.getApiExt(host)

            if not name:
                continue

            name_extra = ''
            if spotter:
                name_extra = spotter

            description = ''
            if "@spot.net" in nzb_id:
                try:
                    # Get details for extended description to retrieve passwords
                    query = self.buildDetailsUrl(nzb_id, host['api_key'])
                    url = '%s%s' % (self.getUrl(host['host']), query)
                    nzb_details = self.getRSSData(
                        url,
                        cache_timeout=1800,
                        headers={'User-Agent': Env.getIdentifier()})[0]

                    description = self.get_text_element(
                        nzb_details, 'description')

                    # Extract a password from the description
                    password = re.search(
                        '(?:' + self.passwords_regex +
                        ')(?: *)(?:\:|\=)(?: *)(.*?)\<br\>|\n|$',
                        description,
                        flags=re.I).group(1)
                    if password:
                        name += ' {{%s}}' % password.strip()
                except:
                    log.debug('Error getting details of "%s": %s',
                              (name, traceback.format_exc()))

            results.append({
                'id':
                nzb_id,
                'provider_extra':
                urlparse(host['host']).hostname or host['host'],
                'name':
                to_unicode(name),
                'name_extra':
                name_extra,
                'age':
                self.calculateAge(int(time.mktime(parse(date).timetuple()))),
                'size':
                int(self.get_element(nzb, 'enclosure').attrib['length']) /
                1024 / 1024,
                'url':
                link,
                'detail_url':
                detail_url,
                'content':
                self.get_text_element(nzb, 'description'),
                'description':
                description,
                'score':
                host['extra_score'],
            })
Пример #21
0
    def getUrl(self, host):
        if '?page=newznabapi' in host:
            return clean_host(host)[:-1] + '&'

        return clean_host(host) + 'api?'
Пример #22
0
    def download(self, data=None, media=None, filedata=None):
        """
        Send a torrent/nzb file to the downloader

        :param data: dict returned from provider
            Contains the release information
        :param media: media dict with information
            Used for creating the filename when possible
        :param filedata: downloaded torrent/nzb filedata
            The file gets downloaded in the searcher and send to this function
            This is done to have failed checking before using the downloader, so the downloader
            doesn't need to worry about that
        :return: boolean
            One faile returns false, but the downloaded should log his own errors
        """

        if not media: media = {}
        if not data: data = {}

        log.info('Sending "%s" (%s) to Transmission.',
                 (data.get('name'), data.get('protocol')))

        if not self.connect():
            return False

        if not filedata and data.get('protocol') == 'torrent':
            log.error('Failed sending torrent, no data')
            return False

        # Set parameters for adding torrent
        params = {'paused': self.conf('paused', default=False)}

        if self.conf('directory'):
            host = clean_host(self.conf('host')).rstrip('/').rsplit(':', 1)
            if os.path.isdir(
                    self.conf('directory')) or not (host[0] == '127.0.0.1'
                                                    or host[0] == 'localhost'):
                params['download-dir'] = self.conf('directory').rstrip(
                    os.path.sep)
            else:
                log.error(
                    'Download directory from Transmission settings: %s doesn\'t exist',
                    self.conf('directory'))

        # Change parameters of torrent
        torrent_params = {}
        if data.get('seed_ratio'):
            torrent_params['seedRatioLimit'] = try_float(
                data.get('seed_ratio'))
            torrent_params['seedRatioMode'] = 1

        if data.get('seed_time'):
            torrent_params['seedIdleLimit'] = try_int(
                data.get('seed_time')) * 60
            torrent_params['seedIdleMode'] = 1

        # Send request to Transmission
        if data.get('protocol') == 'torrent_magnet':
            remote_torrent = self.trpc.add_torrent_uri(data.get('url'),
                                                       arguments=params)
            torrent_params['trackerAdd'] = self.torrent_trackers
        else:
            remote_torrent = self.trpc.add_torrent_file(b64encode(filedata),
                                                        arguments=params)

        if not remote_torrent:
            log.error('Failed sending torrent to Transmission')
            return False

        data = remote_torrent.get('torrent-added') or remote_torrent.get(
            'torrent-duplicate')

        # Change settings of added torrents
        if torrent_params:
            self.trpc.set_torrent(data['hashString'], torrent_params)

        log.info('Torrent sent to Transmission successfully.')
        return self.download_return_id(data['hashString'])