Esempio n. 1
0
    def get_media_info(video_node):

        progress = 0
        if None is not video_node.get('viewOffset') and None is not video_node.get('duration'):
            progress = try_int(video_node.get('viewOffset')) * 100 / try_int(video_node.get('duration'))

        for media in video_node.findall('Media'):
            for part in media.findall('Part'):
                file_name = part.get('file')
                # if '3' > sys.version:  # remove HTML quoted characters, only works in python < 3
                #     file_name = urllib2.unquote(file_name.encode('utf-8', errors='replace'))
                # else:
                file_name = unquote(file_name)

                return {'path_file': file_name, 'media_id': video_node.get('ratingKey'),
                        'played': int(video_node.get('viewCount') or 0), 'progress': progress}
Esempio n. 2
0
def prepare_failed_name(release):
    """Standardizes release name for failed DB
    :param release: release name
    :type release: AnyStr
    :return: standardized release name
    :rtype: AnyStr
    """

    fixed = unquote(release)
    if fixed.endswith('.nzb'):
        fixed = fixed.rpartition('.')[0]

    fixed = re.sub(r'[.\-+ ]', '_', fixed)

    # noinspection PyUnresolvedReferences
    if PY2 and not isinstance(fixed, unicode):
        fixed = text_type(fixed, 'utf-8', 'replace')

    return fixed
Esempio n. 3
0
    def _authorised(self, **kwargs):
        result = False
        if self.digest:
            digest = [x[::-1] for x in self.digest[::-1].rpartition('=')]
            self.digest = digest[2] + digest[1] + quote(unquote(digest[0]))
            params = dict(logged_in=(lambda y='': all([
                self.url and self.session.cookies.get_dict(
                    domain='.' + urlparse(self.url).netloc) and self.session.
                cookies.clear('.' + urlparse(self.url).netloc) is None or True
            ] + [
                'RSS' in y, 'type="password"' not in y,
                self.has_all_cookies(['speedian'], 'inSpeed_')
            ] + [(self.session.cookies.get('inSpeed_' + c) or 'sg!no!pw') in
                 self.digest for c in ['speedian']])),
                          failed_msg=(lambda y=None: None),
                          post_params={'login': False})
            result = super(SpeedCDProvider, self)._authorised(**params)

        if not result and not self.failure_count:
            if self.url and self.digest:
                self.get_url('%slogout.php' % self.url,
                             skip_auth=True,
                             post_data={
                                 'submit.x': 24,
                                 'submit.y': 11
                             })
            self.digest = ''
            params = dict(
                logged_in=(lambda y='': all([
                    self.session.cookies.get_dict(domain='.speed.cd') and self.
                    session.cookies.clear('.speed.cd') is None or True
                ] + [bool(y), not re.search('(?i)type="password"', y)] + [
                    re.search('(?i)Logout', y) or not self.digest or
                    (self.session.cookies.get('inSpeed_speedian') or 'sg!no!pw'
                     ) in self.digest
                ])),
                failed_msg=
                (lambda y='':
                 (re.search(
                     r'(?i)(username|password)((<[^>]+>)|\W)*' +
                     r'(or|and|/|\s)((<[^>]+>)|\W)*(password|incorrect)', y
                 ) and u'Invalid username or password for %s. Check settings'
                  or
                  u'Failed to authenticate or parse a response from %s, abort provider'
                  )),
                post_params={'form_tmpl': True})
            self.urls['login_action'] = self.urls.get('do_login')
            session = super(SpeedCDProvider, self)._authorised(session=None,
                                                               resp_sess=True,
                                                               **params)
            self.urls['login_action'] = ''
            if session:
                self.digest = 'inSpeed_speedian=%s' % session.cookies.get(
                    'inSpeed_speedian')
                sickbeard.save_config()
                result = True
                logger.log('Cookie details for %s updated.' % self.name,
                           logger.DEBUG)
            elif not self.failure_count:
                logger.log(
                    'Invalid cookie details for %s and login failed. Check settings'
                    % self.name, logger.ERROR)
        return result
Esempio n. 4
0
    def _update(self, host=None, show_name=None):
        """ Handle updating Kodi host via HTTP API

        Update the video library for a specific tv show if passed, otherwise update the whole library if option enabled.

        Args:
            show_name: Name of a TV show to target for a library update

        Return:
            True or False
        """

        if not host:
            self._log_warning(u'No host specified, aborting update')
            return False

        self._log_debug(u'Updating library via HTTP method for host: %s' %
                        host)

        # if we're doing per-show
        if show_name:
            self._log_debug(u'Updating library via HTTP method for show %s' %
                            show_name)

            # noinspection SqlResolve
            path_sql = 'SELECT path.strPath' \
                       ' FROM path, tvshow, tvshowlinkpath' \
                       ' WHERE tvshow.c00 = "%s"' % show_name \
                       + ' AND tvshowlinkpath.idShow = tvshow.idShow' \
                         ' AND tvshowlinkpath.idPath = path.idPath'

            # set xml response format, if this fails then don't bother with the rest
            if not self._send(
                    host,
                {
                    'command':
                    'SetResponseFormat(webheader;false;webfooter;false;header;<xml>;footer;</xml>;'
                    'opentag;<tag>;closetag;</tag>;closefinaltag;false)'
                }):
                return False

            # sql used to grab path(s)
            response = self._send(
                host, {'command': 'QueryVideoDatabase(%s)' % path_sql})
            if not response:
                self._log_debug(u'Invalid response for %s on %s' %
                                (show_name, host))
                return False

            try:
                et = XmlEtree.fromstring(quote(response, ':\\/<>'))
            except SyntaxError as e:
                self._log_error(u'Unable to parse XML in response: %s' % ex(e))
                return False

            paths = et.findall('.//field')
            if not paths:
                self._log_debug(u'No valid path found for %s on %s' %
                                (show_name, host))
                return False

            for path in paths:
                # we do not need it double-encoded, gawd this is dumb
                un_enc_path = decode_str(unquote(path.text),
                                         sickbeard.SYS_ENCODING)
                self._log_debug(u'Updating %s on %s at %s' %
                                (show_name, host, un_enc_path))

                if not self._send(
                        host,
                        dict(command='ExecBuiltIn',
                             parameter='Kodi.updatelibrary(video, %s)' %
                             un_enc_path)):
                    self._log_error(
                        u'Update of show directory failed for %s on %s at %s' %
                        (show_name, host, un_enc_path))
                    return False

                # sleep for a few seconds just to be sure kodi has a chance to finish each directory
                if 1 < len(paths):
                    time.sleep(5)
        # do a full update if requested
        else:
            self._log_debug(u'Full library update on host: %s' % host)

            if not self._send(
                    host,
                    dict(command='ExecBuiltIn',
                         parameter='Kodi.updatelibrary(video)')):
                self._log_error(u'Failed full library update on: %s' % host)
                return False

        return True
Esempio n. 5
0
    def _authorised(self, **kwargs):
        result = False
        if self.digest and 'None' not in self.digest and 'login_chk' in self.urls:
            digest = [x[::-1] for x in self.digest[::-1].rpartition('=')]
            self.digest = digest[2] + digest[1] + quote(unquote(digest[0]))
            self.session.cookies = cookiejar_from_dict(
                dict({digest[2]: quote(unquote(digest[0]))}))
            html = self.get_url(self.urls['login_chk'], skip_auth=True)
            result = html and 'RSS' in html and 'type="password"' not in html

        if not result and not self.failure_count:
            if self.url and self.digest:
                self.get_url(self.urls['logout'],
                             skip_auth=True,
                             post_data={
                                 'submit.x': 24,
                                 'submit.y': 11
                             })
            self.digest = ''
            self.session.cookies.clear()
            json = self.get_url(self.urls['login_1'],
                                skip_auth=True,
                                post_data={'username': self.username},
                                parse_json=True)
            resp = filter_list(lambda l: isinstance(l, list),
                               json.get('Fs', []))

            def get_html(_resp):
                for cur_item in _resp:
                    if isinstance(cur_item, list):
                        _html = filter_list(
                            lambda s: isinstance(s, string_types) and
                            'password' in s, cur_item)
                        if not _html:
                            _html = get_html(cur_item)
                        if _html:
                            return _html

            params = {}
            html = get_html(resp)
            if html:
                tags = re.findall(r'(?is)(<input[^>]*?name=[\'"][^\'"]+[^>]*)',
                                  html[0])
                attrs = [[(re.findall(r'(?is)%s=[\'"]([^\'"]+)' % attr, x)
                           or [''])[0] for attr in ['type', 'name', 'value']]
                         for x in tags]
                for itype, name, value in attrs:
                    if 'password' in [itype, name]:
                        params[name] = self.password
                    if name not in ('username',
                                    'password') and 'password' != itype:
                        params.setdefault(name, value)

            if params:
                html = self.get_url(self.urls['login_2'],
                                    skip_auth=True,
                                    post_data=params)
                if html and 'RSS' in html:
                    self.digest = None
                    if self.session.cookies.get('inSpeed_speedian'):
                        self.digest = 'inSpeed_speedian=%s' % self.session.cookies.get(
                            'inSpeed_speedian')
                    sickbeard.save_config()
                    result = True
                    logger.log('Cookie details for %s updated.' % self.name,
                               logger.DEBUG)
            elif not self.failure_count:
                logger.log(
                    'Invalid cookie details for %s and login failed. Check settings'
                    % self.name, logger.ERROR)
        return result
Esempio n. 6
0
    def _update_library_http(self, host=None, show_name=None):
        """Handles updating XBMC host via HTTP API

        Attempts to update the XBMC video library for a specific tv show if passed,
        otherwise update the whole library if enabled.

        Args:
            host: XBMC webserver host:port
            show_name: Name of a TV show to specifically target the library update for

        Returns:
            Returns True or False

        """

        if not host:
            self._log_debug(u'No host passed, aborting update')
            return False

        self._log_debug(u'Updating XMBC library via HTTP method for host: ' +
                        host)

        # if we're doing per-show
        if show_name:
            self._log_debug(u'Updating library via HTTP method for show ' +
                            show_name)

            # noinspection SqlResolve
            path_sql = 'select path.strPath' \
                       ' from path, tvshow, tvshowlinkpath' \
                       ' where tvshow.c00 = "%s"' \
                       ' and tvshowlinkpath.idShow = tvshow.idShow' \
                       ' and tvshowlinkpath.idPath = path.idPath' % show_name

            # use this to get xml back for the path lookups
            xml_command = dict(
                command=
                'SetResponseFormat(webheader;false;webfooter;false;header;<xml>;footer;</xml>;'
                'opentag;<tag>;closetag;</tag>;closefinaltag;false)')
            # sql used to grab path(s)
            sql_command = dict(command='QueryVideoDatabase(%s)' % path_sql)
            # set output back to default
            reset_command = dict(command='SetResponseFormat()')

            # set xml response format, if this fails then don't bother with the rest
            request = self._send_to_xbmc(xml_command, host)
            if not request:
                return False

            sql_xml = self._send_to_xbmc(sql_command, host)
            self._send_to_xbmc(reset_command, host)

            if not sql_xml:
                self._log_debug(u'Invalid response for ' + show_name + ' on ' +
                                host)
                return False

            enc_sql_xml = quote(sql_xml, ':\\/<>')
            try:
                et = XmlEtree.fromstring(enc_sql_xml)
            except SyntaxError as e:
                self._log_error(u'Unable to parse XML response: ' + ex(e))
                return False

            paths = et.findall('.//field')

            if not paths:
                self._log_debug(u'No valid paths found for ' + show_name +
                                ' on ' + host)
                return False

            for path in paths:
                # we do not need it double-encoded, gawd this is dumb
                un_enc_path = decode_str(unquote(path.text),
                                         sickbeard.SYS_ENCODING)
                self._log_debug(u'Updating ' + show_name + ' on ' + host +
                                ' at ' + un_enc_path)
                update_command = dict(
                    command='ExecBuiltIn',
                    parameter='XBMC.updatelibrary(video, %s)' % un_enc_path)
                request = self._send_to_xbmc(update_command, host)
                if not request:
                    self._log_error(u'Update of show directory failed on ' +
                                    show_name + ' on ' + host + ' at ' +
                                    un_enc_path)
                    return False
                # sleep for a few seconds just to be sure xbmc has a chance to finish each directory
                if 1 < len(paths):
                    time.sleep(5)
        # do a full update if requested
        else:
            self._log(u'Doing full library update on host: ' + host)
            update_command = {
                'command': 'ExecBuiltIn',
                'parameter': 'XBMC.updatelibrary(video)'
            }
            request = self._send_to_xbmc(update_command, host)

            if not request:
                self._log_error(u'Full Library update failed on: ' + host)
                return False

        return True