def _add_account(self):
        request_params = {
            'waiting_retry':
            lambda request, remaining: self._progress_dialog_bg.
            update(int((request.current_delay - remaining) / request.
                       current_delay * 100),
                   heading=self._common_addon.getLocalizedString(32043) %
                   ('' if request.current_tries == 1 else ' again'),
                   message=self._common_addon.getLocalizedString(32044) % str(
                       int(remaining)
                   ) + ' ' + self._common_addon.getLocalizedString(32045) %
                   (str(request.current_tries + 1), str(request.tries))),
            'on_complete':
            lambda request:
            (self._progress_dialog.close(), self._progress_dialog_bg.close()),
            'cancel_operation':
            self.cancel_operation,
            'wait':
            self._system_monitor.waitForAbort
        }
        provider = self.get_provider()
        self._progress_dialog.update(
            0, self._common_addon.getLocalizedString(32008))

        self._ip_before_pin = Request(KodiUtils.get_signin_server() + '/ip',
                                      None).request()
        pin_info = provider.create_pin(request_params)
        self._progress_dialog.close()
        if self.cancel_operation():
            return
        if not pin_info:
            raise Exception('Unable to retrieve a pin code')

        tokens_info = {}
        request_params[
            'on_complete'] = lambda request: self._progress_dialog_bg.close()
        self._pin_dialog = QRDialogProgress.create(
            self._addon_name,
            KodiUtils.get_signin_server() + '/signin/%s' % pin_info['pin'],
            self._common_addon.getLocalizedString(32009),
            self._common_addon.getLocalizedString(32010) %
            ('[B]%s[/B]' % KodiUtils.get_signin_server(),
             '[B][COLOR lime]%s[/COLOR][/B]' % pin_info['pin']))
        self._pin_dialog.show()
        max_waiting_time = time.time() + self._DEFAULT_SIGNIN_TIMEOUT
        while not self.cancel_operation() and max_waiting_time > time.time():
            remaining = round(max_waiting_time - time.time())
            percent = int(remaining / self._DEFAULT_SIGNIN_TIMEOUT * 100)
            self._pin_dialog.update(
                percent,
                line3='[CR]' + self._common_addon.getLocalizedString(32011) %
                str(int(remaining)) + '[CR][CR]Your source id is: %s' %
                Utils.get_source_id(self._ip_before_pin))
            if int(remaining) % 5 == 0 or remaining == 1:
                tokens_info = provider.fetch_tokens_info(
                    pin_info, request_params=request_params)
                if self.cancel_operation() or tokens_info:
                    break
            if self._system_monitor.waitForAbort(1):
                break
        self._pin_dialog.close()

        if self.cancel_operation() or time.time() >= max_waiting_time:
            return
        if not tokens_info:
            raise Exception('Unable to retrieve the auth2 tokens')

        self._progress_dialog.update(
            25, self._common_addon.getLocalizedString(32064), ' ', ' ')
        try:
            account = provider.get_account(request_params=request_params,
                                           access_tokens=tokens_info)
        except Exception as e:
            raise UIException(32065, e)
        if self.cancel_operation():
            return

        self._progress_dialog.update(
            50, self._common_addon.getLocalizedString(32017))
        try:
            account['drives'] = provider.get_drives(
                request_params=request_params, access_tokens=tokens_info)
        except Exception as e:
            raise UIException(32018, e)
        if self.cancel_operation():
            return

        self._progress_dialog.update(
            75, self._common_addon.getLocalizedString(32020))
        try:
            account['access_tokens'] = tokens_info
            self._account_manager.save_account(account)
        except Exception as e:
            raise UIException(32021, e)
        if self.cancel_operation():
            return

        self._progress_dialog.update(90)
        try:
            accounts = self._account_manager.get_accounts()
            for drive in account['drives']:
                driveid = drive['id']
                Logger.debug('Looking for account %s...' % driveid)
                if driveid in accounts:
                    drive = accounts[driveid]['drives'][0]
                    Logger.debug(drive)
                    if drive['id'] == driveid and drive['type'] == 'migrated':
                        Logger.debug('Account %s removed.' % driveid)
                        self._account_manager.remove_account(driveid)

        except Exception as e:
            pass
        if self.cancel_operation():
            return

        self._progress_dialog.close()
        KodiUtils.executebuiltin('Container.Refresh')
    def _process_items(self, items, driveid):
        listing = []
        for item in items:
            Logger.debug(item)
            item_id = item['id']
            item_name = Utils.unicode(item['name'])
            item_name_extension = item['name_extension']
            item_driveid = Utils.default(
                Utils.get_safe_value(item, 'drive_id'), driveid)
            list_item = xbmcgui.ListItem(item_name)
            url = None
            is_folder = 'folder' in item
            params = {
                'content_type': self._content_type,
                'item_driveid': item_driveid,
                'item_id': item_id,
                'driveid': driveid
            }
            if 'extra_params' in item:
                params.update(item['extra_params'])
            context_options = []
            info = {
                'size':
                item['size'],
                'date':
                KodiUtils.to_kodi_item_date_str(
                    KodiUtils.to_datetime(
                        Utils.get_safe_value(item, 'last_modified_date')))
            }
            if is_folder:
                params['action'] = '_list_folder'
                url = self._addon_url + '?' + urllib.urlencode(params)
                params['action'] = '_search'
                cmd = 'ActivateWindow(%d,%s?%s)' % (xbmcgui.getCurrentWindowId(
                ), self._addon_url, urllib.urlencode(params))
                context_options.append(
                    (self._common_addon.getLocalizedString(32039), cmd))
                if self._content_type == 'audio' or self._content_type == 'video':
                    params['action'] = '_open_export'
                    params['name'] = urllib.quote(Utils.str(item_name))
                    context_options.append(
                        (self._common_addon.getLocalizedString(32004),
                         'RunPlugin(' + self._addon_url + '?' +
                         urllib.urlencode(params) + ')'))
                    del params['name']
                elif self._content_type == 'image' and self._auto_refreshed_slideshow_supported:
                    params['action'] = '_slideshow'
                    context_options.append(
                        (self._common_addon.getLocalizedString(32032),
                         'RunPlugin(' + self._addon_url + '?' +
                         urllib.urlencode(params) + ')'))
            elif (('video' in item or
                   (item_name_extension
                    and item_name_extension in self._video_file_extensions))
                  and self._content_type == 'video') or (
                      ('audio' in item or
                       (item_name_extension and item_name_extension
                        in self._audio_file_extensions))
                      and self._content_type == 'audio'):
                list_item.setProperty('IsPlayable', 'true')
                params['action'] = 'download'
                cmd = 'RunPlugin(' + self._addon_url + '?' + urllib.urlencode(
                    params) + ')'
                context_options.append(
                    (self._common_addon.getLocalizedString(32051), cmd))
                params['action'] = 'play'
                url = self._addon_url + '?' + urllib.urlencode(params)
                info_type = self._content_type
                if 'audio' in item:
                    info.update(item['audio'])
                    info_type = 'music'
                elif 'video' in item:
                    list_item.addStreamInfo('video', item['video'])
                list_item.setInfo(info_type, info)
                if 'thumbnail' in item:
                    list_item.setArt({
                        'icon': item['thumbnail'],
                        'thumb': item['thumbnail']
                    })
            elif ('image' in item or
                  (item_name_extension
                   and item_name_extension in self._image_file_extensions)
                  ) and self._content_type == 'image':
                Logger.debug(
                    'image in item: %s' % (Utils.str('image' in item)), )
                Logger.debug(
                    'item_name_extension in self._image_file_extensions: %s' %
                    (Utils.str(
                        item_name_extension in self._image_file_extensions), ))
                params['action'] = 'download'
                cmd = 'RunPlugin(' + self._addon_url + '?' + urllib.urlencode(
                    params) + ')'
                context_options.append(
                    (self._common_addon.getLocalizedString(32051), cmd))
                if 'url' in item:
                    url = item['url']
                else:
                    url = self._get_item_play_url(
                        urllib.quote(Utils.str(item_name)), driveid,
                        item_driveid, item_id)
                if 'image' in item:
                    info.update(item['image'])
                list_item.setInfo('pictures', info)
                if 'thumbnail' in item and item['thumbnail']:
                    list_item.setArt({
                        'icon': item['thumbnail'],
                        'thumb': item['thumbnail']
                    })
            if url:
                context_options.extend(
                    self.get_context_options(list_item, params, is_folder))
                list_item.addContextMenuItems(context_options)
                mimetype = Utils.default(
                    Utils.get_mimetype_by_extension(item_name_extension),
                    Utils.get_safe_value(item, 'mimetype'))
                if mimetype:
                    list_item.setProperty('mimetype', mimetype)

                listing.append((url, list_item, is_folder))
        xbmcplugin.addDirectoryItems(self._addon_handle, listing, len(listing))
        xbmcplugin.endOfDirectory(self._addon_handle, True)
 def timed(*args, **kw):
     ts = timer()
     result = method(*args, **kw)
     te = timer()
     Logger.debug('%r: %2.2f ms' % (method.__name__, (te - ts) * 1000))
     return result    
Example #4
0
 def process_change(self, change, items_info, export):
     change_type = None
     changed_item_id = change['id']
     Logger.debug('Change: %s' % Utils.str(change))
     if changed_item_id != export['id']:
         changed_item_name = Utils.get_safe_value(change, 'name', '')
         deleted = Utils.get_safe_value(change, 'removed')
         parent_id = Utils.get_safe_value(change, 'parent', '')
         if changed_item_id in items_info:
             item_info = items_info[changed_item_id]
             item_type = item_info['type']
             is_folder = item_type == 'folder'
             Logger.debug('item_info: %s' % Utils.str(item_info))
             item_info_path = item_info['full_local_path']
             if KodiUtils.file_exists(item_info_path):
                 if deleted:
                     change_type = self.process_change_delete(
                         items_info, changed_item_id, is_folder)
                 elif parent_id != item_info[
                         'parent'] or changed_item_name != item_info['name']:
                     if parent_id in items_info:
                         change_type = 'move'
                         Logger.debug('Change is move')
                         parent_item_info = items_info[parent_id]
                         parent_item_path = parent_item_info[
                             'full_local_path']
                         new_path = os.path.join(
                             parent_item_path,
                             Utils.unicode(changed_item_name))
                         if is_folder:
                             new_path = os.path.join(new_path, '')
                         if KodiUtils.file_rename(item_info_path, new_path):
                             ExportManager.remove_item_info(
                                 items_info, changed_item_id)
                             ExportManager.add_item_info(
                                 items_info, changed_item_id,
                                 Utils.unicode(changed_item_name), new_path,
                                 parent_id, item_type)
                         else:
                             change_type = 'retry'
                     else:
                         Logger.debug(
                             'Change is move but parent not in item list. Change is delete'
                         )
                         change_type = self.process_change_delete(
                             items_info, changed_item_id, is_folder)
             else:
                 Logger.debug(
                     'Invalid state. Changed item not found: %s. Deleting from item list.'
                     % item_info_path)
                 change_type = self.process_change_delete(
                     items_info, changed_item_id, is_folder)
         elif parent_id in items_info and not deleted:
             is_folder = 'application/vnd.google-apps.folder' in change.get(
                 'mimetype')
             content_type = export['content_type']
             item_name_extension = change['name_extension']
             is_stream_file = (
                 ('video' in change
                  or item_name_extension in self._video_file_extensions)
                 and content_type == 'video') or ('audio' in change and
                                                  content_type == 'audio')
             item_type = 'folder' if is_folder else 'file'
             if is_folder or is_stream_file or (
                     'nfo_export' in export and export['nfo_export'] and
                 ('nfo' in item_name_extension
                  or 'text/x-nfo' in change.get("mimetype"))):
                 change_type = 'add'
                 Logger.debug('Change is new item')
                 parent_item_info = items_info[parent_id]
                 parent_item_path = parent_item_info['full_local_path']
                 new_path = os.path.join(parent_item_path,
                                         Utils.unicode(changed_item_name))
                 if is_folder:
                     new_path = os.path.join(new_path, '')
                     if not KodiUtils.mkdirs(new_path):
                         change_type = 'retry'
                 elif is_stream_file:
                     new_path += '.strm'
                     ExportManager.create_strm(
                         export['driveid'], change, new_path, content_type,
                         'plugin://%s/' % self.addonid)
                 else:
                     ExportManager.create_nfo(changed_item_id,
                                              export['item_driveid'],
                                              new_path, self.provider)
                 if change_type != 'retry':
                     ExportManager.add_item_info(
                         items_info, changed_item_id,
                         Utils.unicode(changed_item_name), new_path,
                         parent_id, item_type)
     Logger.debug('change type: %s ' % Utils.str(change_type))
     return change_type
 def process_change_create(self, change, items_info, export):
     content_type = export['content_type']
     changed_item_id = change['id']
     changed_item_name = Utils.get_safe_value(change, 'name', '')
     changed_item_extension = Utils.get_safe_value(change, 'name_extension',
                                                   '')
     parent_id = Utils.get_safe_value(change, 'parent', '')
     is_folder = 'folder' in change
     item_type = 'folder' if is_folder else 'file'
     parent_item_info = Utils.get_safe_value(items_info, parent_id)
     if parent_item_info:
         parent_item_path = parent_item_info['full_local_path']
         new_path = os.path.join(parent_item_path,
                                 Utils.unicode(changed_item_name))
         change_type = 'create'
         if is_folder:
             change_type += '_folder'
             new_path = os.path.join(new_path, '')
             if parent_id == 'root-folder' and KodiUtils.get_addon_setting(
                     'clean_folder') == 'true' and KodiUtils.file_exists(
                         new_path):
                 if not Utils.remove_folder(new_path):
                     error = self._common_addon.getLocalizedString(
                         32066) % new_path
                     KodiUtils.show_notification(error)
                     Logger.debug(error)
             if not KodiUtils.file_exists(new_path):
                 Logger.debug('creating folder: %s' % (new_path, ))
                 if not KodiUtils.mkdirs(new_path):
                     change_type += '_retry'
                     Logger.debug('unable to create folder %s' %
                                  (new_path, ))
             else:
                 change_type += '_ignored'
                 Logger.debug('folder %s already exists' % (new_path, ))
         else:
             download_artwork = 'download_artwork' in export and export[
                 'download_artwork']
             is_download = changed_item_extension \
                           and (
                               changed_item_extension in ['strm', 'nomedia']
                               or (
                                   download_artwork
                                   and (
                                       changed_item_extension in ['nfo']
                                       or (
                                           changed_item_extension in ['jpg', 'png']
                                           and (
                                               any(s in changed_item_name for s in self._artwork_file_extensions)
                                               or parent_item_info['name'] in ['.actors', 'extrafanart']
                                           )
                                       )
                                   )
                               )
                           )
             if is_download:
                 Logger.debug('downloading file: %s' % (new_path, ))
                 change_type = 'download_file'
                 cloud_size = Utils.get_safe_value(change, 'size', 0)
                 local_size = KodiUtils.file(new_path).size()
                 if cloud_size != local_size:
                     Logger.debug(
                         'Download requested. File changed: Local file size (%s) - cloud file size (%s)'
                         % (
                             Utils.str(local_size),
                             Utils.str(cloud_size),
                         ))
                     if not ExportManager.download(change, new_path,
                                                   self.provider):
                         change_type += "_retry"
                         Logger.debug('Unable to download file: %s' %
                                      (new_path, ))
                 else:
                     change_type += '_ignored'
                     Logger.debug(
                         'Download ignored: Local file size (%s) is equal to cloud file size (%s)'
                         % (
                             Utils.str(local_size),
                             Utils.str(cloud_size),
                         ))
             else:
                 is_stream_file = (('video' in change or (changed_item_extension and changed_item_extension in self._video_file_extensions)) and content_type == 'video') \
                                  or (('audio' in change or (changed_item_extension and changed_item_extension in self._audio_file_extensions)) and content_type == 'audio')
                 if is_stream_file:
                     change_type += '_file'
                     if KodiUtils.get_addon_setting(
                             'no_extension_strm') == 'true':
                         new_path = Utils.remove_extension(new_path)
                     new_path += ExportManager._strm_extension
                     strm_content = ExportManager.get_strm_link(
                         export['driveid'], change, content_type,
                         'plugin://%s/' % self.addonid)
                     Logger.debug('creating strm file: %s' % (new_path, ))
                     if not KodiUtils.file_exists(
                             new_path) or KodiUtils.file(
                                 new_path).size() != len(strm_content):
                         if not ExportManager.create_text_file(
                                 new_path, strm_content):
                             change_type += '_retry'
                     else:
                         change_type += '_ignored'
                         Logger.debug(
                             'ignoring strm creation: %s, strm file already exists. same expected size.'
                             % (new_path, ))
                 else:
                     change_type = None
                     Logger.debug('ignoring file: %s' % (new_path, ))
         if change_type:
             ExportManager.add_item_info(items_info, changed_item_id,
                                         Utils.unicode(changed_item_name),
                                         new_path, parent_id, item_type)
     else:
         Logger.debug('invalid state. no parent info found')
         change_type = None
     return change_type
 def _print_slideshow_info(self):
     if xbmc.getCondVisibility('Slideshow.IsActive'):
         Logger.debug('Slideshow is there...')
     elif self.cancel_operation():
         Logger.debug('Abort requested...')
 def process_change(self, change, items_info, export):
     change_type = None
     changed_item_id = change['id']
     Logger.debug('Change: %s' % Utils.str(change))
     if changed_item_id != export['id']:
         changed_item_name = change['name']
         deleted = Utils.get_safe_value(change, 'deleted')
         parent_id = change['parent']
         is_folder = 'folder' in change
         if not is_folder:
             changed_item_name += ExportManager._strm_extension
         if changed_item_id in items_info:
             item_info = items_info[changed_item_id]
             Logger.debug('item_info: %s' % Utils.str(item_info))
             item_info_path = item_info['full_local_path']
             if KodiUtils.file_exists(item_info_path):
                 if deleted:
                     change_type = self.process_change_delete(items_info, changed_item_id, is_folder)
                 elif parent_id != item_info['parent'] or changed_item_name != item_info['name']:
                     if parent_id in items_info:
                         change_type = 'move'
                         Logger.debug('Change is move')
                         parent_item_info = items_info[parent_id]
                         parent_item_path = parent_item_info['full_local_path']
                         new_path = os.path.join(parent_item_path, changed_item_name)
                         if is_folder:
                             new_path = os.path.join(new_path, '')
                         if KodiUtils.file_rename(item_info_path, new_path):
                             ExportManager.remove_item_info(items_info, changed_item_id)
                             ExportManager.add_item_info(items_info, changed_item_id, changed_item_name, new_path, parent_id)
                         else:
                             change_type = 'retry'
                     else:
                         Logger.debug('Change is move but parent not in item list. Change is delete')
                         change_type = self.process_change_delete(items_info, changed_item_id, is_folder)
             else:
                 Logger.debug('Invalid state. Changed item not found: %s. Deleting from item list.' % item_info_path)
                 change_type = self.process_change_delete(items_info, changed_item_id, is_folder)
         elif parent_id in items_info and not deleted:
             content_type = export['content_type']
             item_name_extension = change['name_extension']
             if is_folder or (('video' in change or item_name_extension in self._video_file_extensions) and content_type == 'video') or ('audio' in change and content_type == 'audio'):
                 change_type = 'add'
                 Logger.debug('Change is new item')
                 parent_item_info = items_info[parent_id]
                 parent_item_path = parent_item_info['full_local_path']
                 new_path = os.path.join(parent_item_path, changed_item_name)
                 if is_folder:
                     new_path = os.path.join(new_path, '')
                     if not KodiUtils.mkdirs(new_path):
                         change_type = 'retry'
                 else:
                     ExportManager.create_strm(export['driveid'], change, new_path, content_type, 'plugin://%s/' % self.addonid)
                 if change_type != 'retry':
                     ExportManager.add_item_info(items_info, changed_item_id, changed_item_name, new_path, parent_id)
     Logger.debug('change type: %s ' % Utils.str(change_type))
     return change_type
Example #8
0
 def clear(self):
     self._execute_sql("delete from cache")
     Logger.debug("Cache '%s' cleared" % self._name)
     self.checkpoint()
Example #9
0
    def request(self):
        self.response_text = self._DEFAULT_RESPONSE
        if not self.exceptions:
            self.exceptions = Exception
        if not self.wait:
            self.wait = time.sleep
        if not self.headers:
            self.headers = {}

        for i in xrange(self.tries):
            self.current_tries = i + 1
            if self.before_request:
                self.before_request(self)
            if self.cancel_operation and self.cancel_operation():
                break
            request_report = 'Request URL: ' + self.get_url_for_report(
                self.url)
            request_report += '\nRequest data: ' + Utils.str(self.data)
            request_report += '\nRequest headers: ' + Utils.str(
                self.get_headers_for_report(self.headers))
            response_report = '<response_not_set>'
            response = None
            try:
                Logger.debug(request_report)
                req = urllib2.Request(self.url, self.data, self.headers)
                response = urllib2.urlopen(req)
                self.response_code = response.getcode()
                self.response_info = response.info()
                self.response_url = response.geturl()
                cookiejar = CookieJar()
                cookiejar._policy._now = cookiejar._now = int(time.time())
                self.response_cookies = cookiejar.make_cookies(response, req)
                if self.read_content:
                    self.response_text = response.read()
                content_length = self.response_info.getheader(
                    'content-length', -1)
                response_report = '\nResponse Headers:\n%s' % Utils.str(
                    self.response_info)
                response_report += '\nResponse (%d) content-length=%s, len=<%s>:\n%s' % (
                    self.response_code, content_length, len(
                        self.response_text), self.response_text)
                self.success = True
                break
            except self.exceptions as e:
                root_exception = e
                response_report = '\nResponse <Exception>: '
                if isinstance(e, urllib2.HTTPError):
                    self.response_text = Utils.str(e.read())
                    response_report += self.response_text
                else:
                    response_report += Utils.str(e)
                rex = RequestException(Utils.str(e), root_exception,
                                       request_report, response_report)
                if self.on_exception:
                    self.on_exception(self, rex)
                if self.cancel_operation and self.cancel_operation():
                    break
                if self.current_tries == self.tries:
                    if self.on_failure:
                        self.on_failure(self)
                    if self.on_complete:
                        self.on_complete(self)
                    Logger.debug('Raising exception...')
                    raise rex
                current_time = time.time()
                max_waiting_time = current_time + self.current_delay
                while (not self.cancel_operation
                       or not self.cancel_operation()
                       ) and max_waiting_time > current_time:
                    remaining = round(max_waiting_time - current_time)
                    if self.waiting_retry:
                        self.waiting_retry(self, remaining)
                    self.wait(1)
                    current_time = time.time()
                self.current_delay *= self.backoff
            finally:
                Logger.debug(response_report)
                if response:
                    response.close()
        if self.success and self.on_success:
            self.on_success(self)
        if self.on_complete:
            self.on_complete(self)
        return self.response_text
 def __del__(self):
     del self._system_monitor
     del self._account_manager
     Logger.debug('Request destroyed.')
    def do_GET(self):
        Logger.debug(self.path + ': Requested')
        if self._system_monitor.abortRequested():
            Logger.debug(self.path + ': abort requested')
            return
        data = self.path.split('/')
        size = len(data)
        cached_page = self._page_cache.get(self.path)
        if cached_page:
            if cached_page['pending']:
                Logger.debug(self.path + ': Already requested. Waiting for original request...')
                max_waiting_time = time.time() + 30
                while not self._system_monitor.abortRequested() and max_waiting_time > time.time() and cached_page['pending']:
                    if self._system_monitor.waitForAbort(1):
                        break
                    cached_page = self._page_cache.get(self.path)

            if not self._system_monitor.abortRequested():
                if cached_page['pending']:
                    self.write_response(504)
                    Logger.debug(self.path + ': 504 - Gateway timeout')
                    self._page_cache.remove(self.path)
                else:
                    if 'content' in cached_page and cached_page['content']:
                        content = Utils.get_file_buffer()
                        content.write(cached_page['content'])
                        cached_page['content'] = content
                    self.write_response(cached_page['response_code'], content=Utils.get_safe_value(cached_page, 'content'), headers=Utils.get_safe_value(cached_page, 'headers', {}))
                    Logger.debug(self.path + ': %d - Served from cache' % cached_page['response_code'])
        else:
            cached_page = {'pending': True}
            self._page_cache.set(self.path, cached_page)
            if size > 1 and data[1] == self.server.service.name:
                try:
                    if size == 2:
                        cached_page['response_code'] = 303
                        cached_page['headers'] = {'location': self.path + '/'}
                    elif size > 2 and data[2]:
                        cached_page = self.handle_resource_request(data)
                    else:
                        cached_page = self.show_addon_list()
                except Exception as e:
                    httpex = ExceptionUtils.extract_exception(e, HTTPError)
                    if httpex:
                        cached_page['response_code'] = httpex.code
                    else:
                        cached_page['response_code'] = 500
                    
                    ErrorReport.handle_exception(e)
                    content = Utils.get_file_buffer()
                    content.write(ExceptionUtils.full_stacktrace(e))
                    
                    cached_page['content'] = content
            else:
                cached_page['response_code'] = 404
            cached_page['pending'] = False
            content_value = None
            if 'content' in cached_page:
                content_value = cached_page['content'].getvalue()
            self.write_response(cached_page['response_code'], content=Utils.get_safe_value(cached_page, 'content'), headers=Utils.get_safe_value(cached_page, 'headers', {}))
            cached_page['content'] = content_value
            if Utils.get_safe_value(cached_page, 'response_code', 0) >= 500:
                self._page_cache.remove(self.path)
            else:
                self._page_cache.set(self.path, cached_page)
            Logger.debug(self.path + ': Response code ' + Utils.str(cached_page['response_code']))
 def play(self, driveid, item_driveid=None, item_id=None):
     self.get_provider().configure(self._account_manager, driveid)
     find_subtitles = self._addon.getSetting(
         'set_subtitle') == 'true' and self._content_type == 'video'
     item = self.get_provider().get_item(item_driveid,
                                         item_id,
                                         find_subtitles=find_subtitles)
     file_name = Utils.unicode(item['name'])
     list_item = xbmcgui.ListItem(file_name)
     succeeded = True
     info = KodiUtils.get_current_library_info()
     if not info:
         info = KodiUtils.find_exported_video_in_library(
             item_id, file_name + ExportManager._strm_extension)
     if info and info['id']:
         Logger.debug('library info: %s' % Utils.str(info))
         KodiUtils.set_home_property('dbid', Utils.str(info['id']))
         KodiUtils.set_home_property('dbtype', info['type'])
         KodiUtils.set_home_property('addonid', self._addonid)
         details = KodiUtils.get_video_details(info['type'], info['id'])
         Logger.debug('library details: %s' % Utils.str(details))
         if details and 'resume' in details:
             KodiUtils.set_home_property('playcount',
                                         Utils.str(details['playcount']))
             resume = details['resume']
             if resume['position'] > 0:
                 play_resume = False
                 if self.iskrypton:
                     play_resume = KodiUtils.get_addon_setting(
                         'resume_playing') == 'true'
                 elif KodiUtils.get_addon_setting('ask_resume') == 'true':
                     d = datetime(1, 1,
                                  1) + timedelta(seconds=resume['position'])
                     t = '%02d:%02d:%02d' % (d.hour, d.minute, d.second)
                     Logger.debug(t)
                     option = self._dialog.contextmenu([
                         KodiUtils.localize(32054, addon=self._common_addon)
                         % t,
                         KodiUtils.localize(12021)
                     ])
                     Logger.debug('selected option: %d' % option)
                     if option == -1:
                         succeeded = False
                     elif option == 0:
                         play_resume = True
                 if play_resume:
                     list_item.setProperty('resumetime',
                                           Utils.str(resume['position']))
                     list_item.setProperty('startoffset',
                                           Utils.str(resume['position']))
                     list_item.setProperty('totaltime',
                                           Utils.str(resume['total']))
     else:
         from clouddrive.common.service.player import KodiPlayer
         KodiPlayer.cleanup()
     if 'audio' in item:
         list_item.setInfo('music', item['audio'])
     elif 'video' in item:
         list_item.addStreamInfo('video', item['video'])
     list_item.select(True)
     list_item.setPath(
         self._get_item_play_url(file_name, driveid, item_driveid, item_id))
     list_item.setProperty('mimetype',
                           Utils.get_safe_value(item, 'mimetype'))
     if find_subtitles and 'subtitles' in item:
         subtitles = []
         for subtitle in item['subtitles']:
             subtitles.append(
                 self._get_item_play_url(
                     urllib.quote(Utils.str(subtitle['name'])), driveid,
                     Utils.default(
                         Utils.get_safe_value(subtitle, 'drive_id'),
                         driveid), subtitle['id'], True))
         list_item.setSubtitles(subtitles)
     if not self.cancel_operation():
         xbmcplugin.setResolvedUrl(self._addon_handle, succeeded, list_item)
Example #13
0
    def request(self):
        self.response_text = self._DEFAULT_RESPONSE
        if not self.exceptions:
            self.exceptions = Exception
        if not self.wait:
            self.wait = time.sleep
        if not self.headers:
            self.headers = {}

        for i in range(self.tries):
            self.current_tries = i + 1
            if self.before_request:
                self.before_request(self)
            if self.cancel_operation and self.cancel_operation():
                break
            request_report = 'Request URL: ' + self.get_url_for_report(
                self.url)
            request_report += '\nRequest data: ' + Utils.str(self.data)
            request_report += '\nRequest headers: ' + Utils.str(
                self.get_headers_for_report(self.headers))
            response_report = '<response_not_set>'
            response = None
            rex = None
            download_file = None
            try:
                Logger.debug(request_report)
                req = urllib.request.Request(self.url, self.data, self.headers)
                response = urllib.request.urlopen(req)
                self.response_code = response.getcode()
                self.response_info = response.info()
                self.response_url = response.geturl()
                cookiejar = CookieJar()
                cookiejar._policy._now = cookiejar._now = int(time.time())
                self.response_cookies = cookiejar.make_cookies(response, req)
                if self.read_content:
                    if self.download_path:
                        self.response_text = 'Downloading to: ' + self.download_path + '... '
                        download_file = KodiUtils.file(self.download_path,
                                                       'wb')
                        self.download_progress = 0
                        while True:
                            chunk = response.read(self.DOWNLOAD_CHUNK_SIZE)
                            if not chunk:
                                break
                            download_file.write(chunk)
                            self.download_progress += self.DOWNLOAD_CHUNK_SIZE
                            if self.on_update_download:
                                self.on_update_download(self)
                        self.response_text += ' OK.'
                    else:
                        self.response_text = response.read()
                content_length = self.response_info.get('content-length', -1)
                response_report = '\nResponse Headers:\n%s' % Utils.str(
                    self.response_info)
                response_report += '\nResponse (%d) content-length=%s, len=<%s>:\n' % (
                    self.response_code,
                    content_length,
                    len(self.response_text),
                )
                try:
                    response_report += Utils.str(self.response_text)
                except:
                    response_report += '<possible binary content>'
                self.success = True
                break
            except self.exceptions as e:
                Logger.debug('Exception...')
                root_exception = e
                response_report = '\nResponse <Exception>: '
                if isinstance(e, HTTPError):
                    self.response_code = e.code
                    self.response_text = Utils.str(e.read())
                    response_report += self.response_text
                else:
                    response_report += Utils.str(e)
                rex = RequestException(Utils.str(e), root_exception,
                                       request_report, response_report)
            finally:
                try:
                    if download_file:
                        download_file.close()
                    Logger.debug(response_report)
                except:
                    Logger.debug('unable to print response_report')
                if response:
                    response.close()
            if rex:
                if self.on_exception:
                    Logger.debug('calling self.on_exception...')
                    self.on_exception(self, rex)
                if self.cancel_operation and self.cancel_operation():
                    break
                Logger.debug('current_tries: ' + str(self.current_tries) +
                             ' maximum tries: ' + str(self.tries) + ' i: ' +
                             str(i))
                if self.current_tries == self.tries:
                    Logger.debug('max retries reached')
                    if self.on_failure:
                        self.on_failure(self)
                    if self.on_complete:
                        self.on_complete(self)
                    Logger.debug('Raising exception...')
                    raise rex
                current_time = time.time()
                max_waiting_time = current_time + self.current_delay
                Logger.debug('current_delay: ' + str(self.current_delay) +
                             ' seconds. Waiting...')
                while (not self.cancel_operation
                       or not self.cancel_operation()
                       ) and max_waiting_time > current_time:
                    remaining = round(max_waiting_time - current_time)
                    if self.waiting_retry:
                        Logger.debug('calling self.waiting_retry...')
                        self.waiting_retry(self, remaining)
                    self.wait(1)
                    current_time = time.time()
                Logger.debug('Done waiting.')
                self.current_delay *= self.backoff

        if self.success and self.on_success:
            self.on_success(self)
        if self.on_complete:
            self.on_complete(self)
        return self.response_text