Ejemplo n.º 1
0
def build_config(**kwargs):
    """
    kwargs is filtered for settings that enable updates to Trakt

    :param kwargs: kwargs to be filtered for settings that enable updates to Trakt
    :return: dict of parsed config kwargs where k is Trakt account id, v is a parent location
    """

    config = {}

    root_dirs = []
    if sickbeard.ROOT_DIRS:
        root_pieces = sickbeard.ROOT_DIRS.split('|')
        root_dirs = root_pieces[1:]

    for item in [
            re.findall(r'update-trakt-(\d+)-(.*)', k)
            for k, v in iteritems(kwargs) if k.startswith('update-trakt-')
    ]:
        for account_id, location in item:
            account_id = try_int(account_id, None)
            if None is account_id:
                continue
            for cur_dir in root_dirs:
                account_id = try_int(account_id, None)
                if account_id and decode_str(
                        base64.urlsafe_b64encode(
                            decode_bytes(cur_dir))) == location:
                    if isinstance(config.get(account_id), list):
                        config[account_id] += [cur_dir]
                    else:
                        config[account_id] = [cur_dir]

    return config
Ejemplo n.º 2
0
    def _discover_server(self):

        cs = socket(AF_INET, SOCK_DGRAM)
        mb_listen_port = 7359

        cs.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
        cs.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)
        cs.settimeout(10)
        result, sock_issue = '', None
        for server in ('EmbyServer', 'MediaBrowserServer', 'JellyfinServer'):
            bufr = 'who is %s?' % server
            try:
                assert len(bufr) == cs.sendto(decode_bytes(bufr), ('255.255.255.255', mb_listen_port)), \
                    'Not all data sent through the socket'
                message, host = cs.recvfrom(1024)
                if message:
                    message = decode_str(message)
                    self._log('%s found at %s: udp query response (%s)' %
                              (server, host[0], message))
                    result = ('{"Address":' not in message
                              and message.split('|')[1]
                              or json.loads(message).get('Address', ''))
                    if result:
                        break
            except AssertionError:
                sock_issue = True
            except (BaseException, Exception):
                pass
        if not sock_issue:
            try:
                cs.shutdown(SHUT_RDWR)
            except (BaseException, Exception):
                pass
        return result
Ejemplo n.º 3
0
    def single_request(self, host, handler, request_body, verbose=0):
        # Add SCGI headers to the request.
        headers = [('CONTENT_LENGTH', str(len(request_body))), ('SCGI', '1')]
        header = '\x00'.join(['%s\x00%s' % (key, value) for key, value in headers]) + '\x00'
        header = '%d:%s' % (len(header), header)
        request_body = '%s,%s' % (header, request_body)

        sock = None

        try:
            if host:
                parsed = urlparse('//' + host)
                host, port = parsed.hostname, parsed.port

                addrinfo = socket.getaddrinfo(host, int(port), socket.AF_INET,
                                              socket.SOCK_STREAM)
                sock = socket.socket(*addrinfo[0][:3])
                sock.connect(addrinfo[0][4])
            else:
                sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
                sock.connect(handler)

            # noinspection PyAttributeOutsideInit
            self.verbose = verbose

            sock.send(decode_bytes(request_body))
            return self.parse_response(sock.makefile())
        finally:
            if sock:
                sock.close()
Ejemplo n.º 4
0
def makeProviderList():
    providers = [
        x.provider for x in [getProviderModule(y) for y in __all__] if x
    ]
    import browser_ua
    import zlib
    headers = [1449593765, 1597250020, 1524942228]
    for p in providers:
        if abs(zlib.crc32(decode_bytes(p.name))) + 40000400 in headers:
            p.headers.update({'User-Agent': browser_ua.get_ua()})
    return providers
Ejemplo n.º 5
0
    def _notify(self,
                title,
                body,
                user_key=None,
                api_key=None,
                priority=None,
                device=None,
                sound=None,
                **kwargs):
        """
        Sends a pushover notification to the address provided

        title: The title of the message
        msg: The message to send (unicode)
        user_key: The pushover user id to send the message to (or to subscribe with)

        returns: True if the message succeeded, False otherwise
        """
        user_key = self._choose(user_key, sickbeard.PUSHOVER_USERKEY)
        api_key = self._choose(api_key, sickbeard.PUSHOVER_APIKEY)
        priority = self._choose(priority, sickbeard.PUSHOVER_PRIORITY)
        device = self._choose(device, sickbeard.PUSHOVER_DEVICE)
        sound = self._choose(sound, sickbeard.PUSHOVER_SOUND)

        # build up the URL and parameters
        params = dict(title=title,
                      message=decode_str(body.strip()),
                      user=user_key,
                      timestamp=int(time.time()))
        if api_key:
            params.update(token=api_key)
        if priority:
            params.update(priority=priority)
        if not device:
            params.update(device=device)
        if not sound:
            params.update(sound=sound)

        # send the request to pushover
        result = None
        try:
            req = urllib.request.Request(API_URL)
            # PY2 http_response_obj has no `with` context manager
            http_response_obj = urllib.request.urlopen(
                req, decode_bytes(urlencode(params)))
            http_response_obj.close()

        except urllib.error.HTTPError as e:
            # HTTP status 404 if the provided email address isn't a Pushover user.
            if 404 == e.code:
                result = 'Username is wrong/not a Pushover email. Pushover will send an email to it'
                self._log_warning(result)

            # For HTTP status code 401's, it is because you are passing in either an invalid token,
            # or the user has not added your service.
            elif 401 == e.code:

                # HTTP status 401 if the user doesn't have the service added
                subscribe_note = self._notify(title, body, user_key)
                if subscribe_note:
                    self._log_debug('Subscription sent')
                    # return True
                else:
                    result = 'Subscription could not be sent'
                    self._log_error(result)
            else:
                # If you receive an HTTP status code of 400, it is because you failed to send the proper parameters
                if 400 == e.code:
                    result = 'Wrong data sent to Pushover'

                # If you receive a HTTP status code of 429,
                #  it is because the message limit has been reached (free limit is 7,500)
                elif 429 == e.code:
                    result = 'API message limit reached - try a different API key'

                # If you receive a HTTP status code of 500, service is unavailable
                elif 500 == e.code:
                    result = 'Unable to connect to API, service unavailable'

                self._log_error(result)

        return self._choose(
            (True, 'Failed to send notification: %s' % result)[bool(result)],
            not bool(result))
Ejemplo n.º 6
0
    def _notify(self, title, body, access_token=None, sound=None, **kwargs):
        """
        Sends a boxcar2 notification to the address provided

        title: The title of the message
        body: The message to send
        access_token: To send to this device
        sound: Sound profile to use

        returns: True if the message succeeded, False otherwise
        """
        access_token = self._choose(access_token,
                                    sickbeard.BOXCAR2_ACCESSTOKEN)
        sound = self._choose(sound, sickbeard.BOXCAR2_SOUND)

        # build up the URL and parameters
        # more info goes here -
        # https://boxcar.uservoice.com/knowledgebase/articles/306788-how-to-send-your-boxcar-account-a-notification
        body = decode_str(body.strip())

        data = urlencode({
            'user_credentials': access_token,
            'notification[title]': '%s - %s' % (title, body),
            'notification[long_message]': body,
            'notification[sound]': sound,
            'notification[source_name]': 'SickGear',
            'notification[icon_url]': self._sg_logo_url
        })

        # send the request to boxcar2
        result = None
        try:
            req = urllib.request.Request(
                'https://new.boxcar.io/api/notifications')
            # PY2 http_response_obj has no `with` context manager
            http_response_obj = urllib.request.urlopen(req, decode_bytes(data))
            http_response_obj.close()

        except urllib.error.HTTPError as e:
            if not hasattr(e, 'code'):
                self._log_error(u'Notification failed: %s' % ex(e))
            else:
                result = 'Notification failed. Error code: %s' % e.code
                self._log_error(result)

                if 503 == e.code:
                    result = 'Server too busy to handle the request at this time'
                    self._log_warning(result)
                else:
                    if 404 == e.code:
                        result = 'Access token is wrong/not associated to a device'
                        self._log_error(result)
                    elif 401 == e.code:
                        result = 'Access token not recognized'
                        self._log_error(result)
                    elif 400 == e.code:
                        result = 'Wrong data sent to Boxcar'
                        self._log_error(result)
        except urllib.error.URLError as e:
            self._log_error(u'Notification failed: %s' % ex(e))

        return self._choose(
            (True, 'Failed to send notification: %s' % result)[bool(result)],
            not bool(result))