Exemplo n.º 1
0
 def get_item(self, driveid, item_driveid=None, item_id=None, path=None, find_subtitles=False, include_download_info=False):
     self._provider.configure(self._account_manager, driveid)
     item_driveid = Utils.default(item_driveid, driveid)
     cache_key = self._addonid+'-drive-'+driveid+'-item_driveid-'+Utils.str(item_driveid)+'-item_id-'+Utils.str(item_id)+'-path-'+Utils.str(path)
     f = self._cache.get(cache_key)
     if f:
         item = self._extract_item(f, include_download_info)
     else:
         cache_key = self._addonid+'-drive-None-item_driveid-None-item_id-None-path-'+path
         f = self._cache.get(cache_key)
         if f:
             item = self._extract_item(f, include_download_info)
         else:
             self._parameters['fields'] = self._file_fileds
             if not item_id and path == '/':
                 item_id = 'root'
             if item_id:
                 f = self._provider.get('/files/%s' % item_id, parameters = self._parameters)
                 self._cache.set(cache_key, f, expiration=datetime.timedelta(seconds=59))
                 item = self._extract_item(f, include_download_info)
             else:
                 item = self.get_item_by_path(path, include_download_info)
     
     if find_subtitles:
         subtitles = []
         self._parameters['q'] = 'name contains \'%s\'' % urllib.quote(Utils.remove_extension(item['name']))
         files = self._provider.get('/files', parameters = self._parameters)
         for f in files['files']:
             subtitle = self._extract_item(f, include_download_info)
             if subtitle['name_extension'] == 'srt' or subtitle['name_extension'] == 'sub' or subtitle['name_extension'] == 'sbv':
                 subtitles.append(subtitle)
         if subtitles:
             item['subtitles'] = subtitles
     return item
Exemplo n.º 2
0
 def get_item(self, driveid, item_driveid=None, item_id=None, path=None, find_subtitles=False, include_download_info=False):
     self._provider.configure(self._account_manager, driveid)
     item_driveid = Utils.default(item_driveid, driveid)
     cache_key = self._addonid+'-drive-'+driveid+'-item_driveid-'+Utils.str(item_driveid)+'-item_id-'+Utils.str(item_id)+'-path-'+Utils.str(path)
     f = self._cache.get(cache_key)
     if not f :
         if item_id:
             f = self._provider.get('/drives/'+item_driveid+'/items/' + item_id, parameters = self._extra_parameters)
         elif path == 'sharedWithMe' or path == 'recent':
             return
         else:
             if path == '/':
                 path = 'root'
             else:
                 parts = path.split('/')
                 if len(parts) > 1 and not parts[0]:
                     path = 'root:'+path+':'
             f = self._provider.get('/drives/'+driveid+'/' + path, parameters = self._extra_parameters)
         self._cache.set(cache_key, f, expiration=datetime.timedelta(seconds=59))
     item = self._extract_item(f, include_download_info)
     if find_subtitles:
         subtitles = []
         parent_id = Utils.get_safe_value(Utils.get_safe_value(f, 'parentReference', {}), 'id')
         search_url = '/drives/'+item_driveid+'/items/' + parent_id + '/search(q=\'{'+urllib.quote(Utils.remove_extension(item['name']))+'}\')'
         files = self._provider.get(search_url)
         for f in files['value']:
             subtitle = self._extract_item(f, include_download_info)
             if subtitle['name_extension'] == 'srt' or subtitle['name_extension'] == 'sub' or subtitle['name_extension'] == 'sbv':
                 subtitles.append(subtitle)
         if subtitles:
             item['subtitles'] = subtitles
     return item
Exemplo n.º 3
0
 def __init__(self):
     profile_path = Utils.unicode(KodiUtils.translate_path(KodiUtils.get_addon_info('profile')))
     ini_path = os.path.join(profile_path, 'onedrive.ini')
     if os.path.exists(ini_path):
         config = ConfigParser()
         account_manager = AccountManager(profile_path)
         config.read(ini_path)
         for driveid in config.sections():
             Logger.notice('Migrating drive %s...' % driveid)
             account = { 'id' : driveid, 'name' : config.get(driveid, 'name')}
             account['drives'] = [{
                 'id' : driveid,
                 'name' : '',
                 'type' : 'migrated'
             }]
             account['access_tokens'] = {
                 'access_token': config.get(driveid, 'access_token'),
                 'refresh_token': config.get(driveid, 'refresh_token'),
                 'expires_in': 0,
                 'date': 0
             }
             try:
                 account_manager.add_account(account)
             except Exception as e:
                 raise UIException(32021, e)
         os.remove(ini_path)
     KodiUtils.set_addon_setting('migrated', 'true')
Exemplo n.º 4
0
 def get_subtitles(self,
                   parent,
                   name,
                   item_driveid=None,
                   include_download_info=False):
     parameters = self.prepare_parameters()
     item_driveid = Utils.default(item_driveid, self._driveid)
     subtitles = []
     parameters['fields'] = 'files(' + self._get_field_parameters() + ')'
     parameters['q'] = 'name contains \'%s\'' % Utils.str(
         Utils.remove_extension(name)).replace("'", "\\'")
     files = self.get('/files', parameters=parameters)
     for f in files['files']:
         subtitle = self._extract_item(f, include_download_info)
         if subtitle['name_extension'].lower() in ('srt', 'idx', 'sub',
                                                   'sbv', 'ass', 'ssa',
                                                   'smi'):
             subtitles.append(subtitle)
     return subtitles
 def _show_progress_after_change(self, change, change_type, pending_changes,
                                 changes_done, retry_changes, export):
     completed = len(changes_done) + len(retry_changes)
     target = len(pending_changes) + completed
     msg = self._common_addon.getLocalizedString(32041)
     if change_type:
         msg = Utils.get_safe_value(change, 'name', 'n/a')
     self._export_progress_dialog_bg.update(
         self._get_percent(completed, target),
         self._addon_name + ' ' + self._get_progress_header(export), msg)
 def search(self,
            query,
            item_driveid=None,
            item_id=None,
            on_items_page_completed=None):
     item_driveid = Utils.default(item_driveid, self._driveid)
     parameters = self.prepare_parameters()
     parameters[
         'fields'] = 'files(%s),kind,nextPageToken' % self._get_field_parameters(
         )
     query = 'fullText contains \'%s\'' % Utils.str(query)
     if item_id:
         query += ' and \'%s\' in parents' % item_id
     parameters['q'] = query + ' and not trashed'
     parameters['pageSize'] = 1000
     files = self.get('/files', parameters=parameters)
     if self.cancel_operation():
         return
     return self.process_files(files, parameters, on_items_page_completed)
 def _slideshow(self,
                driveid,
                item_driveid=None,
                item_id=None,
                path=None,
                change_token=None):
     new_change_token = self.new_change_token_slideshow(
         change_token, driveid, item_driveid, item_id, path)
     if self.cancel_operation():
         return
     wait_for_slideshow = False
     if not change_token or change_token != new_change_token:
         Logger.notice(
             'Slideshow will start. change_token: %s, new_change_token: %s'
             % (change_token, new_change_token))
         params = {
             'action': '_list_folder',
             'content_type': self._content_type,
             'item_driveid': Utils.default(item_driveid, ''),
             'item_id': Utils.default(item_id, ''),
             'driveid': driveid,
             'path': Utils.default(path, '')
         }
         extra_params = ',recursive' if self._addon.getSetting(
             'slideshow_recursive') == 'true' else ''
         KodiUtils.executebuiltin('SlideShow(' + self._addon_url + '?' +
                                  urllib.urlencode(params) + extra_params +
                                  ')')
         wait_for_slideshow = True
     else:
         Logger.notice(
             'Slideshow child count is the same, nothing to refresh...')
     t = threading.Thread(target=self._refresh_slideshow,
                          args=(
                              driveid,
                              item_driveid,
                              item_id,
                              path,
                              new_change_token,
                              wait_for_slideshow,
                          ))
     t.setDaemon(True)
     t.start()
Exemplo n.º 8
0
 def get_subtitles(self, driveid, path):
     item = self.get_item(driveid, path)
     key = '%s%s-subtitles' % (
         driveid,
         path,
     )
     Logger.debug('Testing subtitles from cache: %s' % key)
     subtitles = self._items_cache.get(key)
     if not subtitles:
         provider = self._get_provider()
         provider.configure(self._account_manager, driveid)
         self.is_path_possible(driveid, path)
         item_driveid = Utils.default(
             Utils.get_safe_value(item, 'drive_id'), driveid)
         subtitles = provider.get_subtitles(item['parent'], item['name'],
                                            item_driveid)
         Logger.debug('Saving subtitles in cache: %s' % key)
         self._items_cache.set(key, item)
     return subtitles
Exemplo n.º 9
0
 def process_files(self, files, parameters, on_items_page_completed=None, include_download_info=False, extra_info=None):
     items = []
     if files:
         kind = Utils.get_safe_value(files, 'kind', '')
         collection = []
         if kind == 'drive#fileList':
             collection = files['files']
         elif kind == 'drive#changeList':
             collection = files['changes']
         elif 'albums' in files:
             kind = 'album'
             collection = files['albums']
         elif 'mediaItems' in files:
             kind = 'media_item'
             collection = files['mediaItems']
         if collection:
             for f in collection:
                 f['kind'] = Utils.get_safe_value(f, 'kind', kind)
                 item = self._extract_item(f, include_download_info)
                 if item:
                     items.append(item)
             if on_items_page_completed:
                 on_items_page_completed(items)
         if type(extra_info) is dict:
             if 'newStartPageToken' in files:
                 extra_info['change_token'] = files['newStartPageToken']
         if 'nextPageToken' in files:
             parameters['pageToken'] = files['nextPageToken']
             url = '/files'
             provider_method = self.get
             if kind == 'drive#changeList':
                 url = '/changes'
             elif kind == 'album':
                 url = '/albums'
                 provider_method = self._photos_provider.get
             elif kind == 'media_item':
                 url = '/mediaItems:search'
                 provider_method = self._photos_provider.post
             next_files = provider_method(url, parameters = parameters)
             if self.cancel_operation():
                 return
             items.extend(self.process_files(next_files, parameters, on_items_page_completed, include_download_info, extra_info))
     return items
 def _select_stream_format(self, driveid, item_driveid=None, item_id=None, auto=False):
     url = None
     if not auto:
         self._progress_dialog.update(0, self._addon.getLocalizedString(32009))
     self._provider.configure(self._account_manager, driveid)
     self._provider.get_item(item_driveid, item_id)
     request = Request('https://drive.google.com/get_video_info', urllib.urlencode({'docid' : item_id}), {'authorization': 'Bearer %s' % self._provider.get_access_tokens()['access_token']})
     response_text = request.request()
     response_params = dict(urlparse.parse_qsl(response_text))
     if not auto:
         self._progress_dialog.close()
     if Utils.get_safe_value(response_params, 'status', '') == 'ok':
         fmt_list = Utils.get_safe_value(response_params, 'fmt_list', '').split(',')
         stream_formats = []
         for fmt in fmt_list:
             data = fmt.split('/')
             stream_formats.append(data[1])
         stream_formats.append(self._addon.getLocalizedString(32015))
         Logger.debug('Stream formats: %s' % Utils.str(stream_formats))
         select = -1
         if auto:
             select = self._auto_select_stream(stream_formats)
         else:
             select = self._dialog.select(self._addon.getLocalizedString(32016), stream_formats, 8000, 0)
         Logger.debug('Selected: %s' % Utils.str(select))
         if select == -1:
             self._cancel_operation = True
         elif select != len(stream_formats) - 1:
             data = fmt_list[select].split('/')
             fmt_stream_map = Utils.get_safe_value(response_params, 'fmt_stream_map', '').split(',')
             
             for fmt in fmt_stream_map:
                 stream_data = fmt.split('|')
                 if stream_data[0] == data[0]:
                     url = stream_data[1]
                     break
             if url:
                 cookie_header = ''
                 for cookie in request.response_cookies:
                     if cookie_header: cookie_header += ';'
                     cookie_header += cookie.name + '=' + cookie.value;
                 url += '|cookie=' + urllib.quote(cookie_header)
     return url
Exemplo n.º 11
0
    def handle_exception(ex):
        stacktrace = ExceptionUtils.full_stacktrace(ex)
        rex = ExceptionUtils.extract_exception(ex, RequestException)
        httpex = ExceptionUtils.extract_exception(ex, HTTPError)
        dnf = ExceptionUtils.extract_exception(ex, DriveNotFoundException)

        line1 = ''
        line2 = Utils.unicode(ex)

        send_report = True
        log_report = True
        if rex and rex.response:
            line1 = Utils.unicode(rex)
            line2 = ExceptionUtils.extract_error_message(rex.response)

        if httpex:
            if httpex.code == 401:
                send_report = False
            elif httpex.code == 404:
                send_report = False
                log_report = False
        if dnf:
            send_report = False
            log_report = False

        addonid = KodiUtils.get_addon_info('id')
        addon_version = KodiUtils.get_addon_info('version')
        common_addon_version = KodiUtils.get_addon_info(
            'version', 'script.module.clouddrive.common')
        report = '[%s] [%s]/[%s]\n\n%s\n%s\n%s\n\n%s' % (
            addonid, addon_version, common_addon_version, line1, line2, '',
            stacktrace)
        if rex:
            report += '\n\n%s\nResponse:\n%s' % (rex.request, rex.response)
        if log_report:
            Logger.debug(report)
        else:
            Logger.debug(ex)
        if send_report:
            Logger.notice(report)
            Logger.notice('Report sent')
            ErrorReport.send_report(report)
Exemplo n.º 12
0
 def _extract_item(self, f, driveid, include_download_info=False):
     size = long('%s' % Utils.get_safe_value(f, 'size', 0))
     item = {
         'id': f['id'],
         'name': f['name'],
         'name_extension': Utils.get_extension(f['name']),
         'drive_id': driveid,
         'path_lower': f['path_lower'],
         'last_modified_date': Utils.get_safe_value(f, 'client_modified'),
         'size': size
     }
     if f['.tag'] == 'folder':
         item['folder'] = {'child_count': 0}
     metadata = Utils.get_safe_value(
         Utils.get_safe_value(f, 'media_info', {}), 'metadata', {})
     tag = Utils.get_safe_value(metadata, '.tag', '')
     if tag == 'video':
         video = metadata['video']
         dimensions = Utils.get_safe_value(video, 'dimensions', {})
         item['video'] = {
             'width':
             long('%s' % Utils.get_safe_value(dimensions, 'width', 0)),
             'height':
             long('%s' % Utils.get_safe_value(dimensions, 'height', 0)),
             'duration':
             long('%s' % Utils.get_safe_value(video, 'duration', 0)) / 1000
         }
     elif tag == 'photo':
         item['image'] = {'size': size}
     if include_download_info:
         parameters = {
             'arg':
             json.dumps({'path': item['id']}),
             'authorization':
             'Bearer %s' %
             self._provider.get_access_tokens()['access_token']
         }
         url = self._provider._get_content_url() + '/files/download'
         item['download_info'] = {
             'url': url + '?%s' % urllib.urlencode(parameters)
         }
     return item
 def get_export_map(self):
     exports = self.export_manager.load()
     export_map = {}
     for exportid in exports:
         export = exports[exportid]
         schedules = Utils.get_safe_value(export, 'schedules', [])
         exporting = Utils.get_safe_value(export, 'exporting', False)
         if not exporting:
             if Utils.get_safe_value(export, 'schedule', False) and schedules:
                 for schedule in schedules:
                     key = Utils.str(Utils.get_safe_value(schedule, 'type', ''))
                     if key != self._startup_type:
                         key += Utils.get_safe_value(schedule, 'at', '')
                     export_map[key] = Utils.get_safe_value(export_map, key, [])
                     export_map[key].append(export)
             if Utils.get_safe_value(export, 'watch', False):
                 export_map['watch'] = Utils.get_safe_value(export_map, 'watch', [])
                 export_map['watch'].append(export)
     Logger.debug('export_map: %s' % Utils.str(export_map))
     return export_map
Exemplo n.º 14
0
    def get_item_by_path(self, path, include_download_info=False):
        parameters = self.prepare_parameters()
        if path[-1:] == '/':
            path = path[:-1]
        Logger.debug(path + ' <- Target')
        key = '%s%s' % (
            self._driveid,
            path,
        )
        Logger.debug('Testing item from cache: %s' % key)
        item = self._items_cache.get(key)
        if not item:
            parameters['fields'] = 'files(%s)' % self._get_field_parameters()
            index = path.rfind('/')
            filename = urllib.unquote(path[index + 1:])
            parent = path[0:index]
            if not parent:
                parent = 'root'
            else:
                parent = self.get_item_by_path(parent,
                                               include_download_info)['id']
            item = None
            parameters['q'] = '\'%s\' in parents and name = \'%s\'' % (
                Utils.str(parent), Utils.str(filename).replace("'", "\\'"))
            parameters['pageSize'] = 1000
            files = self.get('/files', parameters=parameters)
            if (len(files['files']) > 0):
                for f in files['files']:
                    item = self._extract_item(f, include_download_info)
                    break
        else:
            Logger.debug('Found in cache.')
        if not item:
            raise RequestException(
                'Not found by path',
                HTTPError(path, 404, 'Not found', None, None),
                'Request URL: %s' % path, None)

        else:
            self._items_cache.set(key, item)
        return item
Exemplo n.º 15
0
    def onInit(self):
        self.title_label = self.getControl(1000)
        self.cancel_button = self.getControl(999)
        self.save_button = self.getControl(1001)
        self.save_export_button = self.getControl(1002)

        self.drive_name_label = self.getControl(1003)
        self.drive_folder_label = self.getControl(1004)
        self.dest_folder_label = self.getControl(1005)
        self.dest_folder_button = self.getControl(1006)

        self.update_library_sw = self.getControl(1007)
        self.download_artwork_sw = self.getControl(1008)
        self.watch_drive_sw = self.getControl(1009)
        self.schedule_sw = self.getControl(1010)

        self.schedule_label = self.getControl(10100)
        self.schedule_list = self.getControl(1011)
        self.add_schedule_button = self.getControl(1012)
        self.setFocus(self.dest_folder_button)

        self.schedule_label.setLabel(
            self._common_addon.getLocalizedString(32083))

        self.title_label.setLabel(self._addon_name + ' - ' +
                                  self._common_addon.getLocalizedString(32004))
        account = self.account_manager.get_by_driveid('account', self.driveid)
        drive = self.account_manager.get_by_driveid('drive', self.driveid,
                                                    account)
        drive_name = self.account_manager.get_account_display_name(
            account, drive, self.provider, True)
        self.drive_name_label.setLabel(drive_name)
        self.drive_folder_label.setLabel(self.name)

        exports = self.export_manager.get_exports()
        export = Utils.get_safe_value(exports, self.item_id, {})
        if export:
            self.editing = True
            self.watch_drive_sw.setSelected(
                Utils.get_safe_value(export, 'watch', False))
            self.download_artwork_sw.setSelected(
                Utils.get_safe_value(export, 'download_artwork', False))
            self.schedule_sw.setSelected(
                Utils.get_safe_value(export, 'schedule', False))
            self.update_library_sw.setSelected(
                Utils.get_safe_value(export, 'update_library', False))
            self.schedules = Utils.get_safe_value(export, 'schedules', [])
            for schedule in self.schedules:
                self.add_schedule_item(schedule)

        if not self.editing:
            self.select_detination()
        else:
            self.dest_folder_label.setLabel(
                Utils.get_safe_value(export, 'destination_folder', ''))
        self.schedule_enabled(self.schedule_sw.isSelected())
Exemplo n.º 16
0
    def import_bookmarks(self, driveid, item_driveid=None, item_id=None):
        self._provider.configure(self._account_manager, driveid)

        #  self._progress_dialog.update(0, '')
        #  color = 'lime'
        #  ban = self._common_addon.getLocalizedString(32013)

        item = self._provider.get_item(item_driveid=item_driveid,
                                       item_id=item_id,
                                       find_bookmarks=True,
                                       include_download_info=True)
        bookmarks = []
        for bookmark in item['bookmarks']:
            bookmarks.append(
                self._get_item_play_url(
                    urllib.quote(Utils.str(bookmark['name'])), driveid,
                    Utils.default(Utils.get_safe_value(bookmark, 'drive_id'),
                                  driveid), bookmark['id'], True))
            url = bookmark['download_info']['url']
            request_params = {
                'on_complete':
                lambda request: self.save_bookmark_image(request.response_text
                                                         ),
            }
            request = self._provider.prepare_request('get', url)
            response = request.request()
            if request.response_code == 403 or request.response_code == 429:
                color = 'red'
                ban = self._common_addon.getLocalizedString(32033)
            else:
                self.save_bookmark_image(response, bookmark["name"])
                item_path = 'plugin://plugin.googledrive/?item_id=%s&driveid=%s&item_driveid=%s&action=play&content_type=video' % (
                    item_id, driveid, item_driveid)
                p = {
                    'mode': 'import_image',
                    'item_label': item["name"],
                    'image_name': bookmark["name"],
                    'item_path': item_path,
                }
                addon_id = 'context.item.savebookmarks'
                KodiUtils.run_plugin(addon_id, p)
Exemplo n.º 17
0
 def _remove_export(self, driveid, item_id):
     self._export_manager = ExportManager(self._profile_path)
     exports = self._export_manager.get_exports()
     if item_id in exports:
         item = exports[item_id]
         remove_export = self._dialog.yesno(
             self._addon_name,
             self._common_addon.getLocalizedString(32001) %
             Utils.unicode(item['name']))
         if remove_export:
             keep_locals = self._dialog.yesno(
                 self._addon_name,
                 self._common_addon.getLocalizedString(32086) %
                 Utils.unicode(item['name']))
             if not keep_locals:
                 self._export_manager.remove_export(item_id, False)
             else:
                 self._export_manager.remove_export(item_id)
             KodiUtils.executebuiltin('Container.Refresh')
     else:
         KodiUtils.executebuiltin('Container.Refresh')
Exemplo n.º 18
0
 def changes(self):
     change_token = self.get_change_token()
     if not change_token:
         change_token = Utils.get_safe_value(
             self.get('/changes/startPageToken',
                      parameters=self.prepare_parameters()),
             'startPageToken')
     extra_info = {}
     parameters = self.prepare_parameters()
     parameters['pageToken'] = change_token
     parameters[
         'fields'] = 'kind,nextPageToken,newStartPageToken,changes(kind,type,removed,file(%s))' % self._get_field_parameters(
         )
     f = self.get('/changes', parameters=parameters)
     changes = self.process_files(f,
                                  parameters,
                                  include_download_info=True,
                                  extra_info=extra_info)
     self.persist_change_token(
         Utils.get_safe_value(extra_info, 'change_token'))
     return changes
Exemplo n.º 19
0
    def get_folder_items(self,
                         item_driveid=None,
                         item_id=None,
                         path=None,
                         on_items_page_completed=None,
                         include_download_info=False):
        item_driveid = Utils.default(item_driveid, self._driveid)
        is_album = item_id and item_id[:6] == 'album-'
        if is_album:
            item_id = item_id[6:]
        parameters = self.prepare_parameters()
        if item_id:
            parameters['q'] = '\'%s\' in parents' % item_id
        elif path == 'sharedWithMe' or path == 'starred':
            parameters['q'] = path
        elif path != 'photos':
            if path == '/':
                parent = self._driveid if self._is_team_drive else 'root'
                parameters['q'] = '\'%s\' in parents' % parent
            elif not is_album:
                item = self.get_item_by_path(path, include_download_info)
                parameters['q'] = '\'%s\' in parents' % item['id']

        parameters[
            'fields'] = 'files(%s),kind,nextPageToken' % self._get_field_parameters(
            )
        if 'q' in parameters:
            parameters['q'] += ' and not trashed'

        self.configure(self._account_manager, self._driveid)
        provider_method = self.get
        url = '/files'
        parameters['pageSize'] = 1000
        if path == 'photos':
            self._photos_provider = GooglePhotos()
            self._photos_provider.configure(self._account_manager,
                                            self._driveid)
            parameters = {}
            provider_method = self._photos_provider.get
            url = '/albums'
        elif is_album:
            self._photos_provider = GooglePhotos()
            self._photos_provider.configure(self._account_manager,
                                            self._driveid)
            parameters = {'albumId': item_id}
            provider_method = self._photos_provider.post
            url = '/mediaItems:search'

        files = provider_method(url, parameters=parameters)
        if self.cancel_operation():
            return
        return self.process_files(files, parameters, on_items_page_completed,
                                  include_download_info)
Exemplo n.º 20
0
 def search(self, query, driveid, item_driveid=None, item_id=None, on_items_page_completed=None):
     self._provider.configure(self._account_manager, driveid)
     item_driveid = Utils.default(item_driveid, driveid)
     self._parameters['fields'] = 'files(%s)' % self._file_fileds
     query = 'fullText contains \'%s\'' % query
     if item_id:
         query += ' and \'%s\' in parents' % item_id
     self._parameters['q'] = query
     files = self._provider.get('/files', parameters = self._parameters)
     if self.cancel_operation():
         return
     return self.process_files(driveid, files, on_items_page_completed)
Exemplo n.º 21
0
 def refresh_tokens(self,
                    provider_name,
                    refresh_token,
                    request_params=None):
     request_params = Utils.default(request_params, {})
     headers = {'addon': self.get_addon_header()}
     body = urllib.parse.urlencode({
         'provider': provider_name,
         'refresh_token': refresh_token
     })
     return Request(KodiUtils.get_signin_server() + '/refresh', body,
                    headers, **request_params).request_json()
 def create_text_file(file_path, content):
     f = None
     try:
         f = KodiUtils.file(file_path, 'w')
         f.write(Utils.str(content))
     except Exception as e:
         ErrorReport.handle_exception(e)
         return False
     finally:
         if f:
             f.close()
     return True
Exemplo n.º 23
0
 def display_google_ban_result(self, request):
     self._progress_dialog.close()
     color = 'lime'
     ban = self._common_addon.getLocalizedString(32013)
     if request.response_code == 403 or request.response_code == 429:
         color = 'red'
         ban = self._common_addon.getLocalizedString(32033)
     self._dialog.ok(self._addon_name, 
                     self._addon.getLocalizedString(32072) % '[B][COLOR %s]%s[/COLOR][/B]' % (color, ban,),
                     self._addon.getLocalizedString(32073) % '[B]%s[/B]' % Utils.str(request.response_code),
                     request.response_text
     )
Exemplo n.º 24
0
 def new_change_token_slideshow(self,
                                change_token,
                                driveid,
                                item_driveid=None,
                                item_id=None,
                                path=None):
     self._provider.configure(self._account_manager, driveid)
     if not change_token:
         response = self._provider.get(
             '/changes/startPageToken',
             parameters=self._provider._parameters)
         self._change_token = Utils.get_safe_value(response,
                                                   'startPageToken')
         change_token = 1
     else:
         page_token = self._change_token
         while page_token:
             self._provider._parameters['pageToken'] = page_token
             self._provider._parameters[
                 'fields'] = 'nextPageToken,newStartPageToken,changes(file(id,name,parents))'
             response = self._provider.get(
                 '/changes', parameters=self._provider._parameters)
             if self.cancel_operation():
                 return
             self._change_token = Utils.get_safe_value(
                 response, 'newStartPageToken', self._change_token)
             changes = Utils.get_safe_value(response, 'changes', [])
             for change in changes:
                 f = Utils.get_safe_value(change, 'file', {})
                 parents = Utils.get_safe_value(f, 'parents', [])
                 parents.append(f['id'])
                 if item_id in parents:
                     return change_token + 1
             page_token = Utils.get_safe_value(response, 'nextPageToken')
     return change_token
 def play(self, driveid, item_driveid=None, item_id=None):
     find_subtitles = self._addon.getSetting(
         'set_subtitle') == 'true' and self._content_type == 'video'
     item = self.get_item(driveid,
                          item_driveid,
                          item_id,
                          find_subtitles=find_subtitles)
     file_name = Utils.unicode(item['name'])
     list_item = xbmcgui.ListItem(file_name)
     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(
         DownloadServiceUtil.build_download_url(
             self._addonid, driveid, item_driveid, item_id,
             urllib.quote(Utils.str(file_name))))
     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(
                 DownloadServiceUtil.build_download_url(
                     self._addonid, driveid,
                     Utils.default(
                         Utils.get_safe_value(subtitle, 'drive_id'),
                         driveid), subtitle['id'],
                     urllib.quote(Utils.str(subtitle['name']))))
         list_item.setSubtitles(subtitles)
     xbmcplugin.setResolvedUrl(self._addon_handle, True, list_item)
 def get_subtitles(self):
     try:
         from clouddrive.common.remote.request import Request
         from clouddrive.common.service.download import DownloadServiceUtil
         response = Request(self.getPlayingFile() + '?subtitles',
                            None).request_json()
         if response and 'driveid' in response and 'subtitles' in response:
             driveid = response['driveid']
             subtitles = response['subtitles']
             for subtitle in subtitles:
                 url = DownloadServiceUtil.build_download_url(
                     driveid,
                     Utils.default(
                         Utils.get_safe_value(subtitle, 'drive_id'),
                         driveid), subtitle['id'],
                     urllib.quote(Utils.str(subtitle['name'])))
                 Logger.debug('subtitle: %s' % url)
                 self.setSubtitles(url)
     except Exception as e:
         Logger.error(e)
         from clouddrive.common.remote.errorreport import ErrorReport
         ErrorReport.handle_exception(e)
 def prepare_request(self, method, path, parameters=None, request_params=None, access_tokens=None, headers=None):
     parameters = Utils.default(parameters, {})
     access_tokens = Utils.default(access_tokens, {})
     encoded_parameters = urllib.urlencode(parameters)
     url = self._build_url(method, path, encoded_parameters)
     request_params = self._wrap_on_exception(request_params)
     if not headers:
         headers = Utils.default(self._get_request_headers(), {})
     content_type = Utils.get_safe_value(headers, 'content-type', '')
     if content_type == 'application/json':
         data = json.dumps(parameters)
     else:
         data = None if method == 'get' else encoded_parameters
     if not access_tokens:
         access_tokens = self.get_access_tokens()
     self._validate_access_tokens(access_tokens, url, data, headers)
     if time.time() > (access_tokens['date'] + access_tokens['expires_in'] - 600):
         access_tokens.update(self.refresh_access_tokens(request_params))
         self._validate_access_tokens(access_tokens, 'refresh_access_tokens', 'Unknown', 'Unknown')
         self.persist_access_tokens(access_tokens)
     headers['authorization'] = 'Bearer ' + access_tokens['access_token']
     return Request(url, data, headers, **request_params) 
Exemplo n.º 28
0
 def get_drives(self, request_params={}, access_tokens={}):
     response = self.get('/drives', request_params=request_params, access_tokens=access_tokens)
     drives = []
     drives_id_list  =[]
     for drive in response['value']:
         drives_id_list.append(drive['id'])
         drives.append({
             'id' : drive['id'],
             'name' : Utils.get_safe_value(drive, 'name', ''),
             'type' : drive['driveType']
         })
     
     response = self.get('/me/drives', request_params=request_params, access_tokens=access_tokens)
     for drive in response['value']:
         if not drive['id'] in drives_id_list:
             drives_id_list.append(drive['id'])
             drives.append({
                 'id' : drive['id'],
                 'name' : Utils.get_safe_value(drive, 'name', ''),
                 'type' : drive['driveType']
             })
     return drives
Exemplo n.º 29
0
    def get_folder_items(self,
                         item_driveid=None,
                         item_id=None,
                         path=None,
                         on_items_page_completed=None,
                         include_download_info=False):
        item_driveid = Utils.default(item_driveid, self._driveid)
        is_album = item_id and item_id[:6] == 'album-'

        if is_album:
            Logger.notice(item_id)
            item_id = item_id[6:]
            Logger.notice(item_id)

        parameters = copy.deepcopy(self._default_parameters)
        if item_id:
            parameters['q'] = '\'%s\' in parents' % item_id
        elif path == 'sharedWithMe' or path == 'starred':
            parameters['q'] = path
        elif path != 'photos':
            if path == '/':
                parameters['q'] = '\'root\' in parents'
            elif not is_album:
                item = self.get_item_by_path(path, include_download_info)
                parameters['q'] = '\'%s\' in parents' % item['id']

        parameters['fields'] = 'files(%s),nextPageToken' % self._file_fileds
        if 'q' in parameters:
            parameters['q'] += ' and not trashed'
        if path == 'photos':
            self._photos_provider = GooglePhotos()
            Logger.notice(self._get_api_url())
            self._photos_provider.configure(self._account_manager,
                                            self._driveid)
            files = self._photos_provider.get('/albums')
            files['is_album'] = True
        elif is_album:
            self._photos_provider = GooglePhotos()
            self._photos_provider.configure(self._account_manager,
                                            self._driveid)
            files = self._photos_provider.post('/mediaItems:search',
                                               parameters={'albumId': item_id})
            files['is_media_items'] = True
        else:
            self.configure(self._account_manager, self._driveid)
            files = self.get('/files', parameters=parameters)
            files['is_album'] = False
        if self.cancel_operation():
            return
        return self.process_files(files, parameters, on_items_page_completed,
                                  include_download_info)
Exemplo n.º 30
0
 def __init__(self):
     self._addon = KodiUtils.get_addon()
     self._addonid = self._addon.getAddonInfo('id')
     self._addon_name = self._addon.getAddonInfo('name')
     self._addon_url = sys.argv[0]
     self._addon_version = self._addon.getAddonInfo('version')
     self._common_addon_id = 'script.module.clouddrive.common'
     self._common_addon = KodiUtils.get_addon(self._common_addon_id)
     self._common_addon_version = self._common_addon.getAddonInfo('version')
     self._dialog = xbmcgui.Dialog()
     self._profile_path = Utils.unicode(KodiUtils.translate_path(self._addon.getAddonInfo('profile')))
     self._progress_dialog = DialogProgress(self._addon_name)
     self._progress_dialog_bg = DialogProgressBG(self._addon_name)
     self._export_progress_dialog_bg = DialogProgressBG(self._addon_name)
     self._system_monitor = KodiUtils.get_system_monitor()
     self._account_manager = AccountManager(self._profile_path)
     self._pin_dialog = None
     self.iskrypton = KodiUtils.get_home_property('iskrypton') == 'true'
     
     if len(sys.argv) > 1:
         self._addon_handle = int(sys.argv[1])
         self._addon_params = urlparse.parse_qs(sys.argv[2][1:])
         for param in self._addon_params:
             self._addon_params[param] = self._addon_params.get(param)[0]
         self._content_type = Utils.get_safe_value(self._addon_params, 'content_type')
         if not self._content_type:
             wid = xbmcgui.getCurrentWindowId()
             if wid == 10005 or wid == 10500 or wid == 10501 or wid == 10502:
                 self._content_type = 'audio'
             elif wid == 10002:
                 self._content_type = 'image'
             else:
                 self._content_type = 'video'
         xbmcplugin.addSortMethod(handle=self._addon_handle, sortMethod=xbmcplugin.SORT_METHOD_LABEL)
         xbmcplugin.addSortMethod(handle=self._addon_handle, sortMethod=xbmcplugin.SORT_METHOD_UNSORTED ) 
         xbmcplugin.addSortMethod(handle=self._addon_handle, sortMethod=xbmcplugin.SORT_METHOD_SIZE )
         xbmcplugin.addSortMethod(handle=self._addon_handle, sortMethod=xbmcplugin.SORT_METHOD_DATE )
         xbmcplugin.addSortMethod(handle=self._addon_handle, sortMethod=xbmcplugin.SORT_METHOD_DURATION )
Exemplo n.º 31
0
 def _refresh_slideshow(self, driveid, item_driveid, item_id, path,
                        change_token, wait_for_slideshow):
     if wait_for_slideshow:
         Logger.notice(
             'Waiting up to 10 minutes until the slideshow for folder %s starts...'
             % Utils.default(item_id, path))
         max_waiting_time = time.time() + 10 * 60
         while not self.cancel_operation(
         ) and not KodiUtils.get_cond_visibility(
                 'Slideshow.IsActive') and max_waiting_time > time.time():
             if self._system_monitor.waitForAbort(2):
                 break
         self._print_slideshow_info()
     interval = self._addon.getSetting('slideshow_refresh_interval')
     Logger.notice(
         'Waiting up to %s minute(s) to check if it is needed to refresh the slideshow of folder %s...'
         % (interval, Utils.default(item_id, path)))
     target_time = time.time() + int(interval) * 60
     while not self.cancel_operation() and target_time > time.time(
     ) and KodiUtils.get_cond_visibility('Slideshow.IsActive'):
         if self._system_monitor.waitForAbort(10):
             break
     self._print_slideshow_info()
     if not self.cancel_operation() and KodiUtils.get_cond_visibility(
             'Slideshow.IsActive'):
         try:
             self._slideshow(driveid, item_driveid, item_id, path,
                             change_token)
         except Exception as e:
             Logger.error(
                 'Slideshow failed to auto refresh. Will be restarted when possible. Error: '
             )
             Logger.error(ExceptionUtils.full_stacktrace(e))
             self._refresh_slideshow(driveid, item_driveid, item_id, path,
                                     None, wait_for_slideshow)
     else:
         Logger.notice(
             'Slideshow is not running anymore or abort requested.')
Exemplo n.º 32
0
 def onInit(self):
     import pyqrcode
     self._image_path = os.path.join(
         Utils.unicode(
             KodiUtils.translate_path(
                 KodiUtils.get_addon_info(
                     "profile", "script.module.clouddrive.common"))),
         "qr.png")
     qrcode = pyqrcode.create(self.qr_code)
     qrcode.png(self._image_path, scale=10)
     del qrcode
     self.getControl(self._heading_control).setLabel(self.heading)
     self.getControl(self._qr_control).setImage(self._image_path)
     self.update(self.percent, self.line1, self.line2, self.line3)
Exemplo n.º 33
0
 def create_strm(driveid, item, file_path, content_type, addon_url):
     item_id = Utils.str(item['id'])
     item_drive_id = Utils.default(Utils.get_safe_value(item, 'drive_id'),
                                   driveid)
     f = None
     try:
         f = KodiUtils.file(file_path, 'w')
         content = addon_url + '?' + urllib.urlencode({
             'action': 'play',
             'content_type': content_type,
             'item_driveid': item_drive_id,
             'item_id': item_id,
             'driveid': driveid
         })
         if item['name_extension'] == 'strm':
             content = Request(item['download_info']['url'], None).request()
         f.write(content)
     except:
         return False
     finally:
         if f:
             f.close()
     return True
Exemplo n.º 34
0
 def search(self, query, driveid, item_driveid=None, item_id=None, on_items_page_completed=None):
     self._provider.configure(self._account_manager, driveid)
     item_driveid = Utils.default(item_driveid, driveid)
     url = '/drives/'
     if item_id:
         url += item_driveid+'/items/' + item_id
     else:
         url += driveid
     url += '/search(q=\''+urllib.quote(query)+'\')'
     self._extra_parameters['filter'] = 'file ne null'
     files = self._provider.get(url, parameters = self._extra_parameters)
     if self.cancel_operation():
         return
     return self.process_files(driveid, files, on_items_page_completed)
Exemplo n.º 35
0
 def process_path(self, addon_name, drive_name, path):
     headers = {}
     response = Utils.get_file_buffer()
     driveid = self.get_driveid(drive_name)
     if driveid:
         parts = self.path.split('/')
         filename = parts[len(parts) - 1]
         if filename:
             response_code = 303
             if path:
                 u = urlparse(path)
                 path = u.path
                 Logger.debug('query: %s' % u.query)
                 if u.query == 'subtitles':
                     response_code = 200
                     response.write(
                         json.dumps({
                             'driveid':
                             driveid,
                             'subtitles':
                             self.get_subtitles(driveid, path)
                         }))
                 else:
                     key = '%s%s:children' % (
                         driveid,
                         path[0:path.rfind('/')],
                     )
                     Logger.debug('reading cache key: ' + key)
                     children = self._children_cache.get(key)
                     if not children and type(children) is NoneType:
                         self.get_folder_items(driveid,
                                               path[0:path.rfind('/') + 1])
                     url = self.get_download_url(driveid, path)
                     headers['location'] = url
                     Logger.debug('redirect to: ' + url)
             else:
                 url = self.path + '/'
                 headers['location'] = url
         else:
             response_code = 200
             response.write(str(self.show_folder(driveid, path)))
     else:
         response_code = 404
         response.write('Drive "%s" does not exist for addon "%s"' %
                        (drive_name, addon_name))
     return {
         'response_code': response_code,
         'content': response,
         'headers': headers
     }
Exemplo n.º 36
0
 def __export_folder(self, driveid, folder, export_folder, export,
                     items_info):
     folder_id = Utils.str(folder['id'])
     folder_name = Utils.unicode(folder['name'])
     folder_path = os.path.join(os.path.join(export_folder, folder_name),
                                '')
     if not xbmcvfs.exists(folder_path):
         try:
             xbmcvfs.mkdirs(folder_path)
         except:
             if self._system_monitor.waitForAbort(3):
                 return
             xbmcvfs.mkdirs(folder_path)
     items = self.get_provider().get_folder_items(
         Utils.default(Utils.get_safe_value(folder, 'drive_id'), driveid),
         folder['id'])
     if self.cancel_operation():
         return
     for item in items:
         if 'folder' in item:
             if self._child_count_supported:
                 self._exporting_target += int(
                     item['folder']['child_count'])
             else:
                 self._exporting_target += 1
     for item in items:
         is_folder = 'folder' in item
         item_id = Utils.str(item['id'])
         item_name = Utils.unicode(item['name'])
         item_name_extension = item['name_extension']
         file_path = os.path.join(folder_path, item_name)
         if is_folder:
             ExportManager.add_item_info(items_info, item_id, item_name,
                                         os.path.join(file_path, ''),
                                         folder_id)
             self.__export_folder(driveid, item, folder_path, export,
                                  items_info)
         elif (('video' in item
                or item_name_extension in self._video_file_extensions)
               and export['content_type'] == 'video') or (
                   'audio' in item and export['content_type'] == 'audio'):
             item_name += ExportManager._strm_extension
             file_path += ExportManager._strm_extension
             ExportManager.create_strm(driveid, item, file_path,
                                       export['content_type'],
                                       self._addon_url)
             ExportManager.add_item_info(items_info, item_id, item_name,
                                         file_path, folder_id)
         self._exporting_count += 1
         p = int(self._exporting_count / float(self._exporting_target) *
                 100)
         if self._exporting_percent < p:
             self._exporting_percent = p
         self._export_progress_dialog_bg.update(
             self._exporting_percent, self._addon_name + ' ' +
             self._common_addon.getLocalizedString(32024),
             file_path[len(export['destination_folder']):])
Exemplo n.º 37
0
 def process_files(self, driveid, files, on_items_page_completed=None):
     items = []
     for f in files['value']:
         f = Utils.get_safe_value(f, 'remoteItem', f)
         item = self._extract_item(f)
         cache_key = self._addonid+'-drive-'+driveid+'-item_driveid-'+item['drive_id']+'-item_id-'+item['id']+'-path-None'
         self._cache.set(cache_key, f, expiration=datetime.timedelta(minutes=1))
         items.append(item)
     if on_items_page_completed:
         on_items_page_completed(items)
     if '@odata.nextLink' in files:
         next_files = self._provider.get(files['@odata.nextLink'])
         if self.cancel_operation():
             return
         items.extend(self.process_files(driveid, next_files, on_items_page_completed))
     return items
Exemplo n.º 38
0
 def get_folder_items(self, driveid, item_driveid=None, item_id=None, path=None, on_items_page_completed=None):
     self._provider.configure(self._account_manager, driveid)
     item_driveid = Utils.default(item_driveid, driveid)
     if item_id:
         files = self._provider.get('/drives/'+item_driveid+'/items/' + item_id + '/children', parameters = self._extra_parameters)
     elif path == 'sharedWithMe' or path == 'recent':
         files = self._provider.get('/drives/'+driveid+'/' + path)
     else:
         if path == '/':
             path = 'root'
         else:
             parts = path.split('/')
             if len(parts) > 1 and not parts[0]:
                 path = 'root:'+path+':'
         files = self._provider.get('/drives/'+driveid+'/' + path + '/children', parameters = self._extra_parameters)
     if self.cancel_operation():
         return
     return self.process_files(driveid, files, on_items_page_completed)
Exemplo n.º 39
0
 def get_folder_items(self, driveid, item_driveid=None, item_id=None, path=None, on_items_page_completed=None):
     self._provider.configure(self._account_manager, driveid)
     item_driveid = Utils.default(item_driveid, driveid)
     self._parameters['fields'] = 'files(%s),nextPageToken' % self._file_fileds
     if item_id:
         self._parameters['q'] = '\'%s\' in parents' % item_id
     elif path == 'sharedWithMe' or path == 'starred':
         self._parameters['q'] = path
     elif path == 'photos':
         self._parameters['spaces'] = path
     else:
         if path == '/':
             self._parameters['q'] = '\'root\' in parents'
         else:
             item = self.get_item_by_path(path)
             self._parameters['q'] = '\'%s\' in parents' % item['id']
     files = self._provider.get('/files', parameters = self._parameters)
     if self.cancel_operation():
         return
     return self.process_files(driveid, files, on_items_page_completed)
Exemplo n.º 40
0
 def new_change_token_slideshow(self, change_token, driveid, item_driveid=None, item_id=None, path=None):
     self._provider.configure(self._account_manager, driveid)
     if not change_token:
         response = self._provider.get('/changes/startPageToken', parameters = self._parameters)
         self._change_token = Utils.get_safe_value(response, 'startPageToken')
         change_token = 1
     else:
         page_token = self._change_token
         while page_token:
             self._parameters['pageToken'] = page_token
             self._parameters['fields'] = 'nextPageToken,newStartPageToken,changes(file(id,name,parents))'
             response = self._provider.get('/changes', parameters = self._parameters)
             if self.cancel_operation():
                 return
             self._change_token = Utils.get_safe_value(response, 'newStartPageToken', self._change_token)
             changes = Utils.get_safe_value(response, 'changes', [])
             for change in changes:
                 f = Utils.get_safe_value(change, 'file', {})
                 parents = Utils.get_safe_value(f, 'parents', [])
                 parents.append(f['id'])
                 if item_id in parents:
                     return change_token + 1
             page_token = Utils.get_safe_value(response, 'nextPageToken')
     return change_token
Exemplo n.º 41
0
 def _extract_item(self, f, include_download_info=False):
     item = {
         'id': f['id'],
         'name': f['name'],
         'name_extension' : Utils.get_extension(f['name']),
         'drive_id' : Utils.get_safe_value(Utils.get_safe_value(f, 'parentReference', {}), 'driveId'),
         'mimetype' : Utils.get_safe_value(Utils.get_safe_value(f, 'file', {}), 'mimeType'),
         'last_modified_date' : Utils.get_safe_value(f,'lastModifiedDateTime'),
         'size': Utils.get_safe_value(f, 'size', 0),
         'description': Utils.get_safe_value(f, 'description', '')
     }
     if 'folder' in f:
         item['folder'] = {
             'child_count' : Utils.get_safe_value(f['folder'],'childCount',0)
         }
     if 'video' in f:
         video = f['video']
         item['video'] = {
             'width' : Utils.get_safe_value(video,'width', 0),
             'height' : Utils.get_safe_value(video, 'height', 0),
             'duration' : Utils.get_safe_value(video, 'duration', 0) /1000
         }
     if 'audio' in f:
         audio = f['audio']
         item['audio'] = {
             'tracknumber' : Utils.get_safe_value(audio, 'track'),
             'discnumber' : Utils.get_safe_value(audio, 'disc'),
             'duration' : int(Utils.get_safe_value(audio, 'duration') or '0') / 1000,
             'year' : Utils.get_safe_value(audio, 'year'),
             'genre' : Utils.get_safe_value(audio, 'genre'),
             'album': Utils.get_safe_value(audio, 'album'),
             'artist': Utils.get_safe_value(audio, 'artist'),
             'title': Utils.get_safe_value(audio, 'title')
         }
     if 'image' in f or 'photo' in f:
         item['image'] = {
             'size' : Utils.get_safe_value(f, 'size', 0)
         }
     if 'thumbnails' in f and type(f['thumbnails']) == list and len(f['thumbnails']) > 0:
         thumbnails = f['thumbnails'][0]
         item['thumbnail'] = Utils.get_safe_value(Utils.get_safe_value(thumbnails, 'large', {}), 'url', '')
     if include_download_info:
         item['download_info'] =  {
             'url' : Utils.get_safe_value(f,'@microsoft.graph.downloadUrl')
         }
     return item
Exemplo n.º 42
0
 def _rename_action(self):
     self._action = Utils.get_safe_value({
         'open_folder': '_list_folder',
         'open_drive': '_list_drive',
     }, self._action, self._action)
Exemplo n.º 43
0
 def _extract_item(self, f, include_download_info=False):
     size = long('%s' % Utils.get_safe_value(f, 'size', 0))
     item = {
         'id': f['id'],
         'name': f['name'],
         'name_extension' : Utils.get_extension(f['name']),
         'drive_id' : Utils.get_safe_value(Utils.get_safe_value(f, 'owners', [{}])[0], 'permissionId'),
         'mimetype' : Utils.get_safe_value(f, 'mimeType', ''),
         'last_modified_date' : Utils.get_safe_value(f,'modifiedTime'),
         'size': size,
         'description': Utils.get_safe_value(f, 'description', '')
     }
     if item['mimetype'] == 'application/vnd.google-apps.folder':
         item['folder'] = {
             'child_count' : 0
         }
     if 'videoMediaMetadata' in f:
         video = f['videoMediaMetadata']
         item['video'] = {
             'width' : Utils.get_safe_value(video, 'width'),
             'height' : Utils.get_safe_value(video, 'height'),
             'duration' : long('%s' % Utils.get_safe_value(video, 'durationMillis', 0)) / 1000
         }
     if 'imageMediaMetadata' in f:
         item['image'] = {
             'size' : size
         }
     if 'hasThumbnail' in f and f['hasThumbnail']:
         item['thumbnail'] = Utils.get_safe_value(f, 'thumbnailLink')
     if include_download_info:
         parameters = {
             'alt': 'media',
             'access_token': self._provider.get_access_tokens()['access_token']
         }
         url = self._provider._get_api_url() + '/files/%s' % item['id']
         if 'size' not in f and item['mimetype'] == 'application/vnd.google-apps.document':
             url += '/export'
             parameters['mimeType'] = self.get_mimetype_by_extension(item['name_extension'])
         item['download_info'] =  {
             'url' : url + '?%s' % urllib.urlencode(parameters)
         }
     return item