[plugin_installer] Refactor async download
This commit is contained in:
@@ -106,72 +106,9 @@ class PluginInstaller(GajimPlugin):
|
|||||||
' your installer plugins. Do you want to update those plugins:'
|
' your installer plugins. Do you want to update those plugins:'
|
||||||
'\n%s') % plugins_str, on_response_yes=open_update)
|
'\n%s') % plugins_str, on_response_yes=open_update)
|
||||||
|
|
||||||
def parse_manifest(self, buf):
|
|
||||||
'''
|
|
||||||
given the buffer of the zipfile, returns the list of plugin manifests
|
|
||||||
'''
|
|
||||||
zip_file = zipfile.ZipFile(buf)
|
|
||||||
manifest_list = zip_file.namelist()
|
|
||||||
plugins = []
|
|
||||||
for filename in manifest_list:
|
|
||||||
config = configparser.ConfigParser()
|
|
||||||
conf_file = zip_file.open(filename)
|
|
||||||
config.read_file(io.TextIOWrapper(conf_file, encoding='utf-8'))
|
|
||||||
conf_file.close()
|
|
||||||
if not config.has_section('info'):
|
|
||||||
continue
|
|
||||||
plugins.append(config)
|
|
||||||
return plugins
|
|
||||||
|
|
||||||
def retrieve_path(self, directory, fname):
|
|
||||||
print('retrive path')
|
|
||||||
server = self.config['http_server']
|
|
||||||
if not server:
|
|
||||||
server = self.config_default_values['http_server'][0]
|
|
||||||
if not urlparse(server).scheme:
|
|
||||||
server = 'https://' + server
|
|
||||||
if urlparse(server).scheme != 'https':
|
|
||||||
log.warn('Warning: not using HTTPS is a '
|
|
||||||
'very serious security issue!')
|
|
||||||
location = posixpath.join(directory, fname)
|
|
||||||
uri = urljoin(server, location)
|
|
||||||
log.debug('Fetching {}'.format(uri))
|
|
||||||
request = urlopen(uri)
|
|
||||||
|
|
||||||
manifest_buffer = io.BytesIO(request.read())
|
|
||||||
|
|
||||||
return manifest_buffer
|
|
||||||
|
|
||||||
def retrieve_manifest(self):
|
|
||||||
return self.retrieve_path(self.server_folder, 'manifests.zip')
|
|
||||||
|
|
||||||
@log_calls('PluginInstallerPlugin')
|
|
||||||
def check_update(self):
|
def check_update(self):
|
||||||
def _run():
|
self.thread = download_async(self, check_update=True)
|
||||||
try:
|
self.thread.start()
|
||||||
to_update = []
|
|
||||||
zipbuf = self.retrieve_manifest()
|
|
||||||
plugin_manifests = self.parse_manifest(zipbuf)
|
|
||||||
for config in plugin_manifests:
|
|
||||||
opts = config.options('info')
|
|
||||||
if 'name' not in opts or 'version' not in opts or \
|
|
||||||
'description' not in opts or 'authors' not in opts or \
|
|
||||||
'homepage' not in opts:
|
|
||||||
continue
|
|
||||||
local_version = ftp.get_plugin_version(config.get(
|
|
||||||
'info', 'name'))
|
|
||||||
if local_version:
|
|
||||||
local = convert_version_to_list(local_version)
|
|
||||||
remote = convert_version_to_list(config.get('info',
|
|
||||||
'version'))
|
|
||||||
if remote > local:
|
|
||||||
to_update.append(config.get('info', 'name'))
|
|
||||||
GLib.idle_add(self.warn_update, to_update)
|
|
||||||
except Exception as e:
|
|
||||||
log.error('Ftp error when check updates: %s' % str(e), exc_info=True)
|
|
||||||
ftp = Ftp(self)
|
|
||||||
ftp.run = _run
|
|
||||||
ftp.start()
|
|
||||||
self.timeout_id = 0
|
self.timeout_id = 0
|
||||||
|
|
||||||
@log_calls('PluginInstallerPlugin')
|
@log_calls('PluginInstallerPlugin')
|
||||||
@@ -183,8 +120,8 @@ class PluginInstaller(GajimPlugin):
|
|||||||
for id_, widget in list(self.connected_ids.items()):
|
for id_, widget in list(self.connected_ids.items()):
|
||||||
widget.disconnect(id_)
|
widget.disconnect(id_)
|
||||||
del self.page_num
|
del self.page_num
|
||||||
if hasattr(self, 'ftp'):
|
if hasattr(self, 'thread'):
|
||||||
del self.ftp
|
del self.thread
|
||||||
if self.timeout_id > 0:
|
if self.timeout_id > 0:
|
||||||
GLib.source_remove(self.timeout_id)
|
GLib.source_remove(self.timeout_id)
|
||||||
self.timeout_id = 0
|
self.timeout_id = 0
|
||||||
@@ -259,8 +196,8 @@ class PluginInstaller(GajimPlugin):
|
|||||||
self.window.show_all()
|
self.window.show_all()
|
||||||
|
|
||||||
def on_win_destroy(self, widget):
|
def on_win_destroy(self, widget):
|
||||||
if hasattr(self, 'ftp'):
|
if hasattr(self, 'thread'):
|
||||||
del self.ftp
|
del self.thread
|
||||||
if hasattr(self, 'page_num'):
|
if hasattr(self, 'page_num'):
|
||||||
del self.page_num
|
del self.page_num
|
||||||
|
|
||||||
@@ -280,13 +217,11 @@ class PluginInstaller(GajimPlugin):
|
|||||||
tab_label_text = self.notebook.get_tab_label_text(self.paned)
|
tab_label_text = self.notebook.get_tab_label_text(self.paned)
|
||||||
if tab_label_text != (_('Available')):
|
if tab_label_text != (_('Available')):
|
||||||
return
|
return
|
||||||
if not hasattr(self, 'ftp'):
|
if not hasattr(self, 'thread'):
|
||||||
self.available_plugins_model.clear()
|
self.available_plugins_model.clear()
|
||||||
self.progressbar.show()
|
self.progressbar.show()
|
||||||
self.ftp = Ftp(self)
|
self.thread = download_async(self, upgrading=True)
|
||||||
self.ftp.remote_dirs = None
|
self.thread.start()
|
||||||
self.ftp.upgrading = True
|
|
||||||
self.ftp.start()
|
|
||||||
|
|
||||||
def on_install_upgrade_clicked(self, widget):
|
def on_install_upgrade_clicked(self, widget):
|
||||||
self.install_button.set_property('sensitive', False)
|
self.install_button.set_property('sensitive', False)
|
||||||
@@ -295,9 +230,8 @@ class PluginInstaller(GajimPlugin):
|
|||||||
if self.available_plugins_model[i][Column.UPGRADE]:
|
if self.available_plugins_model[i][Column.UPGRADE]:
|
||||||
dir_list.append(self.available_plugins_model[i][Column.DIR])
|
dir_list.append(self.available_plugins_model[i][Column.DIR])
|
||||||
|
|
||||||
ftp = Ftp(self)
|
self.thread = download_async(self, remote=dir_list)
|
||||||
ftp.remote_dirs = dir_list
|
self.thread.start()
|
||||||
ftp.start()
|
|
||||||
|
|
||||||
def on_some_ftp_error(self, widget, error_text):
|
def on_some_ftp_error(self, widget, error_text):
|
||||||
for i in range(len(self.available_plugins_model)):
|
for i in range(len(self.available_plugins_model)):
|
||||||
@@ -473,16 +407,17 @@ class PluginInstaller(GajimPlugin):
|
|||||||
vadjustment.set_value(0)
|
vadjustment.set_value(0)
|
||||||
|
|
||||||
|
|
||||||
class Ftp(threading.Thread):
|
class download_async(threading.Thread):
|
||||||
def __init__(self, plugin):
|
def __init__(self, plugin, remote_dirs=None,
|
||||||
super(Ftp, self).__init__()
|
upgrading=False, check_update=False):
|
||||||
|
threading.Thread.__init__(self)
|
||||||
self.plugin = plugin
|
self.plugin = plugin
|
||||||
self.window = plugin.window
|
self.window = plugin.window
|
||||||
self.progressbar = plugin.progressbar
|
self.progressbar = plugin.progressbar
|
||||||
self.model = plugin.available_plugins_model
|
self.model = plugin.available_plugins_model
|
||||||
self.remote_dirs = None
|
self.remote_dirs = remote_dirs
|
||||||
self.append_to_model = True
|
self.upgrading = upgrading
|
||||||
self.upgrading = False
|
self.check_update = check_update
|
||||||
icon = Gtk.Image()
|
icon = Gtk.Image()
|
||||||
self.def_icon = icon.render_icon(
|
self.def_icon = icon.render_icon(
|
||||||
Gtk.STOCK_PREFERENCES, Gtk.IconSize.MENU)
|
Gtk.STOCK_PREFERENCES, Gtk.IconSize.MENU)
|
||||||
@@ -501,6 +436,73 @@ class Ftp(threading.Thread):
|
|||||||
return plugin.version
|
return plugin.version
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
|
if self.check_update:
|
||||||
|
self.run_check_update()
|
||||||
|
else:
|
||||||
|
self.run_download_plugin_list()
|
||||||
|
|
||||||
|
def parse_manifest(self, buf):
|
||||||
|
'''
|
||||||
|
given the buffer of the zipfile, returns the list of plugin manifests
|
||||||
|
'''
|
||||||
|
zip_file = zipfile.ZipFile(buf)
|
||||||
|
manifest_list = zip_file.namelist()
|
||||||
|
plugins = []
|
||||||
|
for filename in manifest_list:
|
||||||
|
config = configparser.ConfigParser()
|
||||||
|
conf_file = zip_file.open(filename)
|
||||||
|
config.read_file(io.TextIOWrapper(conf_file, encoding='utf-8'))
|
||||||
|
conf_file.close()
|
||||||
|
if not config.has_section('info'):
|
||||||
|
continue
|
||||||
|
plugins.append(config)
|
||||||
|
return plugins
|
||||||
|
|
||||||
|
def retrieve_path(self, directory, fname):
|
||||||
|
server = self.plugin.config['http_server']
|
||||||
|
if not server:
|
||||||
|
server = self.plugin.config_default_values['http_server'][0]
|
||||||
|
if not urlparse(server).scheme:
|
||||||
|
server = 'https://' + server
|
||||||
|
if urlparse(server).scheme != 'https':
|
||||||
|
log.warn('Warning: not using HTTPS is a '
|
||||||
|
'very serious security issue!')
|
||||||
|
location = posixpath.join(directory, fname)
|
||||||
|
uri = urljoin(server, location)
|
||||||
|
log.debug('Fetching {}'.format(uri))
|
||||||
|
request = urlopen(uri)
|
||||||
|
|
||||||
|
manifest_buffer = io.BytesIO(request.read())
|
||||||
|
|
||||||
|
return manifest_buffer
|
||||||
|
|
||||||
|
def retrieve_manifest(self):
|
||||||
|
return self.retrieve_path(self.plugin.server_folder, 'manifests.zip')
|
||||||
|
|
||||||
|
def run_check_update(self):
|
||||||
|
try:
|
||||||
|
to_update = []
|
||||||
|
zipbuf = self.retrieve_manifest()
|
||||||
|
plugin_manifests = self.parse_manifest(zipbuf)
|
||||||
|
for config in plugin_manifests:
|
||||||
|
opts = config.options('info')
|
||||||
|
if 'name' not in opts or 'version' not in opts or \
|
||||||
|
'description' not in opts or 'authors' not in opts or \
|
||||||
|
'homepage' not in opts:
|
||||||
|
continue
|
||||||
|
local_version = self.get_plugin_version(config.get(
|
||||||
|
'info', 'name'))
|
||||||
|
if local_version:
|
||||||
|
local = convert_version_to_list(local_version)
|
||||||
|
remote = convert_version_to_list(config.get('info',
|
||||||
|
'version'))
|
||||||
|
if remote > local:
|
||||||
|
to_update.append(config.get('info', 'name'))
|
||||||
|
GLib.idle_add(self.warn_update, to_update)
|
||||||
|
except Exception as e:
|
||||||
|
log.error('Ftp error when check updates: %s' % str(e), exc_info=True)
|
||||||
|
|
||||||
|
def run_download_plugin_list(self):
|
||||||
try:
|
try:
|
||||||
GLib.idle_add(self.progressbar.set_text,
|
GLib.idle_add(self.progressbar.set_text,
|
||||||
_('Connecting to server'))
|
_('Connecting to server'))
|
||||||
@@ -508,7 +510,7 @@ class Ftp(threading.Thread):
|
|||||||
GLib.idle_add(self.progressbar.set_text,
|
GLib.idle_add(self.progressbar.set_text,
|
||||||
_('Scan files on the server'))
|
_('Scan files on the server'))
|
||||||
try:
|
try:
|
||||||
buf = self.plugin.retrieve_path(self.plugin.server_folder, 'manifests_images.zip')
|
buf = self.retrieve_path(self.plugin.server_folder, 'manifests_images.zip')
|
||||||
except:
|
except:
|
||||||
log.exception("Error fetching plugin list")
|
log.exception("Error fetching plugin list")
|
||||||
return
|
return
|
||||||
@@ -567,7 +569,6 @@ class Ftp(threading.Thread):
|
|||||||
config.get('info', 'description'),
|
config.get('info', 'description'),
|
||||||
config.get('info', 'authors'),
|
config.get('info', 'authors'),
|
||||||
config.get('info', 'homepage'), ])
|
config.get('info', 'homepage'), ])
|
||||||
self.ftp.quit()
|
|
||||||
GLib.idle_add(self.progressbar.set_fraction, 0)
|
GLib.idle_add(self.progressbar.set_fraction, 0)
|
||||||
if self.remote_dirs:
|
if self.remote_dirs:
|
||||||
self.download_plugin()
|
self.download_plugin()
|
||||||
@@ -601,7 +602,6 @@ class Ftp(threading.Thread):
|
|||||||
continue
|
continue
|
||||||
with zipfile.ZipFile(buf) as zip_file:
|
with zipfile.ZipFile(buf) as zip_file:
|
||||||
zip_file.extractall(os.path.join(local_dir, 'plugins'))
|
zip_file.extractall(os.path.join(local_dir, 'plugins'))
|
||||||
self.ftp.quit()
|
|
||||||
GLib.idle_add(self.window.emit, 'plugin_downloaded', self.remote_dirs)
|
GLib.idle_add(self.window.emit, 'plugin_downloaded', self.remote_dirs)
|
||||||
GLib.source_remove(self.pulse)
|
GLib.source_remove(self.pulse)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user