def reporthook(num_blocks, block_size, file_size, dlg, start_time, filename):
    try:
        percent = min(num_blocks * block_size * 100 / file_size, 100)
        currently_downloaded = float(num_blocks) * block_size / (1024 * 1024)
        kbps_speed = num_blocks * block_size / (time.time() - start_time)
        eta = 0
        if kbps_speed > 0:
            eta = (file_size - num_blocks * block_size) / kbps_speed
            if eta < 0:
                eta = 0
        kbps_speed = kbps_speed / 1024
        eta = divmod(eta, 60)
        file_size_mb = float(file_size) / (1024 * 1024)
        status = '{:.02f} MB of {:.02f} MB '.format(currently_downloaded,
                                                    file_size_mb)
        status += '{} {:.02f} Kb/s '.format(get_local_string(30501),
                                            kbps_speed)
        status += '{} {:02d}:{:02d}'.format(get_local_string(30502),
                                            int(eta[0]), int(eta[1]))
        dlg.update(
            int(percent), '{}[CR]{}[CR]{}'.format(get_local_string(30500),
                                                  filename, status))
    except Exception as exc:
        LOG.error('[download_file] reporthook raised an error: {}', exc)
        dlg.update(100)
    if dlg.iscanceled():
        raise InterruptedError
Exemple #2
0
 def delete_task(self, pathitems=None):  # pylint: disable=unused-argument
     if not kodi_ops.dlg_confirm(kodi_ops.get_local_string(30051),
                                 kodi_ops.get_local_string(30043)):
         return
     with kodi_ops.show_busy_dialog():
         if misc.check_task():
             misc.run_manage_task('delete')
         if misc.check_task():
             # Task deletion failed
             kodi_ops.show_notification(kodi_ops.get_local_string(30047))
             return
         kodi_ops.show_notification(kodi_ops.get_local_string(30046))
def install(pathitems, params):
    LOG.info('Start install Kodi "{}" (params "{}")', pathitems[-1], params)
    use_task_scheduler = G.ADDON.getSettingBool('usetaskscheduler')
    save_downloads = G.ADDON.getSettingBool('save_downloads')
    # Download the file
    if not kodi_ops.dlg_confirm(
            kodi_ops.get_local_string(30070),
            kodi_ops.get_local_string(30071).format(pathitems[-1])):
        return
    # Check if the task is installed
    if use_task_scheduler and not misc.check_task():
        kodi_ops.dlg_ok(kodi_ops.get_local_string(30070),
                        kodi_ops.get_local_string(30072))
        return
    # Check if destination path exist
    if not folder_exists(G.INSTALLER_TEMP_PATH):
        create_folder(G.INSTALLER_TEMP_PATH)
    # Check if the setup installer is already downloaded
    dwn_filepath = join_folders_paths(G.DOWNLOADS_PATH,
                                      '/'.join(pathitems[:-1]), pathitems[-1])
    # Temp file path will be used by the Windows Task scheduled
    temp_filepath = join_folders_paths(G.INSTALLER_TEMP_PATH,
                                       G.INSTALLER_TEMP_NAME)
    if params.get('is_local', 'False') == 'True':
        # Get the file to install from "downloads" folder
        if not file_exists(dwn_filepath):
            raise FileExistsError('The file {] not exists'.format(
                pathitems[:-1]))
        copy_file(dwn_filepath, temp_filepath)
    else:
        # Download the file
        if save_downloads and file_exists(dwn_filepath):
            # Copy the existing file to the temp file path
            copy_file(dwn_filepath, temp_filepath)
        else:
            # Download the setup installer file
            url_file_path = '/'.join(pathitems)
            if not download_file(G.MIRROR_BASE_URL + url_file_path,
                                 temp_filepath, pathitems[-1]):
                # Download cancelled
                kodi_ops.show_notification(kodi_ops.get_local_string(30073))
                return
            # Save the setup installer file
            if save_downloads:
                copy_file(temp_filepath, dwn_filepath)
    with kodi_ops.show_busy_dialog():
        # Run the "AutoUpdateWorker" bash script
        _run_auto_update_worker(use_task=use_task_scheduler)
        # Wait a bit before close Kodi,
        # the bash script have to read the executable path from the Kodi process before continue
        time.sleep(2)
        kodi_ops.json_rpc('Application.Quit')
Exemple #4
0
 def add_task(self, pathitems=None):  # pylint: disable=unused-argument
     if not kodi_ops.dlg_confirm(kodi_ops.get_local_string(30050),
                                 kodi_ops.get_local_string(30042)):
         return
     with kodi_ops.show_busy_dialog():
         if misc.check_task():
             self.delete_task()
         misc.run_manage_task('create')
         if not misc.check_task():
             # Task creation failed
             kodi_ops.dlg_ok(kodi_ops.get_local_string(30050),
                             kodi_ops.get_local_string(30045))
             return
         kodi_ops.show_notification(kodi_ops.get_local_string(30044))
Exemple #5
0
 def get_git_history(self, pathitems=None):
     # Query github data
     filename = pathitems[0]
     data = _get_git_history(filename)
     # Generate list from github data
     list_items = []
     for commit_data in reversed(data['commits']):
         # Show only "Merge" commits
         if not commit_data['commit']['message'].startswith('Merge'):
             continue
         list_item = xbmcgui.ListItem(
             label=_generate_label_from_commit(commit_data), offscreen=True)
         list_item.setContentLookup(False)
         list_items.append(list_item)
     # Show dialog
     index = 0
     while index != -1:
         # Show "Merged PR's of: ..." dialog
         index = xbmcgui.Dialog().select(
             kodi_ops.get_local_string(30081).format(filename),
             list_items,
             preselect=index)
         if not index == -1:
             # Get PR number
             pr_number = re.findall(r'#(\d+)', list_items[index].getLabel())
             xbmcgui.Dialog().textviewer(list_items[index].getLabel(),
                                         _get_pr_details(pr_number))
 def subfolder(self, pathitems=None):
     G.FILES_LIST.clear()
     add_github_menu = 'master' in pathitems and 'nightlies' in pathitems and not self.is_local(
     )
     folder_list = []
     file_list = []
     if self.is_local():
         current_path = G.DOWNLOADS_PATH + '\\'.join(pathitems)
         for item in os.listdir(current_path):
             if os.path.isfile(os.path.join(current_path, item)):
                 file_list.append(item)
             else:
                 folder_list.append(item)
     else:
         url = G.MIRROR_BASE_URL + '/'.join(pathitems) + '/'
         from urllib.request import Request, urlopen
         page_response = urlopen(Request(url), timeout=10).read()
         # Find the folders in the webpage
         folder_list = re.findall(r'href="([^\/"\.]+)\/"',
                                  page_response.decode())
         # Find the executables names in the webpage
         file_list = re.findall(r'href="([^"]*\.exe)"',
                                page_response.decode())
     directory_items = []
     # Create the directory items
     for folder_name in folder_list:
         pathitems_value = ['subfolder'] + pathitems + [folder_name]
         directory_items.append(
             create_listitem(pathitems_value,
                             is_folder=True,
                             label=folder_name,
                             is_local=self.is_local()))
     # Create the directory file items
     for filename in file_list:
         # Memorize filename in to globals, allow to find other info from items for github operations
         G.FILES_LIST.append(filename)
         pathitems_value = pathitems + [filename]
         if add_github_menu:
             # Add "View github history" menu
             menu_item = [(kodi_ops.get_local_string(30080),
                           kodi_ops.run_plugin_action(
                               build_url(['get_git_history', filename],
                                         mode=G.MODE_ACTION)))]
         else:
             menu_item = None
         directory_items.append(
             create_listitem(pathitems_value,
                             is_folder=False,
                             label=filename,
                             menu_items=menu_item,
                             is_local=self.is_local(),
                             art_thumb='DefaultAddon.png'))
     title = ARCHITECTURES.get(pathitems[-1], pathitems[-1])
     finalize_directory(directory_items, title=title)
     end_of_directory(False)
def download_file(url, dest_path, filename):
    start_time = time.time()
    dlg = xbmcgui.DialogProgress()
    dlg.create(G.ADDON_ID, get_local_string(30499))
    try:
        urlretrieve(
            url.rstrip('/'), dest_path,
            lambda num_blocks, block_size, file_size: reporthook(
                num_blocks, block_size, file_size, dlg, start_time, filename))
        return True
    except InterruptedError:
        LOG.error('Download interrupted by user')
    except Exception as exc:
        LOG.error('Download failed due to an error: {}', exc)
        raise Exception('Download failed') from exc
    finally:
        dlg.close()
    return False
def run(argv):
    # Initialize globals right away to avoid stale values from the last addon invocation.
    # Otherwise Kodi's reuseLanguageInvoker will cause some really quirky behavior!
    # PR: https://github.com/xbmc/xbmc/pull/13814
    G.init_globals(argv)
    LOG.info('Started (Version {})'.format(G.VERSION_RAW))
    LOG.info('URL is {}'.format(G.URL))
    success = False
    try:
        pathitems = [part for part in G.REQUEST_PATH.split('/') if part]
        success = route(pathitems)
    except Exception as exc:
        import traceback
        LOG.error(traceback.format_exc())
        kodi_ops.dlg_ok(
            'AutoUpdateKodi',
            kodi_ops.get_local_string(30700).format('[{}] {}'.format(
                exc.__class__.__name__, exc)))
    if not success:
        from xbmcplugin import endOfDirectory
        endOfDirectory(handle=G.PLUGIN_HANDLE, succeeded=False)
    LOG.log_time_trace()
Exemple #9
0
 def delete_downloads(self, pathitems=None):  # pylint: disable=unused-argument
     if kodi_ops.dlg_confirm(kodi_ops.get_local_string(30074),
                             kodi_ops.get_local_string(30075)):
         with kodi_ops.show_busy_dialog():
             delete_folder_contents(G.DOWNLOADS_PATH,
                                    delete_subfolders=True)
Exemple #10
0
 def show_notification_disconnected(**kwargs):
     kodi_ops.show_notification(
         kodi_ops.get_local_string(32001).format(**kwargs))