def _remove_drive(self, driveid): self._account_manager.load() account = self._account_manager.get_account_by_driveid(driveid) drive = self._account_manager.get_drive_by_driveid(driveid) if self._dialog.yesno(self._addon_name, self._common_addon.getLocalizedString(32023) % self._get_display_name(account, drive, True), None): self._account_manager.remove_drive(driveid) KodiUtils.executebuiltin('Container.Refresh')
def _run_export(self, driveid, item_id): self._export_manager = ExportManager(self._profile_path) export = self._export_manager.get_exports()[item_id] export['run_immediately'] = True self._export_manager.save_export(export) KodiUtils.show_notification( self._common_addon.getLocalizedString(32055) % '60')
def start(self): port = self.get_port() KodiUtils.set_service_port(self.name, port) self._server = BaseServer((self._interface, port), self._handler, self, self.data) Logger.notice('Service \'%s\' started in port %s' % (self.name, port)) self._server.serve_forever()
def _run_export(self, driveid, item_id=None): export_manager = ExportManager(self._account_manager._addon_data_path) export = export_manager.load()[item_id] Logger.debug('Running export:') Logger.debug(export) if Utils.get_safe_value(export, 'exporting', False): self._dialog.ok( self._addon_name, self._common_addon.getLocalizedString(32059) + ' ' + self._common_addon.getLocalizedString(32038)) else: export['exporting'] = True export_manager.save() export_folder = export['destination_folder'] if xbmcvfs.exists(export_folder): self.get_provider().configure(self._account_manager, driveid) self._export_progress_dialog_bg.create( self._addon_name + ' ' + self._common_addon.getLocalizedString(32024), self._common_addon.getLocalizedString(32025)) self._export_progress_dialog_bg.update(0) item = self.get_provider().get_item(export['item_driveid'], item_id) if self.cancel_operation(): return if self._child_count_supported: self._exporting_target = int(item['folder']['child_count']) self._exporting_target += 1 folder_name = Utils.unicode(item['name']) folder_path = os.path.join( os.path.join(export_folder, folder_name), '') if self._addon.getSetting( 'clean_folder') != 'true' or not xbmcvfs.exists( folder_path) or self._remove_folder(folder_path): self._exporting = item_id export_items_info = {} ExportManager.add_item_info(export_items_info, item_id, folder_name, folder_path, None) self.__export_folder(driveid, item, export_folder, export, export_items_info) export_manager.save_items_info(item_id, export_items_info) if Utils.get_safe_value(export, 'update_library', False) and self._content_type: database = self._content_type if database == 'audio': database = 'music' KodiUtils.update_library(database) else: error = self._common_addon.getLocalizedString( 32066) % folder_path Logger.debug(error) self._dialog.ok(self._addon_name, error) self._export_progress_dialog_bg.close() else: error = self._common_addon.getLocalizedString( 32026) % export_folder Logger.debug(error) self._dialog.ok(self._addon_name, error) export['exporting'] = False export_manager.save()
def send_report(report): if KodiUtils.get_addon_setting('report_error') == 'true': report_url = KodiUtils.get_signin_server() + '/report' t = threading.Thread(target=Request( report_url, urllib.urlencode({'stacktrace': report})).request) t.setDaemon(True) t.start()
class DownloadService(BaseServerService): name = 'download' profile_path = Utils.unicode(KodiUtils.translate_path(KodiUtils.get_addon_info('profile'))) def __init__(self, provider_class): super(DownloadService, self).__init__(provider_class) self._handler = Download
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')
def _list_exports(self, driveid): self._export_manager = ExportManager(self._profile_path) exports = self._export_manager.get_exports() listing = [] for exportid in exports: export = exports[exportid] if export['driveid'] == driveid and export[ 'content_type'] == self._content_type: item_name = Utils.unicode(export['name']) params = { 'action': '_open_export', 'content_type': self._content_type, 'driveid': driveid, 'item_driveid': export['item_driveid'], 'item_id': export['id'], 'name': urllib.parse.quote(Utils.str(item_name)) } url = self._addon_url + '?' + urllib.parse.urlencode(params) list_item = xbmcgui.ListItem(item_name) context_options = [] params['action'] = '_run_export' context_options.append((KodiUtils.localize(21479), 'RunPlugin(' + self._addon_url + '?' + urllib.parse.urlencode(params) + ')')) params['action'] = '_remove_export' context_options.append( (KodiUtils.localize(1210), 'RunPlugin(' + self._addon_url + '?' + urllib.parse.urlencode(params) + ')')) list_item.addContextMenuItems(context_options) listing.append((url, list_item, True)) xbmcplugin.addDirectoryItems(self._addon_handle, listing, len(listing)) xbmcplugin.endOfDirectory(self._addon_handle, True)
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')
def _remove_account(self, driveid): account = self._account_manager.get_by_driveid('account', driveid) if self._dialog.yesno( self._addon_name, self._common_addon.getLocalizedString(32022) % self._get_display_name(account, with_format=True)): self._account_manager.remove_account(account['id']) KodiUtils.executebuiltin('Container.Refresh')
def is_valid_export(self): if not self.dest_folder_label.getLabel(): self._dialog.ok( self._addon_name, KodiUtils.localize(32084, addon=self._common_addon) % KodiUtils.localize(32085, addon=self._common_addon)) return False return True
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
def remove_folder(folder_path, system_monitor=None): from clouddrive.common.ui.utils import KodiUtils if not KodiUtils.rmdir(folder_path, True): if not system_monitor: system_monitor=KodiUtils.get_system_monitor() if system_monitor.waitForAbort(3): return False return KodiUtils.rmdir(folder_path, True) return True
def __init__(self, addon_data_path): self._addon_data_path = addon_data_path self._config_path = os.path.join(addon_data_path, self._config_file_name) if not os.path.exists(addon_data_path): try: os.makedirs(addon_data_path) except: KodiUtils.get_system_monitor().waitForAbort(3) os.makedirs(addon_data_path)
def _open_export(self, driveid, item_driveid, item_id, name): export_dialog = ExportMainDialog.create(self._content_type, driveid, item_driveid, item_id, name, self._account_manager, self.get_provider()) export_dialog.doModal() if export_dialog.run: KodiUtils.show_notification( self._common_addon.getLocalizedString(32055) % '60')
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)
def __init__(self, request, client_address, server): self._system_monitor = KodiUtils.get_system_monitor() self._account_manager = AccountManager(server.service.profile_path) self._addonid = KodiUtils.get_addon_info('id') expiration = datetime.timedelta(minutes=KodiUtils.get_cache_expiration_time()) self._page_cache = Cache(self._addonid, 'page', expiration) self._children_cache = Cache(self._addonid, 'children', expiration) self._items_cache = Cache(self._addonid, 'items', expiration) BaseHandler.__init__(self, request, client_address, server)
def _remove_export(self, driveid, item_id): export_manager = ExportManager(self._account_manager._addon_data_path) item = export_manager.load()[item_id] if self._dialog.yesno( self._addon_name, self._common_addon.getLocalizedString(32001) % Utils.unicode(item['name']), None): export_manager.remove_export(item_id) KodiUtils.executebuiltin('Container.Refresh')
def run_export(self, export): export['exporting'] = True params = { 'action': '_run_export', 'content_type': Utils.get_safe_value(export, 'content_type', ''), 'driveid': Utils.get_safe_value(export, 'driveid', ''), 'item_id': export['id'] } KodiUtils.run_plugin(self.addonid, params, False)
def get_cloud_drive_addons(self): addons = [] addonid = KodiUtils.get_addon_info('id') response = KodiUtils.execute_json_rpc('Addons.GetAddons', {'type':'xbmc.python.pluginsource', 'enabled': True, 'properties': ['dependencies', 'name']}) for addon in Utils.get_safe_value(Utils.get_safe_value(response, 'result', {}), 'addons', []): for dependency in addon['dependencies']: if dependency['addonid'] == addonid: addons.append(addon) break return addons
def _get_item_play_url(self, file_name, driveid, item_driveid=None, item_id=None): url = None if KodiUtils.get_addon_setting('ask_stream_format') == 'false': if KodiUtils.get_addon_setting('default_stream_quality') == 'Original': url = super(GoogleDriveAddon, self)._get_item_play_url(file_name, driveid, item_driveid, item_id) else: url = self._select_stream_format(driveid, item_driveid, item_id, True) if not url: url = self._select_stream_format(driveid, item_driveid, item_id, False) return url
def _remove_export(self, driveid, item_id): self._export_manager = ExportManager(self._account_manager._addon_data_path) item = self._export_manager.load()[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')
def remove_export(self, exportid, keep_local=True): self.load() export = self.exports[exportid] path = os.path.join(export['destination_folder'], export['name'], '') if not keep_local: if KodiUtils.file_exists(path): Utils.remove_folder(path) if self.get_items_info_path(exportid): KodiUtils.file_delete(self.get_items_info_path(exportid)) del self.exports[exportid] self.save()
def track_progress(self): Logger.debug('tracking progress started...') monitor = KodiUtils.get_system_monitor() while self.isPlaying(): KodiUtils.set_home_property('dbresume_position', Utils.str(self.getTime())) KodiUtils.set_home_property('dbresume_total', Utils.str(self.getTotalTime())) if monitor.waitForAbort(1): break del monitor Logger.debug('tracking progress finished')
def _get_item_play_url(self, file_name, driveid, item_driveid=None, item_id=None, is_subtitle=False): url = None if self._content_type == 'video' and not is_subtitle: if KodiUtils.get_addon_setting('ask_stream_format') == 'false': if KodiUtils.get_addon_setting('default_stream_quality') == 'Original': url = self._get_url_original(driveid, item_driveid, item_id) else: url = self._select_stream_format(driveid, item_driveid, item_id, True) else: url = self._select_stream_format(driveid, item_driveid, item_id, False) if not url: url = self._get_url_original(driveid, item_driveid, item_id) return url
def process_watch(self, export_map): exports = Utils.get_safe_value(export_map, 'watch', []) update_library = {} changes_by_drive = {} for export in exports: item_id = export['id'] driveid = export['driveid'] if driveid in changes_by_drive: changes = changes_by_drive[driveid] else: self.provider.configure(self._account_manager, export['driveid']) changes = self.provider.changes() changes_by_drive[driveid] = changes items_info = self.export_manager.get_items_info(item_id) if items_info: if changes and not Utils.get_safe_value( export, 'exporting', False): Logger.debug( '*** Processing changes for export "%s" in %s' % (export['name'], export['destination_folder'])) while True: changes_retry = [] changes_done = [] for change in changes: change_type = self.process_change( change, items_info, export) if change_type and change_type != 'retry': changes_done.append(change) self.export_manager.save_items_info( item_id, items_info) if Utils.get_safe_value( export, 'update_library', False): update_library[Utils.get_safe_value( export, 'content_type', 'None')] = True elif change_type and change_type == 'retry': changes_retry.append(change) for change in changes_done: changes_by_drive[driveid].remove(change) if changes_done and changes_retry: changes = changes_retry Logger.debug('Retrying pending changes...') else: break else: self.run_export(export) if update_library: if Utils.get_safe_value(update_library, 'video', False): KodiUtils.update_library('video') if Utils.get_safe_value(update_library, 'audio', False): KodiUtils.update_library('music')
def onInit(self): self.title_label = self.getControl(1000) self.cancel_button = self.getControl(1002) self.save_button = self.getControl(1003) self.schedule_type_button = self.getControl(1011) self.schedule_at_label = self.getControl(10100) self.schedule_at_button = self.getControl(1012) self.title_label.setLabel(self._common_addon.getLocalizedString(32083)) self.setFocus(self.save_button) self.setFocus(self.schedule_type_button) self.schedule_type_button.setLabel(KodiUtils.localize(self.schedule['type'], addon=self._common_addon)) self.schedule_at_button.setLabel(self.schedule['at']) self.schedule_at_label.setLabel(KodiUtils.localize(32080, addon=self._common_addon)) self.check_schedule_type()
def _get_connection(self): profile_path = KodiUtils.get_addon_info("profile", self._addonid) if not KodiUtils.file_exists(profile_path): KodiUtils.mkdirs(profile_path) db = KodiUtils.translate_path("%s/cache_%s.db" % (profile_path, self._name,)) con = sqlite3.connect(db, timeout=30, isolation_level=None) con.execute('pragma journal_mode=wal;') rs = con.execute("select name from sqlite_master where type='table' AND name='cache'") if not rs.fetchone(): try: con.execute("create table cache(key text unique, value text, expiration integer)") except Exception as ex: Logger.debug(ex) return con
def saveProgress(self): dbid = KodiUtils.get_home_property('dbid') addonid = KodiUtils.get_home_property('addonid') if addonid and addonid == self.addonid: if dbid: Logger.debug('ok to save dbid: ' + dbid) dbtype = KodiUtils.get_home_property('dbtype') position = KodiUtils.get_home_property('dbresume_position') total = KodiUtils.get_home_property('dbresume_total') if dbtype and position and total: position = float(position) total = float(total) percent = position / total * 100 details = {} Logger.debug('position is %d of %d = %d percent' % (position, total, percent)) if percent >= 90: position = 0 total = 0 details['resume'] = {'position': 0, 'total': 0} details['lastplayed'] = KodiUtils.to_db_date_str( datetime.datetime.today()) details['playcount'] = int( KodiUtils.get_home_property('playcount')) + 1 elif position > 180: details['resume'] = { 'position': position, 'total': total } if details: Logger.debug( KodiUtils.save_video_details( dbtype, dbid, details)) Logger.debug('details saved to db - %s: %s' % (dbid, Utils.str(details)))
def __export_folder(self, driveid, folder, export_folder, export, items_info, root_id): 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,'folder') self.__export_folder(driveid, item, folder_path, export, items_info, root_id) 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 if self._addon.getSetting('skip_unmodified') and KodiUtils.file_exists(file_path) and KodiUtils.file(file_path).size() == item["size"]: continue 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,'file') elif 'nfo_export' in export and export['nfo_export'] and ('nfo' in item_name_extension or 'text/x-nfo' in item.get("mimetype")): nfo_path = os.path.join(folder_path, Utils.unicode(item_name)) if self._addon.getSetting('skip_unmodified') and KodiUtils.file_exists(nfo_path) and KodiUtils.file(nfo_path).size() == item["size"]: continue ExportManager.create_nfo(item_id, export["item_driveid"], nfo_path, self.get_provider()) ExportManager.add_item_info(items_info, item_id, item_name, nfo_path, folder_id,'file') self._export_manager.save_items_info(root_id, items_info) 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']):])
def __init__(self, provider_class, handler=Source): super(SourceService, self).__init__(provider_class) self._handler = handler addonid = KodiUtils.get_addon_info('id') Cache(addonid, 'page', 0).clear() Cache(addonid, 'children', 0).clear() Cache(addonid, 'items', 0).clear()
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 def _rename_action(self): self._action = Utils.get_safe_value({ 'open_folder': '_list_folder', 'open_drive': '_list_drive', }, self._action, self._action) if __name__ == '__main__': onedrive_addon = OneDriveAddon() if not KodiUtils.get_addon_setting('migrated'): try: MigrateAccounts() except Exception as e: onedrive_addon._handle_exception(e, False) onedrive_addon.route()