Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
gajim
gajim-plugins
Commits
3db0e1fe
Commit
3db0e1fe
authored
Apr 29, 2022
by
Philipp Hörist
Browse files
[plugin_installer] Remove plugin
This is integrated into Gajim now
parent
d7b9b099
Changes
9
Hide whitespace changes
Inline
Side-by-side
plugin_installer/__init__.py
deleted
100644 → 0
View file @
d7b9b099
from
.plugin_installer
import
PluginInstaller
plugin_installer/config_dialog.py
deleted
100644 → 0
View file @
d7b9b099
# This file is part of Gajim.
#
# Gajim is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Gajim is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Gajim. If not, see <http://www.gnu.org/licenses/>.
from
gi.repository
import
Gtk
from
gajim.gui.settings
import
SettingsDialog
from
gajim.gui.const
import
Setting
from
gajim.gui.const
import
SettingKind
from
gajim.gui.const
import
SettingType
from
gajim.plugins.plugins_i18n
import
_
class
PluginInstallerConfigDialog
(
SettingsDialog
):
def
__init__
(
self
,
plugin
,
parent
):
self
.
plugin
=
plugin
settings
=
[
Setting
(
SettingKind
.
SWITCH
,
_
(
'Check for updates'
),
SettingType
.
VALUE
,
self
.
plugin
.
config
[
'check_update'
],
desc
=
_
(
'Check for updates after start'
),
callback
=
self
.
on_setting
,
data
=
'check_update'
),
Setting
(
SettingKind
.
SWITCH
,
_
(
'Update automatically'
),
SettingType
.
VALUE
,
self
.
plugin
.
config
[
'auto_update'
],
desc
=
_
(
'Update plugins automatically'
),
callback
=
self
.
on_setting
,
data
=
'auto_update'
),
Setting
(
SettingKind
.
SWITCH
,
_
(
'Notify after update'
),
SettingType
.
VALUE
,
self
.
plugin
.
config
[
'auto_update_feedback'
],
desc
=
_
(
'Show message when automatic update was successful'
),
callback
=
self
.
on_setting
,
data
=
'auto_update_feedback'
),
]
SettingsDialog
.
__init__
(
self
,
parent
,
_
(
'Plugin Installer Configuration'
),
Gtk
.
DialogFlags
.
MODAL
,
settings
,
None
)
def
on_setting
(
self
,
value
,
data
):
self
.
plugin
.
config
[
data
]
=
value
plugin_installer/installer.ui
deleted
100644 → 0
View file @
d7b9b099
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.38.2 -->
<interface>
<requires
lib=
"gtk+"
version=
"3.20"
/>
<object
class=
"GtkListStore"
id=
"plugin_store"
>
<columns>
<!-- column-name icon -->
<column
type=
"GdkPixbuf"
/>
<!-- column-name name -->
<column
type=
"gchararray"
/>
<!-- column-name localversion -->
<column
type=
"gchararray"
/>
<!-- column-name version -->
<column
type=
"gchararray"
/>
<!-- column-name upgrade -->
<column
type=
"gboolean"
/>
<!-- column-name plugin -->
<column
type=
"PyObject"
/>
</columns>
</object>
<object
class=
"GtkBox"
id=
"available_plugins_box"
>
<property
name=
"visible"
>
True
</property>
<property
name=
"can-focus"
>
False
</property>
<property
name=
"border-width"
>
18
</property>
<property
name=
"spacing"
>
18
</property>
<child>
<object
class=
"GtkOverlay"
>
<property
name=
"visible"
>
True
</property>
<property
name=
"can-focus"
>
False
</property>
<child>
<object
class=
"GtkBox"
id=
"plugins_box"
>
<property
name=
"width-request"
>
180
</property>
<property
name=
"visible"
>
True
</property>
<property
name=
"can-focus"
>
False
</property>
<property
name=
"hexpand"
>
True
</property>
<property
name=
"orientation"
>
vertical
</property>
<child>
<object
class=
"GtkScrolledWindow"
id=
"scrolledwindow"
>
<property
name=
"visible"
>
True
</property>
<property
name=
"can-focus"
>
True
</property>
<property
name=
"hscrollbar-policy"
>
never
</property>
<property
name=
"shadow-type"
>
out
</property>
<child>
<object
class=
"GtkTreeView"
id=
"available_plugins_treeview"
>
<property
name=
"visible"
>
True
</property>
<property
name=
"can-focus"
>
True
</property>
<property
name=
"model"
>
plugin_store
</property>
<property
name=
"search-column"
>
2
</property>
<child
internal-child=
"selection"
>
<object
class=
"GtkTreeSelection"
id=
"treeview-selection"
>
<signal
name=
"changed"
handler=
"_on_plugin_selection_changed"
swapped=
"no"
/>
</object>
</child>
<child>
<object
class=
"GtkTreeViewColumn"
>
<property
name=
"resizable"
>
True
</property>
<property
name=
"sizing"
>
fixed
</property>
<property
name=
"fixed-width"
>
180
</property>
<property
name=
"min-width"
>
150
</property>
<property
name=
"max-width"
>
300
</property>
<property
name=
"title"
translatable=
"yes"
>
Plugin
</property>
<property
name=
"clickable"
>
True
</property>
<property
name=
"sort-indicator"
>
True
</property>
<property
name=
"sort-column-id"
>
1
</property>
<child>
<object
class=
"GtkCellRendererPixbuf"
id=
"pixbufrenderer"
/>
<attributes>
<attribute
name=
"pixbuf"
>
0
</attribute>
</attributes>
</child>
<child>
<object
class=
"GtkCellRendererText"
id=
"plugintextrenderer"
>
<property
name=
"ellipsize"
>
end
</property>
</object>
<attributes>
<attribute
name=
"text"
>
1
</attribute>
</attributes>
</child>
</object>
</child>
<child>
<object
class=
"GtkTreeViewColumn"
>
<property
name=
"title"
translatable=
"yes"
>
Installed
</property>
<child>
<object
class=
"GtkCellRendererText"
id=
"versiontextrenderer"
/>
<attributes>
<attribute
name=
"text"
>
2
</attribute>
</attributes>
</child>
</object>
</child>
<child>
<object
class=
"GtkTreeViewColumn"
>
<property
name=
"title"
translatable=
"yes"
>
Available
</property>
<child>
<object
class=
"GtkCellRendererText"
id=
"availabletextrenderer"
/>
<attributes>
<attribute
name=
"text"
>
3
</attribute>
</attributes>
</child>
</object>
</child>
<child>
<object
class=
"GtkTreeViewColumn"
>
<property
name=
"title"
translatable=
"yes"
>
Install
</property>
<property
name=
"clickable"
>
True
</property>
<property
name=
"alignment"
>
0.5
</property>
<property
name=
"sort-indicator"
>
True
</property>
<property
name=
"sort-column-id"
>
4
</property>
<child>
<object
class=
"GtkCellRendererToggle"
id=
"togglerenderer"
>
<signal
name=
"toggled"
handler=
"_available_plugin_toggled"
swapped=
"no"
/>
</object>
<attributes>
<attribute
name=
"active"
>
4
</attribute>
</attributes>
</child>
</object>
</child>
<style>
<class
name=
"space"
/>
</style>
</object>
</child>
</object>
<packing>
<property
name=
"expand"
>
True
</property>
<property
name=
"fill"
>
True
</property>
<property
name=
"position"
>
0
</property>
</packing>
</child>
<child>
<object
class=
"GtkToolbar"
>
<property
name=
"visible"
>
True
</property>
<property
name=
"can-focus"
>
False
</property>
<property
name=
"toolbar-style"
>
text
</property>
<property
name=
"show-arrow"
>
False
</property>
<child>
<object
class=
"GtkToolButton"
id=
"install_plugin_button"
>
<property
name=
"visible"
>
True
</property>
<property
name=
"sensitive"
>
False
</property>
<property
name=
"can-focus"
>
False
</property>
<property
name=
"label"
translatable=
"yes"
>
Install / Upda_te
</property>
<property
name=
"use-underline"
>
True
</property>
<signal
name=
"clicked"
handler=
"_on_install_update_clicked"
swapped=
"no"
/>
</object>
<packing>
<property
name=
"expand"
>
False
</property>
<property
name=
"homogeneous"
>
False
</property>
</packing>
</child>
<style>
<class
name=
"inline-toolbar"
/>
</style>
</object>
<packing>
<property
name=
"expand"
>
False
</property>
<property
name=
"fill"
>
True
</property>
<property
name=
"position"
>
1
</property>
</packing>
</child>
</object>
<packing>
<property
name=
"index"
>
-1
</property>
</packing>
</child>
<child
type=
"overlay"
>
<object
class=
"GtkSpinner"
id=
"spinner"
>
<property
name=
"visible"
>
True
</property>
<property
name=
"can-focus"
>
False
</property>
<property
name=
"active"
>
True
</property>
</object>
</child>
</object>
<packing>
<property
name=
"expand"
>
False
</property>
<property
name=
"fill"
>
True
</property>
<property
name=
"position"
>
0
</property>
</packing>
</child>
<child>
<object
class=
"GtkBox"
>
<property
name=
"width-request"
>
400
</property>
<property
name=
"visible"
>
True
</property>
<property
name=
"can-focus"
>
False
</property>
<property
name=
"hexpand"
>
True
</property>
<property
name=
"orientation"
>
vertical
</property>
<property
name=
"spacing"
>
18
</property>
<child>
<object
class=
"GtkLabel"
id=
"name_label"
>
<property
name=
"visible"
>
True
</property>
<property
name=
"can-focus"
>
False
</property>
<property
name=
"no-show-all"
>
True
</property>
<property
name=
"halign"
>
start
</property>
<property
name=
"label"
>
<
Plugin Name
>
</property>
<property
name=
"selectable"
>
True
</property>
<property
name=
"xalign"
>
0
</property>
<style>
<class
name=
"large-header"
/>
</style>
</object>
<packing>
<property
name=
"expand"
>
False
</property>
<property
name=
"fill"
>
True
</property>
<property
name=
"position"
>
0
</property>
</packing>
</child>
<child>
<object
class=
"GtkLabel"
id=
"description_label"
>
<property
name=
"visible"
>
True
</property>
<property
name=
"can-focus"
>
False
</property>
<property
name=
"halign"
>
start
</property>
<property
name=
"label"
>
<
Description
>
</property>
<property
name=
"wrap"
>
True
</property>
<property
name=
"wrap-mode"
>
word-char
</property>
<property
name=
"selectable"
>
True
</property>
<property
name=
"xalign"
>
0
</property>
</object>
<packing>
<property
name=
"expand"
>
False
</property>
<property
name=
"fill"
>
True
</property>
<property
name=
"position"
>
1
</property>
</packing>
</child>
<child>
<!-- n-columns=3 n-rows=3 -->
<object
class=
"GtkGrid"
>
<property
name=
"visible"
>
True
</property>
<property
name=
"can-focus"
>
False
</property>
<property
name=
"row-spacing"
>
6
</property>
<property
name=
"column-spacing"
>
12
</property>
<child>
<object
class=
"GtkLabel"
>
<property
name=
"visible"
>
True
</property>
<property
name=
"can-focus"
>
False
</property>
<property
name=
"halign"
>
end
</property>
<property
name=
"valign"
>
start
</property>
<property
name=
"label"
translatable=
"yes"
>
Version
</property>
<style>
<class
name=
"dim-label"
/>
</style>
</object>
<packing>
<property
name=
"left-attach"
>
0
</property>
<property
name=
"top-attach"
>
0
</property>
</packing>
</child>
<child>
<object
class=
"GtkLabel"
>
<property
name=
"visible"
>
True
</property>
<property
name=
"can-focus"
>
False
</property>
<property
name=
"halign"
>
end
</property>
<property
name=
"valign"
>
start
</property>
<property
name=
"label"
translatable=
"yes"
>
Authors
</property>
<style>
<class
name=
"dim-label"
/>
</style>
</object>
<packing>
<property
name=
"left-attach"
>
0
</property>
<property
name=
"top-attach"
>
1
</property>
</packing>
</child>
<child>
<object
class=
"GtkLabel"
>
<property
name=
"visible"
>
True
</property>
<property
name=
"can-focus"
>
False
</property>
<property
name=
"halign"
>
end
</property>
<property
name=
"valign"
>
start
</property>
<property
name=
"label"
translatable=
"yes"
>
Homepage
</property>
<style>
<class
name=
"dim-label"
/>
</style>
</object>
<packing>
<property
name=
"left-attach"
>
0
</property>
<property
name=
"top-attach"
>
2
</property>
</packing>
</child>
<child>
<object
class=
"GtkLabel"
id=
"version_label"
>
<property
name=
"visible"
>
True
</property>
<property
name=
"can-focus"
>
False
</property>
<property
name=
"halign"
>
start
</property>
<property
name=
"label"
>
<
empty
>
</property>
<property
name=
"wrap"
>
True
</property>
<property
name=
"wrap-mode"
>
word-char
</property>
<property
name=
"selectable"
>
True
</property>
<property
name=
"xalign"
>
0
</property>
</object>
<packing>
<property
name=
"left-attach"
>
1
</property>
<property
name=
"top-attach"
>
0
</property>
</packing>
</child>
<child>
<object
class=
"GtkLabel"
id=
"authors_label"
>
<property
name=
"visible"
>
True
</property>
<property
name=
"can-focus"
>
False
</property>
<property
name=
"halign"
>
start
</property>
<property
name=
"label"
>
<
empty
>
</property>
<property
name=
"wrap"
>
True
</property>
<property
name=
"wrap-mode"
>
word-char
</property>
<property
name=
"selectable"
>
True
</property>
<property
name=
"xalign"
>
0
</property>
</object>
<packing>
<property
name=
"left-attach"
>
1
</property>
<property
name=
"top-attach"
>
1
</property>
</packing>
</child>
<child>
<object
class=
"GtkLabel"
id=
"homepage_linkbutton"
>
<property
name=
"visible"
>
True
</property>
<property
name=
"can-focus"
>
False
</property>
<property
name=
"halign"
>
start
</property>
<property
name=
"label"
>
<
empty
>
</property>
<property
name=
"wrap"
>
True
</property>
<property
name=
"wrap-mode"
>
word-char
</property>
<property
name=
"xalign"
>
0
</property>
</object>
<packing>
<property
name=
"left-attach"
>
1
</property>
<property
name=
"top-attach"
>
2
</property>
</packing>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
</object>
<packing>
<property
name=
"expand"
>
False
</property>
<property
name=
"fill"
>
True
</property>
<property
name=
"position"
>
2
</property>
</packing>
</child>
</object>
<packing>
<property
name=
"expand"
>
False
</property>
<property
name=
"fill"
>
True
</property>
<property
name=
"position"
>
1
</property>
</packing>
</child>
</object>
</interface>
plugin_installer/manifest.ini
deleted
100644 → 0
View file @
d7b9b099
[info]
name:
Plugin
Installer
short_name:
plugin_installer
version:
1.4.0
description:
Install
and
upgrade
plugins
for
Gajim
authors:
Denis
Fomin
<fominde@gmail.com>
Yann
Leboulanger
<asterix@lagaule.org>
Thilo
Molitor
<thilo@eightysoft.de>
Philipp
Hörist
<philipp@hoerist.com>
homepage:
https://dev.gajim.org/gajim/gajim-plugins/wikis/PluginInstallerPlugin
min_gajim_version:
1.4.0-dev1
max_gajim_version:
1.4.90
plugin_installer/plugin_installer.png
deleted
100644 → 0
View file @
d7b9b099
541 Bytes
plugin_installer/plugin_installer.py
deleted
100644 → 0
View file @
d7b9b099
# Copyright (C) 2010-2012 Denis Fomin <fominde AT gmail.com>
# Copyright (C) 2011-2012 Yann Leboulanger <asterix AT lagaule.org>
# Copyright (C) 2017-2019 Philipp Hörist <philipp AT hoerist.com>
#
# This file is part of Gajim.
#
# Gajim is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published
# by the Free Software Foundation; version 3 only.
#
# Gajim is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Gajim. If not, see <http://www.gnu.org/licenses/>.
import
logging
from
functools
import
partial
from
io
import
BytesIO
from
zipfile
import
ZipFile
from
gi.repository
import
GLib
from
gi.repository
import
Soup
from
gajim.common
import
app
from
gajim.plugins
import
GajimPlugin
from
gajim.plugins.plugins_i18n
import
_
from
gajim.gui.dialogs
import
DialogButton
from
gajim.gui.dialogs
import
InformationDialog
from
gajim.gui.dialogs
import
ConfirmationCheckDialog
from
plugin_installer.config_dialog
import
PluginInstallerConfigDialog
from
plugin_installer.widget
import
AvailablePage
from
plugin_installer.utils
import
parse_manifests_zip
from
plugin_installer.remote
import
MANIFEST_URL
from
plugin_installer.remote
import
MANIFEST_IMAGE_URL
log
=
logging
.
getLogger
(
'gajim.p.installer'
)
class
PluginInstaller
(
GajimPlugin
):
def
init
(
self
):
# pylint: disable=attribute-defined-outside-init
self
.
description
=
_
(
'Install and upgrade plugins for Gajim'
)
self
.
config_dialog
=
partial
(
PluginInstallerConfigDialog
,
self
)
self
.
config_default_values
=
{
'check_update'
:
(
True
,
''
),
'auto_update'
:
(
False
,
''
),
'auto_update_feedback'
:
(
True
,
''
)}
self
.
gui_extension_points
=
{
'plugin_window'
:
(
self
.
_on_connect_plugin_window
,
self
.
_on_disconnect_plugin_window
)}
self
.
_check_update_id
=
None
self
.
_available_page
=
None
self
.
_update_in_progress
=
False
self
.
_download_in_progress
=
False
self
.
_download_queue
=
0
self
.
_needs_restart
=
False
self
.
_session
=
Soup
.
Session
()
@
property
def
download_in_progress
(
self
):
return
self
.
_download_in_progress
def
activate
(
self
):
if
self
.
config
[
'check_update'
]:
# Check for updates X seconds after Gajim was started
self
.
_check_update_id
=
GLib
.
timeout_add_seconds
(
10
,
self
.
_check_for_updates
)
def
deactivate
(
self
):
if
self
.
_check_update_id
is
not
None
:
GLib
.
source_remove
(
self
.
_check_update_id
)
self
.
_check_update_id
=
None
def
_set_download_in_progress
(
self
,
state
):
self
.
_download_in_progress
=
state
if
self
.
_available_page
is
not
None
:
self
.
_available_page
.
set_download_in_progress
(
state
)
def
_check_for_updates
(
self
):
if
self
.
_download_in_progress
:
log
.
info
(
'Abort checking for updates because '
'other downloads are in progress'
)
return
log
.
info
(
'Checking for Updates...'
)
message
=
Soup
.
Message
.
new
(
'GET'
,
MANIFEST_URL
)
self
.
_session
.
queue_message
(
message
,
self
.
_on_check_for_updates_finished
)
def
_on_check_for_updates_finished
(
self
,
_session
,
message
):
if
message
.
status_code
!=
Soup
.
Status
.
OK
:
log
.
warning
(
'Download failed: %s'
,
MANIFEST_URL
)
log
.
warning
(
Soup
.
Status
.
get_phrase
(
message
.
status_code
))
return
data
=
message
.
props
.
response_body_data
.
get_data
()
if
data
is
None
:
return
plugin_list
=
parse_manifests_zip
(
data
)
for
plugin
in
list
(
plugin_list
):
if
plugin
.
needs_update
():
log
.
info
(
'Update available for: %s - %s'
,
plugin
.
name
,
plugin
.
version
)
else
:
plugin_list
.
remove
(
plugin
)
if
not
plugin_list
:
log
.
info
(
'No updates available'
)
return
if
self
.
config
[
'auto_update'
]:
self
.
_update_in_progress
=
True
self
.
_download_plugins
(
plugin_list
)
else
:
self
.
_notify_about_update
(
plugin_list
)
def
_notify_about_update
(
self
,
plugins
):
def
_open_update
(
is_checked
):
if
is_checked
:
self
.
config
[
'auto_update'
]
=
True
self
.
_download_plugins
(
plugins
)
plugins_str
=
'
\n
'
+
'
\n
'
.
join
([
plugin
.
name
for
plugin
in
plugins
])
ConfirmationCheckDialog
(
_
(
'Plugin Updates'
),
_
(
'Plugin Updates Available'
),
_
(
'There are updates for your plugins:
\n
'
'<b>%s</b>'
)
%
plugins_str
,
_
(
'Update plugins automatically next time'
),
[
DialogButton
.
make
(
'Cancel'
),
DialogButton
.
make
(
'Accept'
,
text
=
_
(
'_Update'
),
is_default
=
True
,
callback
=
_open_update
)]).
show
()
def
_download_plugin_list
(
self
):
log
.
info
(
'Download plugin list...'
)
message
=
Soup
.
Message
.
new
(
'GET'
,
MANIFEST_IMAGE_URL
)
self
.
_session
.
queue_message
(
message
,
self
.
_on_download_plugin_list_finished
)
def
_on_download_plugin_list_finished
(
self
,
_session
,
message
):
if
message
.
status_code
!=
Soup
.
Status
.
OK
:
log
.
warning
(
'Download failed: %s'
,
MANIFEST_IMAGE_URL
)
log
.
warning
(
Soup
.
Status
.
get_phrase
(
message
.
status_code
))
return
data
=
message
.
props
.
response_body_data
.
get_data
()
if
data
is
None
:
return
plugin_list
=
parse_manifests_zip
(
data
)
if
not
plugin_list
:
log
.
warning
(
'No plugins found in zip'
)
if
self
.
_available_page
is
None
:
return
self
.
_available_page
.
append_plugins
(
plugin_list
)
log
.
info
(
'Downloading plugin list finished'
)
def
_on_download_plugins
(
self
,
_available_page
,
_signal_name
,
plugin_list
):
self
.
_download_plugins
(
plugin_list
)
def
_download_plugins
(
self
,
plugin_list
):
if
self
.
_download_in_progress
:
log
.
warning
(
'Download started while other download in progress'
)
return
self
.
_set_download_in_progress
(
True
)
self
.
_download_queue
=
len
(
plugin_list
)
for
plugin
in
plugin_list
:
self
.
_download_plugin
(
plugin
)
def
_download_plugin
(
self
,
plugin
):
log
.
info
(
'Download plugin %s'
,
plugin
.
name
)
message
=
Soup
.
Message
.
new
(
'GET'
,
plugin
.
remote_uri
)