[plugin_installer] Refactor manifest parsing
This commit is contained in:
@@ -29,11 +29,11 @@ import threading
|
|||||||
import configparser
|
import configparser
|
||||||
import os
|
import os
|
||||||
import ssl
|
import ssl
|
||||||
import zipfile
|
|
||||||
import logging
|
import logging
|
||||||
import posixpath
|
import posixpath
|
||||||
import urllib.error
|
import urllib.error
|
||||||
|
|
||||||
|
from zipfile import ZipFile
|
||||||
from distutils.version import LooseVersion as V
|
from distutils.version import LooseVersion as V
|
||||||
from urllib.request import urlopen
|
from urllib.request import urlopen
|
||||||
from common import gajim
|
from common import gajim
|
||||||
@@ -64,7 +64,7 @@ class Column(IntEnum):
|
|||||||
HOMEPAGE = 8
|
HOMEPAGE = 8
|
||||||
|
|
||||||
|
|
||||||
def get_plugin_version(plugin_name):
|
def get_local_version(plugin_name):
|
||||||
for plugin in gajim.plugin_manager.plugins:
|
for plugin in gajim.plugin_manager.plugins:
|
||||||
if plugin.name == plugin_name:
|
if plugin.name == plugin_name:
|
||||||
return plugin.version
|
return plugin.version
|
||||||
@@ -347,7 +347,12 @@ class DownloadAsync(threading.Thread):
|
|||||||
Gtk.STOCK_PREFERENCES, Gtk.IconSize.MENU)
|
Gtk.STOCK_PREFERENCES, Gtk.IconSize.MENU)
|
||||||
|
|
||||||
def model_append(self, row):
|
def model_append(self, row):
|
||||||
self.model.append(row)
|
row_data = [
|
||||||
|
row['icon'], row['remote_dir'], row['name'], row['local_version'],
|
||||||
|
row['version'], row['upgrade'], row['description'], row['authors'],
|
||||||
|
row['homepage']
|
||||||
|
]
|
||||||
|
self.model.append(row_data)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def progressbar_pulse(self):
|
def progressbar_pulse(self):
|
||||||
@@ -381,17 +386,48 @@ class DownloadAsync(threading.Thread):
|
|||||||
'''
|
'''
|
||||||
given the buffer of the zipfile, returns the list of plugin manifests
|
given the buffer of the zipfile, returns the list of plugin manifests
|
||||||
'''
|
'''
|
||||||
zip_file = zipfile.ZipFile(buf)
|
zip_file = ZipFile(buf)
|
||||||
manifest_list = zip_file.namelist()
|
manifest_list = zip_file.namelist()
|
||||||
plugins = []
|
plugins = []
|
||||||
for filename in manifest_list:
|
for filename in manifest_list:
|
||||||
|
# Parse manifest
|
||||||
|
if not filename.endswith('manifest.ini'):
|
||||||
|
continue
|
||||||
config = configparser.ConfigParser()
|
config = configparser.ConfigParser()
|
||||||
conf_file = zip_file.open(filename)
|
conf_file = zip_file.open(filename)
|
||||||
config.read_file(io.TextIOWrapper(conf_file, encoding='utf-8'))
|
config.read_file(io.TextIOWrapper(conf_file, encoding='utf-8'))
|
||||||
conf_file.close()
|
conf_file.close()
|
||||||
if not config.has_section('info'):
|
if not config.has_section('info'):
|
||||||
|
log.warn('Plugin is missing INFO section in manifest.ini. '
|
||||||
|
'Plugin not loaded.')
|
||||||
continue
|
continue
|
||||||
plugins.append(config)
|
opts = config.options('info')
|
||||||
|
if not set(MANDATORY_FIELDS).issubset(opts):
|
||||||
|
log.warn('Plugin is missing mandatory fields in manifest.ini. '
|
||||||
|
'Plugin not loaded.')
|
||||||
|
continue
|
||||||
|
# Add icon and remote dir
|
||||||
|
icon = None
|
||||||
|
remote_dir = filename.split('/')[0]
|
||||||
|
png_filename = '{0}/{0}.png'.format(remote_dir)
|
||||||
|
icon = self.def_icon
|
||||||
|
if png_filename in manifest_list:
|
||||||
|
data = zip_file.open(png_filename).read()
|
||||||
|
pix = GdkPixbuf.PixbufLoader()
|
||||||
|
pix.set_size(16, 16)
|
||||||
|
pix.write(data)
|
||||||
|
pix.close()
|
||||||
|
icon = pix.get_pixbuf()
|
||||||
|
|
||||||
|
# transform to dictonary
|
||||||
|
config_dict = {}
|
||||||
|
for key, value in config.items('info'):
|
||||||
|
config_dict[key] = value
|
||||||
|
config_dict['icon'] = icon
|
||||||
|
config_dict['remote_dir'] = remote_dir
|
||||||
|
config_dict['upgrade'] = False
|
||||||
|
|
||||||
|
plugins.append(config_dict)
|
||||||
return plugins
|
return plugins
|
||||||
|
|
||||||
def download_url(self, url):
|
def download_url(self, url):
|
||||||
@@ -418,64 +454,28 @@ class DownloadAsync(threading.Thread):
|
|||||||
def run_check_update(self):
|
def run_check_update(self):
|
||||||
to_update = []
|
to_update = []
|
||||||
zipbuf = self.download_url(MANIFEST_URL)
|
zipbuf = self.download_url(MANIFEST_URL)
|
||||||
plugin_manifests = self.parse_manifest(zipbuf)
|
plugin_list = self.parse_manifest(zipbuf)
|
||||||
for config in plugin_manifests:
|
for plugin in plugin_list:
|
||||||
opts = config.options('info')
|
local_version = get_local_version(plugin['name'])
|
||||||
if not set(MANDATORY_FIELDS).issubset(opts):
|
|
||||||
continue
|
|
||||||
local_version = get_plugin_version(config.get(
|
|
||||||
'info', 'name'))
|
|
||||||
if local_version:
|
if local_version:
|
||||||
if V(config.get('info', 'version')) > V(local_version):
|
if V(plugin['version']) > V(local_version):
|
||||||
to_update.append(config.get('info', 'name'))
|
to_update.append(plugin['name'])
|
||||||
GLib.idle_add(self.plugin.warn_update, to_update)
|
GLib.idle_add(self.plugin.warn_update, to_update)
|
||||||
|
|
||||||
def run_download_plugin_list(self):
|
def run_download_plugin_list(self):
|
||||||
if not self.remote_dirs:
|
if not self.remote_dirs:
|
||||||
log.info('Downloading Pluginlist...')
|
log.info('Downloading Pluginlist...')
|
||||||
buf = self.download_url(MANIFEST_IMAGE_URL)
|
zipbuf = self.download_url(MANIFEST_IMAGE_URL)
|
||||||
zip_file = zipfile.ZipFile(buf)
|
plugin_list = self.parse_manifest(zipbuf)
|
||||||
manifest_list = zip_file.namelist()
|
for plugin in plugin_list:
|
||||||
for filename in manifest_list:
|
plugin['local_version'] = get_local_version(plugin['name'])
|
||||||
if not filename.endswith('manifest.ini'):
|
if self.upgrading and plugin['local_version']:
|
||||||
continue
|
if V(plugin['version']) > V(plugin['local_version']):
|
||||||
dir_ = filename.split('/')[0]
|
plugin['upgrade'] = True
|
||||||
config = configparser.ConfigParser()
|
|
||||||
conf_file = zip_file.open(filename)
|
|
||||||
config.read_file(io.TextIOWrapper(conf_file, encoding='utf-8'))
|
|
||||||
conf_file.close()
|
|
||||||
opts = config.options('info')
|
|
||||||
if not set(MANDATORY_FIELDS).issubset(opts):
|
|
||||||
continue
|
|
||||||
|
|
||||||
local_version = get_plugin_version(
|
|
||||||
config.get('info', 'name'))
|
|
||||||
upgrade = False
|
|
||||||
if self.upgrading and local_version:
|
|
||||||
if V(config.get('info', 'version')) > V(local_version):
|
|
||||||
upgrade = True
|
|
||||||
GLib.idle_add(
|
GLib.idle_add(
|
||||||
self.plugin.install_button.set_property,
|
self.plugin.install_button.set_property,
|
||||||
'sensitive', True)
|
'sensitive', True)
|
||||||
png_filename = dir_ + '/' + dir_ + '.png'
|
GLib.idle_add(self.model_append, plugin)
|
||||||
if png_filename in manifest_list:
|
|
||||||
data = zip_file.open(png_filename).read()
|
|
||||||
pbl = GdkPixbuf.PixbufLoader()
|
|
||||||
pbl.set_size(16, 16)
|
|
||||||
pbl.write(data)
|
|
||||||
pbl.close()
|
|
||||||
def_icon = pbl.get_pixbuf()
|
|
||||||
else:
|
|
||||||
def_icon = self.def_icon
|
|
||||||
if local_version:
|
|
||||||
base_dir, user_dir = gajim.PLUGINS_DIRS
|
|
||||||
local_dir = os.path.join(user_dir, dir_)
|
|
||||||
GLib.idle_add(self.model_append, [def_icon, dir_,
|
|
||||||
config.get('info', 'name'), local_version,
|
|
||||||
config.get('info', 'version'), upgrade,
|
|
||||||
config.get('info', 'description'),
|
|
||||||
config.get('info', 'authors'),
|
|
||||||
config.get('info', 'homepage'), ])
|
|
||||||
GLib.idle_add(self.plugin.select_root_iter)
|
GLib.idle_add(self.plugin.select_root_iter)
|
||||||
else:
|
else:
|
||||||
self.download_plugin()
|
self.download_plugin()
|
||||||
@@ -499,7 +499,7 @@ class DownloadAsync(threading.Thread):
|
|||||||
except:
|
except:
|
||||||
log.exception("Error downloading plugin %s" % filename)
|
log.exception("Error downloading plugin %s" % filename)
|
||||||
continue
|
continue
|
||||||
with zipfile.ZipFile(buf) as zip_file:
|
with ZipFile(buf) as zip_file:
|
||||||
zip_file.extractall(os.path.join(local_dir, 'plugins'))
|
zip_file.extractall(os.path.join(local_dir, 'plugins'))
|
||||||
GLib.idle_add(self.plugin.on_plugin_downloaded, self.remote_dirs)
|
GLib.idle_add(self.plugin.on_plugin_downloaded, self.remote_dirs)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user