Beispiel #1
0
    def __call_trakt(self, url, extra_data=None, cache_limit=.25, cached=True):
        if not cached: cache_limit = 0
        data={'username': self.username, 'password': self.sha1password}
        if extra_data: data.update(extra_data)
        url = '%s%s%s' % (self.protocol, BASE_URL, url)
        log_utils.log('Trakt Call: %s, data: %s' % (url, data), xbmc.LOGDEBUG)

        db_connection = DB_Connection()
        created, cached_result = db_connection.get_cached_url(url)
        if cached_result and (time.time() - created) < (60 * 60 * cache_limit):
            result = cached_result
            log_utils.log('Returning cached result for: %s' % (url), xbmc.LOGDEBUG)
        else: 
            try:
                f=urllib2.urlopen(url, json.dumps(data), self.timeout)
                result=f.read()
                db_connection.cache_url(url, result)
            except (ssl.SSLError,socket.timeout)  as e:
                if cached_result:
                    result = cached_result
                    log_utils.log('Temporary Trakt Error (%s). Using Cached Page Instead.' % (str(e)), xbmc.LOGWARNING)
                else:
                    raise TransientTraktError('Temporary Trakt Error: '+str(e))
            except urllib2.URLError as e:
                if isinstance(e, urllib2.HTTPError):
                    if e.code in TEMP_ERRORS:
                        if cached_result:
                            result = cached_result
                            log_utils.log('Temporary Trakt Error (%s). Using Cached Page Instead.' % (str(e)), xbmc.LOGWARNING)
                        else:
                            raise TransientTraktError('Temporary Trakt Error: '+str(e))
                    elif e.code == 404:
                        return
                    else:
                        raise
                elif isinstance(e.reason, socket.timeout) or isinstance(e.reason, ssl.SSLError):
                    if cached_result:
                        result = cached_result
                        log_utils.log('Temporary Trakt Error (%s). Using Cached Page Instead' % (str(e)), xbmc.LOGWARNING)
                    else:
                        raise TransientTraktError('Temporary Trakt Error: '+str(e))
                else:
                    raise TraktError('Trakt Error: '+str(e))

        response=json.loads(result)

        if 'status' in response and response['status']=='failure':
            if 'message' in response: raise TraktError(response['message'])
            if 'error' in response: raise TraktError(response['error'])
            else: raise TraktError()
        else:
            #log_utils.log('Trakt Response: %s' % (response), xbmc.LOGDEBUG)
            return response
 def __init__(self):
     self.db_connection = DB_Connection()
class SRT_Scraper():
    def __init__(self):
        self.db_connection = DB_Connection()

    def get_tvshow_id(self, title, year=None):
        match_title = title.lower()
        rows = self.db_connection.get_related_url(VIDEO_TYPES.TVSHOW, title, year, SRT_SOURCE)
        if rows:
            tvshow_id = rows[0][0]
            log_utils.log('Returning local tvshow id: |%s|%s|%s|' % (title, year, tvshow_id), log_utils.LOGDEBUG)
            return tvshow_id

        html = self.__get_cached_url(BASE_URL, 24)
        regex = re.compile('option\s+value="(\d+)"\s*>(.*?)</option')
        site_matches = []
        for item in regex.finditer(html):
            tvshow_id, site_title = item.groups()

            # strip year off title and assign it to year if it exists
            r = re.search('(\s*\((\d{4})\))$', site_title)
            if r:
                site_title = site_title.replace(r.group(1), '')
                site_year = r.group(2)
            else:
                site_year = None

            # print 'show: |%s|%s|%s|' % (tvshow_id, site_title, site_year)
            if match_title == site_title.lower():
                if year is None or year == site_year:
                    self.db_connection.set_related_url(VIDEO_TYPES.TVSHOW, title, year, SRT_SOURCE, tvshow_id)
                    return tvshow_id

                site_matches.append((tvshow_id, site_title, site_year))

        if not site_matches:
            return None
        elif len(site_matches) == 1:
            self.db_connection.set_related_url(VIDEO_TYPES.TVSHOW, title, year, SRT_SOURCE, site_matches[0][0])
            return site_matches[0][0]
        else:
            # there were multiple title matches and year was passed but no exact year matches found
            for match in site_matches:
                # return the match that has no year specified
                if match[2] is None:
                    self.db_connection.set_related_url(VIDEO_TYPES.TVSHOW, title, year, SRT_SOURCE, match[0])
                    return match[0]

    def get_season_subtitles(self, language, tvshow_id, season):
        url = BASE_URL + '/ajax_loadShow.php?show=%s&season=%s&langs=&hd=%s&hi=%s' % (tvshow_id, season, 0, 0)
        html = self.__get_cached_url(url, .25)
        # print html.decode('ascii', 'ignore')
        req_hi = kodi.get_setting('subtitle-hi') == 'true'
        req_hd = kodi.get_setting('subtitle-hd') == 'true'
        items = []
        regex = re.compile('<td>(\d+)</td><td>(\d+)</td><td>.*?</td><td>(.*?)</td><td.*?>(.*?)</td>.*?<td.*?>(.+?)</td><td.*?>(.*?)</td><td.*?>(.*?)</td><td.*?>(.*?)</td><td.*?><a\s+href="(.*?)">.+?</td>',
                           re.DOTALL)
        for match in regex.finditer(html):
            season, episode, srt_lang, version, completed, hi, corrected, hd, srt_url = match.groups()
            if not language or language == srt_lang and (not req_hi or hi) and (not req_hd or hd):
                item = {}
                item['season'] = season
                item['episode'] = episode
                item['language'] = srt_lang
                item['version'] = version

                if completed.lower() == 'completed':
                    item['completed'] = True
                    item['percent'] = '100'
                else:
                    item['completed'] = False
                    r = re.search('([\d.]+)%', completed)
                    if r:
                        item['percent'] = r.group(1)
                    else:
                        item['percent'] = '0'

                item['hi'] = True if hi else False
                item['corrected'] = True if corrected else False
                item['hd'] = True if hd else False
                item['url'] = srt_url
                items.append(item)
        return items

    def get_episode_subtitles(self, language, tvshow_id, season, episode):
        subtitles = self.get_season_subtitles(language, tvshow_id, season)
        items = []
        for subtitle in subtitles:
            if subtitle['episode'] == str(episode):
                items.append(subtitle)

        return items

    def download_subtitle(self, url):
        url = BASE_URL + url
        (response, srt) = self.__get_url(url)
        if not hasattr(response, 'info') or 'Content-Disposition' not in response.info():
            return

        cd = response.info()['Content-Disposition']
        r = re.search('filename="(.*)"', cd)
        if r:
            filename = r.group(1)
        else:
            filename = 'addic7ed_subtitle.srt'
        filename = re.sub('[^\x00-\x7F]', '', filename)

        final_path = os.path.join(kodi.get_setting('subtitle-folder'), filename)
        final_path = kodi.translate_path(final_path)
        if not xbmcvfs.exists(os.path.dirname(final_path)):
            try:
                try: xbmcvfs.mkdirs(os.path.dirname(final_path))
                except: os.mkdir(os.path.dirname(final_path))
            except:
                log_utils.log('Failed to create directory %s' % os.path.dirname(final_path), log_utils.LOGERROR)
                raise

        with open(final_path, 'w') as f:
            f.write(srt)
        return final_path

    def __get_url(self, url):
        try:
            req = urllib2.Request(url)
            host = BASE_URL.replace('http://', '')
            req.add_header('User-Agent', USER_AGENT)
            req.add_header('Host', host)
            req.add_header('Referer', BASE_URL)
            response = urllib2.urlopen(req, timeout=10)
            body = response.read()
            parser = HTMLParser.HTMLParser()
            body = parser.unescape(body)
        except Exception as e:
            kodi.notify(msg='Failed to connect to URL: %s' % (url), duration=5000)
            log_utils.log('Failed to connect to URL %s: (%s)' % (url, e), log_utils.LOGERROR)
            return ('', '')

        return (response, body)

    def __get_cached_url(self, url, cache=8):
        log_utils.log('Fetching Cached URL: %s' % url, log_utils.LOGDEBUG)
        before = time.time()

        _created, _res_header, html = self.db_connection.get_cached_url(url, cache_limit=cache)
        if html:
            log_utils.log('Returning cached result for: %s' % (url), log_utils.LOGDEBUG)
            return html

        log_utils.log('No cached url found for: %s' % url, log_utils.LOGDEBUG)
        req = urllib2.Request(url)

        host = BASE_URL.replace('http://', '')
        req.add_header('User-Agent', USER_AGENT)
        req.add_header('Host', host)
        req.add_header('Referer', BASE_URL)
        try:
            body = self.__http_get_with_retry(url, req)
            body = body.decode('utf-8')
            parser = HTMLParser.HTMLParser()
            body = parser.unescape(body)
        except Exception as e:
            kodi.notify(msg='Failed to connect to URL: %s' % (url), duration=5000)
            log_utils.log('Failed to connect to URL %s: (%s)' % (url, e), log_utils.LOGERROR)
            return ''

        self.db_connection.cache_url(url, body)
        after = time.time()
        log_utils.log('Cached Url Fetch took: %.2f secs' % (after - before), log_utils.LOGDEBUG)
        return body

    def __http_get_with_retry(self, url, request):
        log_utils.log('Fetching URL: %s' % request.get_full_url(), log_utils.LOGDEBUG)
        retries = 0
        html = None
        while retries <= MAX_RETRIES:
            try:
                response = urllib2.urlopen(request, timeout=10)
                html = response.read()
                # if no exception, jump out of the loop
                break
            except socket.timeout:
                retries += 1
                log_utils.log('Retry #%s for URL %s because of timeout' % (retries, url), log_utils.LOGWARNING)
                continue
            except urllib2.HTTPError as e:
                # if it's a temporary code, retry
                if e.code in TEMP_ERRORS:
                    retries += 1
                    log_utils.log('Retry #%s for URL %s because of HTTP Error %s' % (retries, url, e.code), log_utils.LOGWARNING)
                    continue
                # if it's not pass it back up the stack
                else:
                    raise
        else:
            raise

        response.close()
        return html
Beispiel #4
0
 def __get_cached_url(self, url, cache_limit=8):
         
     utils.log('Fetching Cached URL: %s' % url, xbmc.LOGDEBUG)
     before = time.time()
     
     db_connection=DB_Connection()
     html = db_connection.get_cached_url(url, cache_limit)
     if html:
         utils.log('Returning cached result for: %s' % (url), xbmc.LOGDEBUG)
         return html
     
     utils.log('No cached url found for: %s' % url, xbmc.LOGDEBUG)
     req = urllib2.Request(url)
 
     host = re.sub('http://', '', self.base_url)
     req.add_header('User-Agent', USER_AGENT)
     req.add_unredirected_header('Host', host)
     req.add_unredirected_header('Referer', self.base_url)
 
     try:
         body = self.__http_get_with_retry_2(url, req)
         if '<title>Are You a Robot?</title>' in body:
             utils.log('bot detection')
 
             # download the captcha image and save it to a file for use later
             captchaimgurl = 'http://' + host + '/CaptchaSecurityImages.php'
             captcha_save_path = xbmc.translatePath('special://userdata/addon_data/plugin.video.1channel/CaptchaSecurityImage.jpg')
             req = urllib2.Request(captchaimgurl)
             host = re.sub('http://', '', self.base_url)
             req.add_header('User-Agent', USER_AGENT)
             req.add_header('Host', host)
             req.add_header('Referer', self.base_url)
             response = urllib2.urlopen(req)
             the_img = response.read()
             with open(captcha_save_path, 'wb') as f:
                 f.write(the_img)
 
             # now pop open dialog for input
             # TODO: make the size and loc configurable
             img = xbmcgui.ControlImage(550, 15, 240, 100, captcha_save_path)
             wdlg = xbmcgui.WindowDialog()
             wdlg.addControl(img)
             wdlg.show()
             kb = xbmc.Keyboard('', 'Type the letters in the image', False)
             kb.doModal()
             capcode = kb.getText()
             if (kb.isConfirmed()):
                 userInput = kb.getText()
             if userInput != '':
                 # post back user string
                 wdlg.removeControl(img)    
                 capcode = kb.getText()
                 data = {'security_code':capcode,
                         'not_robot':'I\'m Human! I Swear!'}
                 data = urllib.urlencode(data)
                 roboturl = 'http://' + host + '/are_you_a_robot.php'
                 req = urllib2.Request(roboturl)
                 host = re.sub('http://', '', self.base_url)
                 req.add_header('User-Agent', USER_AGENT)
                 req.add_header('Host', host)
                 req.add_header('Referer', self.base_url)
                 response = urllib2.urlopen(req, data)
                 body = self.__get_url(url)
                
             elif userInput == '':
                 dialog = xbmcgui.Dialog()
                 dialog.ok("Robot Check", "You must enter text in the image to continue")
             wdlg.close()
 
         body = unicode(body, 'windows-1252')
         parser = HTMLParser.HTMLParser()
         body = parser.unescape(body)
     except Exception as e:
         dialog = xbmcgui.Dialog()
         dialog.ok("Connection failed", "Failed to connect to url", url)
         utils.log('Failed to connect to URL %s: %s' % (url, str(e)), xbmc.LOGERROR)
         return ''
     
     db_connection.cache_url(url, body)
     after = time.time()
     utils.log('Cached Url Fetch took: %.2f secs' % (after - before), xbmc.LOGDEBUG)
     return body
Beispiel #5
0
    def __get_cached_url(self, url, cache_limit=8):

        utils.log('Fetching Cached URL: %s' % url, xbmc.LOGDEBUG)
        before = time.time()

        db_connection = DB_Connection()
        html = db_connection.get_cached_url(url, cache_limit)
        if html:
            utils.log('Returning cached result for: %s' % (url), xbmc.LOGDEBUG)
            return html

        utils.log('No cached url found for: %s' % url, xbmc.LOGDEBUG)
        req = urllib2.Request(url)

        host = re.sub('http://', '', self.base_url)
        req.add_header('User-Agent', USER_AGENT)
        req.add_unredirected_header('Host', host)
        req.add_unredirected_header('Referer', self.base_url)

        try:
            body = self.__http_get_with_retry_2(url, req)
            if '<title>Are You a Robot?</title>' in body:
                utils.log('bot detection')

                # download the captcha image and save it to a file for use later
                captchaimgurl = 'http://' + host + '/CaptchaSecurityImages.php'
                captcha_save_path = xbmc.translatePath(
                    'special://userdata/addon_data/plugin.video.1channel/CaptchaSecurityImage.jpg'
                )
                req = urllib2.Request(captchaimgurl)
                host = re.sub('http://', '', self.base_url)
                req.add_header('User-Agent', USER_AGENT)
                req.add_header('Host', host)
                req.add_header('Referer', self.base_url)
                response = urllib2.urlopen(req)
                the_img = response.read()
                with open(captcha_save_path, 'wb') as f:
                    f.write(the_img)

                # now pop open dialog for input
                # TODO: make the size and loc configurable
                img = xbmcgui.ControlImage(550, 15, 240, 100,
                                           captcha_save_path)
                wdlg = xbmcgui.WindowDialog()
                wdlg.addControl(img)
                wdlg.show()
                kb = xbmc.Keyboard('', 'Type the letters in the image', False)
                kb.doModal()
                capcode = kb.getText()
                if (kb.isConfirmed()):
                    userInput = kb.getText()
                if userInput != '':
                    # post back user string
                    wdlg.removeControl(img)
                    capcode = kb.getText()
                    data = {
                        'security_code': capcode,
                        'not_robot': 'I\'m Human! I Swear!'
                    }
                    data = urllib.urlencode(data)
                    roboturl = 'http://' + host + '/are_you_a_robot.php'
                    req = urllib2.Request(roboturl)
                    host = re.sub('http://', '', self.base_url)
                    req.add_header('User-Agent', USER_AGENT)
                    req.add_header('Host', host)
                    req.add_header('Referer', self.base_url)
                    response = urllib2.urlopen(req, data)
                    body = self.__get_url(url)

                elif userInput == '':
                    dialog = xbmcgui.Dialog()
                    dialog.ok("Robot Check",
                              "You must enter text in the image to continue")
                wdlg.close()

            body = unicode(body, 'windows-1252', 'ignore')
            parser = HTMLParser.HTMLParser()
            body = parser.unescape(body)
        except Exception as e:
            dialog = xbmcgui.Dialog()
            dialog.ok("Connection failed", "Failed to connect to url", url)
            utils.log('Failed to connect to URL %s: %s' % (url, str(e)),
                      xbmc.LOGERROR)
            return ''

        db_connection.cache_url(url, body)
        after = time.time()
        utils.log('Cached Url Fetch took: %.2f secs' % (after - before),
                  xbmc.LOGDEBUG)
        return body
    def __call_trakt(self, url, method=None, data=None, params=None, auth=True, cache_limit=.25, cached=True):
        res_headers = {}
        if not cached: cache_limit = 0
        if self.offline:
            db_cache_limit = int(time.time()) / 60 / 60
        else:
            if cache_limit > 8:
                db_cache_limit = cache_limit
            else:
                db_cache_limit = 8
        json_data = json.dumps(data) if data else None
        headers = {'Content-Type': 'application/json', 'trakt-api-key': V2_API_KEY, 'trakt-api-version': 2}
        url = '%s%s%s' % (self.protocol, BASE_URL, url)
        if params: url = url + '?' + urllib.urlencode(params)

        db_connection = DB_Connection()
        created, cached_headers, cached_result = db_connection.get_cached_url(url, json_data, db_cache_limit)
        if cached_result and (self.offline or (time.time() - created) < (60 * 60 * cache_limit)):
            result = cached_result
            res_headers = dict(cached_headers)
            log_utils.log('***Using cached result for: %s' % (url), log_utils.LOGDEBUG)
        else:
            auth_retry = False
            while True:
                try:
                    if auth: headers.update({'Authorization': 'Bearer %s' % (self.token)})
                    log_utils.log('***Trakt Call: %s, header: %s, data: %s cache_limit: %s cached: %s' % (url, headers, json_data, cache_limit, cached), log_utils.LOGDEBUG)
                    request = urllib2.Request(url, data=json_data, headers=headers)
                    if method is not None: request.get_method = lambda: method.upper()
                    response = urllib2.urlopen(request, timeout=self.timeout)
                    result = ''
                    while True:
                        data = response.read()
                        if not data: break
                        result += data
                    res_headers = dict(response.info().items())

                    db_connection.cache_url(url, result, json_data, response.info().items())
                    break
                except (ssl.SSLError, socket.timeout) as e:
                    if cached_result:
                        result = cached_result
                        log_utils.log('Temporary Trakt Error (%s). Using Cached Page Instead.' % (str(e)), log_utils.LOGWARNING)
                    else:
                        raise TransientTraktError('Temporary Trakt Error: ' + str(e))
                except urllib2.URLError as e:
                    if isinstance(e, urllib2.HTTPError):
                        if e.code in TEMP_ERRORS:
                            if cached_result:
                                result = cached_result
                                log_utils.log('Temporary Trakt Error (%s). Using Cached Page Instead.' % (str(e)), log_utils.LOGWARNING)
                                break
                            else:
                                raise TransientTraktError('Temporary Trakt Error: ' + str(e))
                        elif e.code == 401 or e.code == 405:
                            # token is fine, profile is private
                            if e.info().getheader('X-Private-User') == 'true':
                                raise TraktAuthError('Object is No Longer Available (%s)' % (e.code))
                            # auth failure retry or a token request
                            elif auth_retry or url.endswith('/oauth/token'):
                                self.token = None
                                kodi.set_setting('trakt_oauth_token', '')
                                kodi.set_setting('trakt_refresh_token', '')
                                raise TraktAuthError('Trakt Call Authentication Failed (%s)' % (e.code))
                            # first try token fail, try to refresh token
                            else:
                                result = self.refresh_token(kodi.get_setting('trakt_refresh_token'))
                                self.token = result['access_token']
                                kodi.set_setting('trakt_oauth_token', result['access_token'])
                                kodi.set_setting('trakt_refresh_token', result['refresh_token'])
                                auth_retry = True
                        elif e.code == 404:
                            raise TraktNotFoundError('Object Not Found (%s)' % (e.code))
                        else:
                            raise
                    elif isinstance(e.reason, socket.timeout) or isinstance(e.reason, ssl.SSLError):
                        if cached_result:
                            result = cached_result
                            log_utils.log('Temporary Trakt Error (%s). Using Cached Page Instead' % (str(e)), log_utils.LOGWARNING)
                            break
                        else:
                            raise TransientTraktError('Temporary Trakt Error: ' + str(e))
                    else:
                        raise TraktError('Trakt Error: ' + str(e))
                except:
                    raise

        try:
            js_data = json.loads(result)
            if 'x-sort-by' in res_headers and 'x-sort-how' in res_headers:
                js_data = utils2.sort_list(res_headers['x-sort-by'], res_headers['x-sort-how'], js_data)
        except ValueError:
            js_data = ''
            if result:
                log_utils.log('Invalid JSON Trakt API Response: %s - |%s|' % (url, js_data), log_utils.LOGERROR)

        # log_utils.log('Trakt Response: %s' % (response), xbmc.LOGDEBUG)
        return js_data
Beispiel #7
0
SORT_FIELDS = [
    (SORT_LIST[int(kodi.get_setting('sort1_field'))], SORT_SIGNS[kodi.get_setting('sort1_order')]),
    (SORT_LIST[int(kodi.get_setting('sort2_field'))], SORT_SIGNS[kodi.get_setting('sort2_order')]),
    (SORT_LIST[int(kodi.get_setting('sort3_field'))], SORT_SIGNS[kodi.get_setting('sort3_order')]),
    (SORT_LIST[int(kodi.get_setting('sort4_field'))], SORT_SIGNS[kodi.get_setting('sort4_order')]),
    (SORT_LIST[int(kodi.get_setting('sort5_field'))], SORT_SIGNS[kodi.get_setting('sort5_order')]),
    (SORT_LIST[int(kodi.get_setting('sort6_field'))], SORT_SIGNS[kodi.get_setting('sort6_order')])]

last_check = datetime.datetime.fromtimestamp(0)

TOKEN = kodi.get_setting('trakt_oauth_token')
use_https = kodi.get_setting('use_https') == 'true'
trakt_timeout = int(kodi.get_setting('trakt_timeout'))
list_size = int(kodi.get_setting('list_size'))
trakt_api = Trakt_API(TOKEN, use_https, list_size, trakt_timeout)
db_connection = DB_Connection()

THEME_LIST = ['Shine', 'Luna_Blue', 'Iconic', 'Simple', 'SALTy', 'SALTy (Blended)', 'SALTy (Blue)', 'SALTy (Frog)', 'SALTy (Green)',
              'SALTy (Macaw)', 'SALTier (Green)', 'SALTier (Orange)', 'SALTier (Red)', 'IGDB', 'Simply Elegant', 'IGDB Redux']
THEME = THEME_LIST[int(kodi.get_setting('theme'))]
if xbmc.getCondVisibility('System.HasAddon(script.salts.themepak)'):
    themepak_path = xbmcaddon.Addon('script.salts.themepak').getAddonInfo('path')
else:
    themepak_path = kodi.get_path()
THEME_PATH = os.path.join(themepak_path, 'art', 'themes', THEME)
PLACE_POSTER = os.path.join(kodi.get_path(), 'resources', 'place_poster.png')

def art(name):
    path = os.path.join(THEME_PATH, name)
    if not xbmcvfs.exists(path):
        if name == 'fanart.jpg':
Beispiel #8
0
    def __call_trakt(self, url, method=None, data=None, params=None, auth=True, cache_limit=0.25, cached=True):
        if not cached:
            cache_limit = 0
        db_cache_limit = cache_limit if cache_limit > 8 else 8
        json_data = json.dumps(data) if data else None
        headers = {"Content-Type": "application/json", "trakt-api-key": V2_API_KEY, "trakt-api-version": 2}
        url = "%s%s%s" % (self.protocol, BASE_URL, url)
        if params:
            url = url + "?" + urllib.urlencode(params)

        db_connection = DB_Connection()
        created, cached_result = db_connection.get_cached_url(url, json_data, db_cache_limit)
        if cached_result and (time.time() - created) < (60 * 60 * cache_limit):
            result = cached_result
            log_utils.log("Returning cached result for: %s" % (url), log_utils.LOGDEBUG)
        else:
            auth_retry = False
            while True:
                try:
                    if auth:
                        headers.update({"Authorization": "Bearer %s" % (self.token)})
                    log_utils.log(
                        "Trakt Call: %s, header: %s, data: %s cache_limit: %s cached: %s"
                        % (url, headers, data, cache_limit, cached),
                        log_utils.LOGDEBUG,
                    )
                    request = urllib2.Request(url, data=json_data, headers=headers)
                    if method is not None:
                        request.get_method = lambda: method.upper()
                    f = urllib2.urlopen(request, timeout=self.timeout)
                    result = ""
                    while True:
                        data = f.read()
                        if not data:
                            break
                        result += data

                    db_connection.cache_url(url, result, json_data)
                    break
                except (ssl.SSLError, socket.timeout) as e:
                    if cached_result:
                        result = cached_result
                        log_utils.log(
                            "Temporary Trakt Error (%s). Using Cached Page Instead." % (str(e)), log_utils.LOGWARNING
                        )
                    else:
                        raise TransientTraktError("Temporary Trakt Error: " + str(e))
                except urllib2.URLError as e:
                    if isinstance(e, urllib2.HTTPError):
                        if e.code in TEMP_ERRORS:
                            if cached_result:
                                result = cached_result
                                log_utils.log(
                                    "Temporary Trakt Error (%s). Using Cached Page Instead." % (str(e)),
                                    log_utils.LOGWARNING,
                                )
                                break
                            else:
                                raise TransientTraktError("Temporary Trakt Error: " + str(e))
                        elif e.code == 401 or e.code == 405:
                            if auth_retry or url.endswith("/token"):
                                self.token = None
                                kodi.set_setting("trakt_oauth_token", "")
                                kodi.set_setting("trakt_refresh_token", "")
                                raise TraktAuthError("Trakt Call Authentication Failed (%s)" % (e.code))
                            else:
                                result = self.get_token()
                                self.token = result["access_token"]
                                kodi.set_setting("trakt_oauth_token", result["access_token"])
                                kodi.set_setting("trakt_refresh_token", result["refresh_token"])
                                auth_retry = True
                        elif e.code == 404:
                            raise TraktNotFoundError()
                        else:
                            raise
                    elif isinstance(e.reason, socket.timeout) or isinstance(e.reason, ssl.SSLError):
                        if cached_result:
                            result = cached_result
                            log_utils.log(
                                "Temporary Trakt Error (%s). Using Cached Page Instead" % (str(e)), log_utils.LOGWARNING
                            )
                            break
                        else:
                            raise TransientTraktError("Temporary Trakt Error: " + str(e))
                    else:
                        raise TraktError("Trakt Error: " + str(e))
                except:
                    raise

        try:
            response = json.loads(result)
        except ValueError:
            response = ""
            if result:
                log_utils.log("Invalid JSON Trakt API Response: %s - |%s|" % (url, result), log_utils.LOGERROR)

        # log_utils.log('Trakt Response: %s' % (response), xbmc.LOGDEBUG)
        return response
Beispiel #9
0
 def __get_db_connection(self):
     worker_id = threading.current_thread().ident
     if not self.__db_connection or self.__worker_id != worker_id:
         self.__db_connection = DB_Connection()
         self.__worker_id = worker_id
     return self.__db_connection
Beispiel #10
0
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
"""
import json
import xbmc
import xbmcgui
import xbmcaddon
import utils
from utils import MODES
from db_utils import DB_Connection

ADDON = xbmcaddon.Addon(id='plugin.video.1channel_bp')
utils.log('Service: Installed Version: %s' % (ADDON.getAddonInfo('version')))

db_connection = DB_Connection()
db_connection.init_database()

class Service(xbmc.Player):
    def __init__(self, *args, **kwargs):
        xbmc.Player.__init__(self, *args, **kwargs)
        self.reset()

        self.last_run = 0
        self.DB = ''
        utils.log('Service: starting...')

    def reset(self):
        utils.log('Service: Resetting...')
        win = xbmcgui.Window(10000)
        win.clearProperty('1ch.playing.title')
Beispiel #11
0
    def __call_trakt(self, url, method=None, data=None, params=None, auth=True, cache_limit=.25, cached=True):
        res_headers = {}
        if not cached: cache_limit = 0
        db_cache_limit = cache_limit if cache_limit > 8 else 8
        json_data = json.dumps(data) if data else None
        headers = {'Content-Type': 'application/json', 'trakt-api-key': V2_API_KEY, 'trakt-api-version': 2}
        url = '%s%s%s' % (self.protocol, BASE_URL, url)
        if params: url = url + '?' + urllib.urlencode(params)

        db_connection = DB_Connection()
        created, cached_result = db_connection.get_cached_url(url, json_data, db_cache_limit)
        if cached_result and (time.time() - created) < (60 * 60 * cache_limit):
            result = cached_result
            log_utils.log('Returning cached result for: %s' % (url), log_utils.LOGDEBUG)
        else:
            auth_retry = False
            while True:
                try:
                    if auth: headers.update({'Authorization': 'Bearer %s' % (self.token)})
                    log_utils.log('Trakt Call: %s, header: %s, data: %s cache_limit: %s cached: %s' % (url, headers, data, cache_limit, cached), log_utils.LOGDEBUG)
                    request = urllib2.Request(url, data=json_data, headers=headers)
                    if method is not None: request.get_method = lambda: method.upper()
                    response = urllib2.urlopen(request, timeout=self.timeout)
                    result = ''
                    while True:
                        data = response.read()
                        if not data: break
                        result += data
                    res_headers = dict(response.info().items())

                    db_connection.cache_url(url, result, json_data)
                    break
                except (ssl.SSLError, socket.timeout) as e:
                    if cached_result:
                        result = cached_result
                        log_utils.log('Temporary Trakt Error (%s). Using Cached Page Instead.' % (str(e)), log_utils.LOGWARNING)
                    else:
                        raise TransientTraktError('Temporary Trakt Error: ' + str(e))
                except urllib2.URLError as e:
                    if isinstance(e, urllib2.HTTPError):
                        if e.code in TEMP_ERRORS:
                            if cached_result:
                                result = cached_result
                                log_utils.log('Temporary Trakt Error (%s). Using Cached Page Instead.' % (str(e)), log_utils.LOGWARNING)
                                break
                            else:
                                raise TransientTraktError('Temporary Trakt Error: ' + str(e))
                        elif e.code == 401 or e.code == 405:
                            # token is fine, profile is private
                            if e.info().getheader('X-Private-User') == 'true':
                                raise TraktAuthError('Object is No Longer Available (%s)' % (e.code))
                            # auth failure retry or a token request
                            elif auth_retry or url.endswith('/token'):
                                self.token = None
                                kodi.set_setting('trakt_oauth_token', '')
                                kodi.set_setting('trakt_refresh_token', '')
                                raise TraktAuthError('Trakt Call Authentication Failed (%s)' % (e.code))
                            # first try token fail, try to refresh token
                            else:
                                result = self.get_token()
                                self.token = result['access_token']
                                kodi.set_setting('trakt_oauth_token', result['access_token'])
                                kodi.set_setting('trakt_refresh_token', result['refresh_token'])
                                auth_retry = True
                        elif e.code == 404:
                            raise TraktNotFoundError('Object Not Found (%s)' % (e.code))
                        else:
                            raise
                    elif isinstance(e.reason, socket.timeout) or isinstance(e.reason, ssl.SSLError):
                        if cached_result:
                            result = cached_result
                            log_utils.log('Temporary Trakt Error (%s). Using Cached Page Instead' % (str(e)), log_utils.LOGWARNING)
                            break
                        else:
                            raise TransientTraktError('Temporary Trakt Error: ' + str(e))
                    else:
                        raise TraktError('Trakt Error: ' + str(e))
                except:
                    raise

        try:
            js_data = json.loads(result)
            if 'x-sort-by' in res_headers and 'x-sort-how' in res_headers:
                js_data = self.__sort_list(res_headers['x-sort-by'], res_headers['x-sort-how'], js_data)
        except ValueError:
            js_data = ''
            if result:
                log_utils.log('Invalid JSON Trakt API Response: %s - |%s|' % (url, js_data), log_utils.LOGERROR)

        # log_utils.log('Trakt Response: %s' % (response), xbmc.LOGDEBUG)
        return js_data
Beispiel #12
0
    def __call_trakt(self, url, data = None, params=None, auth=True, cache_limit=.25, cached=True):
        if not cached: cache_limit = 0
        db_cache_limit = cache_limit if cache_limit > 8 else 8
        json_data=json.dumps(data) if data else None
        headers = {'Content-Type': 'application/json', 'trakt-api-key': V2_API_KEY, 'trakt-api-version': 2}
        if auth: headers.update({'trakt-user-login': self.username, 'trakt-user-token': self.token})
        url = '%s%s%s' % (self.protocol, BASE_URL, url)
        if params: url = url + '?' + urllib.urlencode(params)
        log_utils.log('Trakt Call: %s, header: %s, data: %s' % (url, headers, data), xbmc.LOGDEBUG)

        db_connection = DB_Connection()
        created, cached_result = db_connection.get_cached_url(url, db_cache_limit)
        if cached_result and (time.time() - created) < (60 * 60 * cache_limit):
            result = cached_result
            log_utils.log('Returning cached result for: %s' % (url), xbmc.LOGDEBUG)
        else: 
            login_retry=False
            while True:
                try:
                    request = urllib2.Request(url, data = json_data, headers = headers )
                    f=urllib2.urlopen(request, timeout = self.timeout)
                    result=f.read()
                    db_connection.cache_url(url, result)
                    break
                except (ssl.SSLError,socket.timeout)  as e:
                    if cached_result:
                        result = cached_result
                        log_utils.log('Temporary Trakt Error (%s). Using Cached Page Instead.' % (str(e)), xbmc.LOGWARNING)
                    else:
                        raise TransientTraktError('Temporary Trakt Error: '+str(e))
                except urllib2.URLError as e:
                    if isinstance(e, urllib2.HTTPError):
                        if e.code in TEMP_ERRORS:
                            if cached_result:
                                result = cached_result
                                log_utils.log('Temporary Trakt Error (%s). Using Cached Page Instead.' % (str(e)), xbmc.LOGWARNING)
                                break
                            else:
                                raise TransientTraktError('Temporary Trakt Error: '+str(e))
                        elif e.code == 401:
                            if login_retry or url.endswith('login'):
                                raise
                            else:
                                self.token = self.login()
                                xbmcaddon.Addon('plugin.video.salts').setSetting('trakt_token', self.token)
                                login_retry=True
                        else:
                            raise
                    elif isinstance(e.reason, socket.timeout) or isinstance(e.reason, ssl.SSLError):
                        if cached_result:
                            result = cached_result
                            log_utils.log('Temporary Trakt Error (%s). Using Cached Page Instead' % (str(e)), xbmc.LOGWARNING)
                            break
                        else:
                            raise TransientTraktError('Temporary Trakt Error: '+str(e))
                    else:
                        raise TraktError('Trakt Error: '+str(e))
                else:
                    raise

        response=json.loads(result)

        if 'status' in response and response['status']=='failure':
            if 'message' in response: raise TraktError(response['message'])
            if 'error' in response: raise TraktError(response['error'])
            else: raise TraktError()
        else:
            #log_utils.log('Trakt Response: %s' % (response), xbmc.LOGDEBUG)
            return response
Beispiel #13
0
    def __call_trakt(self, url, data=None, params=None, auth=True, cache_limit=.25, cached=True):
        if not cached: cache_limit = 0
        db_cache_limit = cache_limit if cache_limit > 8 else 8
        json_data = json.dumps(data) if data else None
        headers = {'Content-Type': 'application/json', 'trakt-api-key': V2_API_KEY, 'trakt-api-version': 2}
        url = '%s%s%s' % (self.protocol, BASE_URL, url)
        if params: url = url + '?' + urllib.urlencode(params)

        db_connection = DB_Connection()
        created, cached_result = db_connection.get_cached_url(url, db_cache_limit)
        if cached_result and (time.time() - created) < (60 * 60 * cache_limit):
            result = cached_result
            log_utils.log('Returning cached result for: %s' % (url), log_utils.LOGDEBUG)
        else:
            auth_retry = False
            while True:
                try:
                    if auth: headers.update({'Authorization': 'Bearer %s' % (self.token)})
                    log_utils.log('Trakt Call: %s, header: %s, data: %s' % (url, headers, data), log_utils.LOGDEBUG)
                    request = urllib2.Request(url, data=json_data, headers=headers)
                    f = urllib2.urlopen(request, timeout=self.timeout)
                    result = ''
                    while True:
                        data = f.read()
                        if not data: break
                        result += data

                    db_connection.cache_url(url, result)
                    break
                except (ssl.SSLError, socket.timeout)  as e:
                    if cached_result:
                        result = cached_result
                        log_utils.log('Temporary Trakt Error (%s). Using Cached Page Instead.' % (str(e)), log_utils.LOGWARNING)
                    else:
                        raise TransientTraktError('Temporary Trakt Error: ' + str(e))
                except urllib2.URLError as e:
                    if isinstance(e, urllib2.HTTPError):
                        if e.code in TEMP_ERRORS:
                            if cached_result:
                                result = cached_result
                                log_utils.log('Temporary Trakt Error (%s). Using Cached Page Instead.' % (str(e)), log_utils.LOGWARNING)
                                break
                            else:
                                raise TransientTraktError('Temporary Trakt Error: ' + str(e))
                        elif e.code == 401 or e.code == 405:
                            if auth_retry or url.endswith('/token'):
                                self.token = None
                                kodi.set_setting('trakt_oauth_token', '')
                                kodi.set_setting('trakt_refresh_token', '')
                                raise TraktError('Trakt Call Authentication Failed (%s)' % (e.code))
                            else:
                                result = self.get_token()
                                self.token = result['access_token']
                                kodi.set_setting('trakt_oauth_token', result['access_token'])
                                kodi.set_setting('trakt_refresh_token', result['refresh_token'])
                                auth_retry = True
                        elif e.code == 404:
                            raise TraktNotFoundError()
                        else:
                            raise
                    elif isinstance(e.reason, socket.timeout) or isinstance(e.reason, ssl.SSLError):
                        if cached_result:
                            result = cached_result
                            log_utils.log('Temporary Trakt Error (%s). Using Cached Page Instead' % (str(e)), log_utils.LOGWARNING)
                            break
                        else:
                            raise TransientTraktError('Temporary Trakt Error: ' + str(e))
                    else:
                        raise TraktError('Trakt Error: ' + str(e))
                except:
                    raise

        response = json.loads(result)

        if 'status' in response and response['status'] == 'failure':
            if 'message' in response: raise TraktError(response['message'])
            if 'error' in response: raise TraktError(response['error'])
            else: raise TraktError()
        else:
            # log_utils.log('Trakt Response: %s' % (response), xbmc.LOGDEBUG)
            return response
Beispiel #14
0
"""
import json
import xbmc
import xbmcgui
import xbmcaddon
import utils
from utils import MODES
from db_utils import DB_Connection

ADDON = xbmcaddon.Addon(id='plugin.video.1channel')
utils.log('Service: Installed Version: %s' % (ADDON.getAddonInfo('version')))

LASTPLAYEDFILE =  xbmc.translatePath(xbmcaddon.Addon().getAddonInfo('profile')).decode('utf-8') + 'lastplayed.txt'
TMPLASTPLAY =  xbmc.translatePath(xbmcaddon.Addon().getAddonInfo('profile')).decode('utf-8') + 'lastplayedtmp.txt'

db_connection = DB_Connection()
db_connection.init_database()

class Service(xbmc.Player):
    def __init__(self, *args, **kwargs):
        xbmc.Player.__init__(self, *args, **kwargs)
        self.reset()

        self.last_run = 0
        self.DB = ''
        utils.log('Service: starting...')

    def reset(self):
        utils.log('Service: Resetting...')
        win = xbmcgui.Window(10000)
        win.clearProperty('1ch.playing.title')
Beispiel #15
0
class SRT_Scraper():
    def __init__(self):
        self.db_connection = DB_Connection()

    def get_tvshow_id(self, title, year=None):
        match_title = title.lower()
        rows = self.db_connection.get_related_url(VIDEO_TYPES.TVSHOW, title,
                                                  year, SRT_SOURCE)
        if rows:
            tvshow_id = rows[0][0]
            logger.log(
                'Returning local tvshow id: |%s|%s|%s|' %
                (title, year, tvshow_id), log_utils.LOGDEBUG)
            return tvshow_id

        html = self.__get_cached_url(BASE_URL, 24)
        regex = re.compile('option\s+value="(\d+)"\s*>(.*?)</option')
        site_matches = []
        for item in regex.finditer(html):
            tvshow_id, site_title = item.groups()

            # strip year off title and assign it to year if it exists
            r = re.search('(\s*\((\d{4})\))$', site_title)
            if r:
                site_title = site_title.replace(r.group(1), '')
                site_year = r.group(2)
            else:
                site_year = None

            # print 'show: |%s|%s|%s|' % (tvshow_id, site_title, site_year)
            if match_title == site_title.lower():
                if year is None or year == site_year:
                    self.db_connection.set_related_url(VIDEO_TYPES.TVSHOW,
                                                       title, year, SRT_SOURCE,
                                                       tvshow_id)
                    return tvshow_id

                site_matches.append((tvshow_id, site_title, site_year))

        if not site_matches:
            return None
        elif len(site_matches) == 1:
            self.db_connection.set_related_url(VIDEO_TYPES.TVSHOW, title, year,
                                               SRT_SOURCE, site_matches[0][0])
            return site_matches[0][0]
        else:
            # there were multiple title matches and year was passed but no exact year matches found
            for match in site_matches:
                # return the match that has no year specified
                if match[2] is None:
                    self.db_connection.set_related_url(VIDEO_TYPES.TVSHOW,
                                                       title, year, SRT_SOURCE,
                                                       match[0])
                    return match[0]

    def get_season_subtitles(self, language, tvshow_id, season):
        url = BASE_URL + '/ajax_loadShow.php?show=%s&season=%s&langs=&hd=%s&hi=%s' % (
            tvshow_id, season, 0, 0)
        html = self.__get_cached_url(url, .25)
        # print html.decode('ascii', 'ignore')
        req_hi = kodi.get_setting('subtitle-hi') == 'true'
        req_hd = kodi.get_setting('subtitle-hd') == 'true'
        items = []
        regex = re.compile(
            '<td>(\d+)</td><td>(\d+)</td><td>.*?</td><td>(.*?)</td><td.*?>(.*?)</td>.*?<td.*?>(.+?)</td><td.*?>(.*?)</td><td.*?>(.*?)</td><td.*?>(.*?)</td><td.*?><a\s+href="(.*?)">.+?</td>',
            re.DOTALL)
        for match in regex.finditer(html):
            season, episode, srt_lang, version, completed, hi, corrected, hd, srt_url = match.groups(
            )
            if not language or language == srt_lang and (
                    not req_hi or hi) and (not req_hd or hd):
                item = {}
                item['season'] = season
                item['episode'] = episode
                item['language'] = srt_lang
                item['version'] = version

                if completed.lower() == 'completed':
                    item['completed'] = True
                    item['percent'] = '100'
                else:
                    item['completed'] = False
                    r = re.search('([\d.]+)%', completed)
                    if r:
                        item['percent'] = r.group(1)
                    else:
                        item['percent'] = '0'

                item['hi'] = True if hi else False
                item['corrected'] = True if corrected else False
                item['hd'] = True if hd else False
                item['url'] = srt_url
                items.append(item)
        return items

    def get_episode_subtitles(self, language, tvshow_id, season, episode):
        subtitles = self.get_season_subtitles(language, tvshow_id, season)
        items = []
        for subtitle in subtitles:
            if subtitle['episode'] == str(episode):
                items.append(subtitle)

        return items

    def download_subtitle(self, url):
        url = BASE_URL + url
        (response, srt) = self.__get_url(url)
        if not hasattr(response,
                       'info') or 'Content-Disposition' not in response.info():
            return

        cd = response.info()['Content-Disposition']
        r = re.search('filename="(.*)"', cd)
        if r:
            filename = r.group(1)
        else:
            filename = 'addic7ed_subtitle.srt'
        filename = re.sub('[^\x00-\x7F]', '', filename)
        filename = re.sub('[<>:"/\\|?*]', '_', filename)
        filename = re.sub('_+', '_', filename)

        final_path = os.path.join(kodi.get_setting('subtitle-folder'),
                                  filename)
        final_path = kodi.translate_path(final_path)
        if not xbmcvfs.exists(os.path.dirname(final_path)):
            try:
                try:
                    xbmcvfs.mkdirs(os.path.dirname(final_path))
                except:
                    os.makedirs(os.path.dirname(final_path))
            except:
                logger.log(
                    'Failed to create directory %s' %
                    os.path.dirname(final_path), log_utils.LOGERROR)
                raise

        with open(final_path, 'w') as f:
            f.write(srt)
        return final_path

    def __get_url(self, url):
        try:
            req = urllib2.Request(url)
            host = BASE_URL.replace('http://', '')
            req.add_header('User-Agent', USER_AGENT)
            req.add_header('Host', host)
            req.add_header('Referer', BASE_URL)
            response = urllib2.urlopen(req, timeout=10)
            body = response.read()
            body = utils2.cleanse_title(body)
            body = body.encode('utf-8')
        except Exception as e:
            kodi.notify(msg='Failed to connect to URL: %s' % (url),
                        duration=5000)
            logger.log('Failed to connect to URL %s: (%s)' % (url, e),
                       log_utils.LOGERROR)
            return ('', '')

        return (response, body)

    def __get_cached_url(self, url, cache=8):
        logger.log('Fetching Cached URL: %s' % url, log_utils.LOGDEBUG)
        before = time.time()

        _created, _res_header, html = self.db_connection.get_cached_url(
            url, cache_limit=cache)
        if html:
            logger.log('Returning cached result for: %s' % (url),
                       log_utils.LOGDEBUG)
            return html.decode('utf-8')

        logger.log('No cached url found for: %s' % url, log_utils.LOGDEBUG)
        req = urllib2.Request(url)

        host = BASE_URL.replace('http://', '')
        req.add_header('User-Agent', USER_AGENT)
        req.add_header('Host', host)
        req.add_header('Referer', BASE_URL)
        try:
            response = urllib2.urlopen(req, timeout=10)
            html = response.read()
            html = utils2.cleanse_title(html)
        except Exception as e:
            kodi.notify(msg='Failed to connect to URL: %s' % (url),
                        duration=5000)
            logger.log('Failed to connect to URL %s: (%s)' % (url, e),
                       log_utils.LOGERROR)
            return ''

        self.db_connection.cache_url(url, html)
        after = time.time()
        logger.log('Cached Url Fetch took: %.2f secs' % (after - before),
                   log_utils.LOGDEBUG)
        return html
Beispiel #16
0
 def __init__(self):
     self.db_connection = DB_Connection()
Beispiel #17
0
def _get_db_connection():
    global _db_connection
    if _db_connection is None:
        _db_connection = DB_Connection()
    return _db_connection