improved usability of "plugin_manager" plugin

This commit is contained in:
lars 2006-11-08 12:19:30 +00:00
parent adab9731c5
commit 3fe6170979
23 changed files with 186 additions and 49 deletions

View file

@ -4,6 +4,7 @@ import CryptoBoxPlugin
class date(CryptoBoxPlugin.CryptoBoxPlugin): class date(CryptoBoxPlugin.CryptoBoxPlugin):
pluginCapabilities = [ "system" ] pluginCapabilities = [ "system" ]
pluginVisibility = [ "preferences" ]
requestAuth = False requestAuth = False
rank = 10 rank = 10

View file

@ -2,7 +2,8 @@ import CryptoBoxPlugin
class disks(CryptoBoxPlugin.CryptoBoxPlugin): class disks(CryptoBoxPlugin.CryptoBoxPlugin):
pluginCapabilities = [ "menu" ] pluginCapabilities = [ "system" ]
pluginVisibility = [ "menu" ]
requestAuth = False requestAuth = False
rank = 10 rank = 10

View file

@ -4,6 +4,7 @@ from CryptoBoxExceptions import *
class format_fs(CryptoBoxPlugin.CryptoBoxPlugin): class format_fs(CryptoBoxPlugin.CryptoBoxPlugin):
pluginCapabilities = [ "volume" ] pluginCapabilities = [ "volume" ]
pluginVisibility = [ "volume" ]
requestAuth = True requestAuth = True
rank = 60 rank = 60

View file

@ -2,7 +2,8 @@ import CryptoBoxPlugin
class help(CryptoBoxPlugin.CryptoBoxPlugin): class help(CryptoBoxPlugin.CryptoBoxPlugin):
pluginCapabilities = [ "menu" ] pluginCapabilities = [ "system" ]
pluginVisibility = [ "menu" ]
requestAuth = False requestAuth = False
rank = 80 rank = 80

View file

@ -3,7 +3,8 @@ import CryptoBoxPlugin
class language_selection(CryptoBoxPlugin.CryptoBoxPlugin): class language_selection(CryptoBoxPlugin.CryptoBoxPlugin):
pluginCapabilities = [ "system", "menu" ] pluginCapabilities = [ "system" ]
pluginVisibility = [ "menu", "preferences" ]
requestAuth = False requestAuth = False
rank = 60 rank = 60

View file

@ -4,6 +4,7 @@ import os
class logs(CryptoBoxPlugin.CryptoBoxPlugin): class logs(CryptoBoxPlugin.CryptoBoxPlugin):
pluginCapabilities = [ "system" ] pluginCapabilities = [ "system" ]
pluginVisibility = [ "preferences" ]
requestAuth = False requestAuth = False
rank = 90 rank = 90

View file

@ -10,6 +10,7 @@ CHANGE_IP_DELAY=1
class network(CryptoBoxPlugin.CryptoBoxPlugin): class network(CryptoBoxPlugin.CryptoBoxPlugin):
pluginCapabilities = [ "system" ] pluginCapabilities = [ "system" ]
pluginVisibility = [ "preferences" ]
requestAuth = True requestAuth = True
rank = 30 rank = 30

View file

@ -7,6 +7,7 @@ import CryptoBoxPlugin
class partition(CryptoBoxPlugin.CryptoBoxPlugin): class partition(CryptoBoxPlugin.CryptoBoxPlugin):
pluginCapabilities = [ "system" ] pluginCapabilities = [ "system" ]
pluginVisibility = [ "preferences" ]
requestAuth = True requestAuth = True
rank = 80 rank = 80

View file

@ -32,11 +32,13 @@ Python code interface:
time (for the "date" plugin)) time (for the "date" plugin))
- the class variable "pluginCapabilities" must be an array of strings (supported: "system" and - the class variable "pluginCapabilities" must be an array of strings (supported: "system" and
"volume") "volume")
- the class variable "pluginVisibility" may contain one or more of the following items:
menu/preferences/volume. This obviously should fit to the 'pluginCapabilities' variable.
An empty list is interpreted as a disabled plugin.
- the class variable "requestAuth" is boolean and defines, if admin authentication is necessary - the class variable "requestAuth" is boolean and defines, if admin authentication is necessary
for this plugin for this plugin
- the class variable "rank" is an integer in the range of 0..100 - it determines the order - the class variable "rank" is an integer in the range of 0..100 - it determines the order
of plugins in listings (lower value -> higher priority) of plugins in listings (lower value -> higher priority)
- the class variable "enabled" is boolean and detemines the default availability of the plugin
- volume plugins contain the attribute "device" (you may trust this value - a volume plugin will - volume plugins contain the attribute "device" (you may trust this value - a volume plugin will
never get called with an invalid device) never get called with an invalid device)
- the python module which contains the plugin's class should also contain a class called - the python module which contains the plugin's class should also contain a class called
@ -50,8 +52,8 @@ Language file structure:
Name (a short description) Name (a short description)
Link (the visible text for links to this plugin) Link (the visible text for links to this plugin)
Rank (defines the order of the plugins displayed (0..100)) Rank (defines the order of the plugins displayed (0..100))
- all warnings, error and success messages should be stored below WarningMessage.??? - all warnings, hints and success messages should be stored below WarningMessage.???
(resp. ErrorMessage or SuccessMessage) (resp. AdviceMessage or SuccessMessage)
Clearsilver template: Clearsilver template:

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

View file

@ -1,17 +1,24 @@
Name = Plugin Manager Name = Plugin Manager
Link = Manage plugins Link = Manage plugins
Title.PluginManager = Plugin Manager Title {
PluginManager = Plugin Manager
VolumePlugins = Volume plugins
SystemPlugins = System plugins
}
Button.SaveSettings = Save settings Button {
SaveSettings = Save settings
Up = move up
Down = move down
}
Text { Text {
PluginName = Plugin PluginName = Plugin
PluginRank = Priority PluginRank = Order
PluginEnabled = Enabled? PluginEnabled = Enabled?
RequestsAuth = Requires admin? RequestsAuth = Requires admin?
VolumePlugin = Volume InMenu = Main menu
SystemPlugin = System InPreferences = Preferences
MenuPlugin = Menu WhereVisible = Where visible?
PluginTypes = Type of plugin
} }

View file

@ -14,6 +14,10 @@
width: 24px; width: 24px;
height: 24px; height: 24px;
} }
table.plugin_list a img {
border: none;
}
</style> </style>
@ -22,36 +26,75 @@
<?cs call:handle_messages() ?> <?cs call:handle_messages() ?>
<h2><?cs var:html_escape(Lang.Plugins.plugin_manager.Title.VolumePlugins) ?></h2>
<?cs call:print_form_header("manage_plugins", "plugin_manager") ?> <?cs call:print_form_header("manage_plugins", "plugin_manager") ?>
<table class="plugin_list"> <p><table class="plugin_list">
<tr>
<th></th>
<th colspan="3"><?cs var:html_escape(Lang.Plugins.plugin_manager.Text.PluginTypes) ?></th>
<th></th>
<th></th>
<th></th>
</tr>
<tr> <tr>
<th><?cs var:html_escape(Lang.Plugins.plugin_manager.Text.PluginName) ?></th> <th><?cs var:html_escape(Lang.Plugins.plugin_manager.Text.PluginName) ?></th>
<th><?cs var:html_escape(Lang.Plugins.plugin_manager.Text.MenuPlugin) ?></th>
<th><?cs var:html_escape(Lang.Plugins.plugin_manager.Text.SystemPlugin) ?></th>
<th><?cs var:html_escape(Lang.Plugins.plugin_manager.Text.VolumePlugin) ?></th>
<th><?cs var:html_escape(Lang.Plugins.plugin_manager.Text.PluginRank) ?></th>
<th><?cs var:html_escape(Lang.Plugins.plugin_manager.Text.PluginEnabled) ?></th> <th><?cs var:html_escape(Lang.Plugins.plugin_manager.Text.PluginEnabled) ?></th>
<th><?cs var:html_escape(Lang.Plugins.plugin_manager.Text.RequestsAuth) ?></th> <th><?cs var:html_escape(Lang.Plugins.plugin_manager.Text.RequestsAuth) ?></th>
<th><?cs var:html_escape(Lang.Plugins.plugin_manager.Text.PluginRank) ?></th>
</tr> </tr>
<?cs each:x = Settings.PluginList <?cs # count volume plugins ?><?cs set: all_count = #0
?><?cs each:x = Settings.PluginList ?><?cs if: x.Types.volume ?><?cs
set: all_count = all_count + 1 ?><?cs /if ?><?cs /each ?>
<?cs set:run_counter = 0 ?><?cs
loop: index = #0, #100, #1 ?><?cs
each:x = Settings.PluginList ?><?cs if:(x.Rank == index) && x.Types.volume
?><?cs set: run_counter = run_counter + 1
?><input type="hidden" name="<?cs var:name(x) ?>_listed" value="1" /><tr> ?><input type="hidden" name="<?cs var:name(x) ?>_listed" value="1" /><tr>
<td style="text-align:left"><?cs var:html_escape(name(x)) ?></td> <td style="text-align:left"><a name="<?cs var:html_escape(name(x)) ?>"><?cs var:html_escape(x.Name) ?></a></td>
<td><?cs if:x.Types.menu ?><img src="icons/plugin_manager?image=gtk-ok_nuvola.png" alt="X" /><?cs else ?><img src="icons/plugin_manager?image=gtk-stop_nuvola.png" alt="-" /><?cs /if ?></td> <td><input type="checkbox" name="<?cs var:name(x) ?>_visible_volume" <?cs if:x.Visible.volume ?>checked="checked"<?cs /if ?> /></td>
<td><?cs if:x.Types.system ?><img src="icons/plugin_manager?image=gtk-ok_nuvola.png" alt="X" /><?cs else ?><img src="icons/plugin_manager?image=gtk-stop_nuvola.png" alt="-" /><?cs /if ?></td>
<td><?cs if:x.Types.volume ?><img src="icons/plugin_manager?image=gtk-ok_nuvola.png" alt="X" /><?cs else ?><img src="icons/plugin_manager?image=gtk-stop_nuvola.png" alt="-" /><?cs /if ?></td>
<td><input style="text-align:right" type="text" size="3" name="<?cs var:name(x) ?>_rank" value="<?cs var:html_escape(x.Rank) ?>" /></td>
<td><input type="checkbox" name="<?cs var:name(x) ?>_enabled" <?cs if:x.Enabled ?>checked="checked"<?cs /if ?> /></td>
<td><input type="checkbox" name="<?cs var:name(x) ?>_auth" <?cs if:x.RequestAuth ?>checked="checked"<?cs /if ?> /></td> <td><input type="checkbox" name="<?cs var:name(x) ?>_auth" <?cs if:x.RequestAuth ?>checked="checked"<?cs /if ?> /></td>
</tr><?cs /each ?> <td>
</table> <?cs if:run_counter != all_count ?><a href="<?cs call:link("plugin_manager", "plugin_name", name(x), "action", "down") ?>">
<img src="icons/plugin_manager?image=tango-go-down.png" alt="<?cs var:html_escape(Lang.Plugins.plugin_manager.Button.Down) ?>" title="<?cs var:html_escape(Lang.Plugins.plugin_manager.Button.Down) ?>" /></a><?cs /if ?>
<?cs if:run_counter != 1 ?><a href="<?cs call:link("plugin_manager", "plugin_name", name(x), "action", "up") ?>" >
<img src="icons/plugin_manager?image=tango-go-up.png" alt="<?cs var:html_escape(Lang.Plugins.plugin_manager.Button.Up) ?>" title="<?cs var:html_escape(Lang.Plugins.plugin_manager.Button.Up) ?>" /></a><?cs /if ?>
<input type="hidden" name="<?cs var:html_escape(name(x)) ?>_rank" value="<?cs var:html_escape(x.Rank) ?>" /></td>
</tr><?cs /if ?><?cs /each ?><?cs /loop ?>
</table></p>
<h2><?cs var:html_escape(Lang.Plugins.plugin_manager.Title.SystemPlugins) ?></h2>
<p><table class="plugin_list">
<tr>
<th></th>
<th colspan="2"><?cs var:html_escape(Lang.Plugins.plugin_manager.Text.WhereVisible) ?></th>
<th></th>
<th></th>
<th></th>
</tr>
<?cs # count non-volume plugins ?><?cs set: all_count = #0
?><?cs each:x = Settings.PluginList ?><?cs if: !x.Types.volume ?><?cs
set: all_count = all_count + 1 ?><?cs /if ?><?cs /each ?>
<tr>
<th><?cs var:html_escape(Lang.Plugins.plugin_manager.Text.PluginName) ?></th>
<th><?cs var:html_escape(Lang.Plugins.plugin_manager.Text.InMenu) ?></th>
<th><?cs var:html_escape(Lang.Plugins.plugin_manager.Text.InPreferences) ?></th>
<th><?cs var:html_escape(Lang.Plugins.plugin_manager.Text.RequestsAuth) ?></th>
<th><?cs var:html_escape(Lang.Plugins.plugin_manager.Text.PluginRank) ?></th>
</tr>
<?cs set:run_counter = 0 ?><?cs
loop:index = #0, #100, #1 ?><?cs
each:x = Settings.PluginList ?><?cs if:(x.Rank == index) && !x.Types.volume
?><?cs set: run_counter = run_counter + 1
?><input type="hidden" name="<?cs var:name(x) ?>_listed" value="1" /><tr>
<td style="text-align:left"><a name="<?cs var:html_escape(name(x)) ?>"><?cs var:html_escape(x.Name) ?></a></td>
<td><input type="checkbox" name="<?cs var:name(x) ?>_visible_menu" <?cs if:x.Visible.menu ?>checked="checked"<?cs /if ?> /></td>
<td><input type="checkbox" name="<?cs var:name(x) ?>_visible_preferences" <?cs if:x.Visible.preferences ?>checked="checked"<?cs /if ?> /></td>
<td><input type="checkbox" name="<?cs var:name(x) ?>_auth" <?cs if:x.RequestAuth ?>checked="checked"<?cs /if ?> /></td>
<td>
<?cs if:run_counter != all_count ?><a href="<?cs call:link("plugin_manager", "plugin_name", name(x), "action", "down") ?>">
<img src="icons/plugin_manager?image=tango-go-down.png" alt="<?cs var:html_escape(Lang.Plugins.plugin_manager.Button.Down) ?>" title="<?cs var:html_escape(Lang.Plugins.plugin_manager.Button.Down) ?>" /></a><?cs /if ?>
<?cs if:run_counter != 1 ?><a href="<?cs call:link("plugin_manager", "plugin_name", name(x), "action", "up") ?>" >
<img src="icons/plugin_manager?image=tango-go-up.png" alt="<?cs var:html_escape(Lang.Plugins.plugin_manager.Button.Up) ?>" title="<?cs var:html_escape(Lang.Plugins.plugin_manager.Button.Up) ?>" value="<?cs var:x.Rank ?>" /></a><?cs /if ?>
<input type="hidden" name="<?cs var:html_escape(name(x)) ?>_rank" value="<?cs var:html_escape(x.Rank) ?>" /></td>
</tr><?cs /if ?><?cs /each ?><?cs /loop ?>
</table></p>
<p> <p>
<input type="hidden" name="store" value="1" /> <input type="hidden" name="store" value="1" />
@ -59,3 +102,5 @@
</p> </p>
</form> </form>

View file

@ -1,15 +1,30 @@
import CryptoBoxPlugin import CryptoBoxPlugin
import Plugins
class plugin_manager(CryptoBoxPlugin.CryptoBoxPlugin): class plugin_manager(CryptoBoxPlugin.CryptoBoxPlugin):
pluginCapabilities = [ "system" ] pluginCapabilities = [ "system" ]
pluginVisibility = [ "preferences" ]
requestAuth = True requestAuth = True
rank = 90 rank = 90
def doAction(self, store=None, **args): def doAction(self, store=None, action=None, plugin_name=None, **args):
import re import re
if store: if plugin_name:
## check for invalid characters
if re.search(u'\W', plugin_name): return "plugin_list"
pluginList = Plugins.PluginManager(self.cbox, self.cbox.prefs["Locations"]["PluginDir"])
plugin = pluginList.getPlugin(plugin_name)
if not plugin: return "plugin_list"
## take only plugins, that are of the same type as the choosen one
self.plugins = [e for e in pluginList.getPlugins() if e.pluginCapabilities == plugin.pluginCapabilities]
if action == "up":
self.__move_up(plugin)
elif action == "down":
self.__move_down(plugin)
return "plugin_list"
elif store:
for key in args.keys(): for key in args.keys():
if key.endswith("_listed"): if key.endswith("_listed"):
if not re.search(u'\W',key): if not re.search(u'\W',key):
@ -27,26 +42,80 @@ class plugin_manager(CryptoBoxPlugin.CryptoBoxPlugin):
return "no status" return "no status"
def __setConfig(self, name, args): def __sortPlugins(self):
setting = {} """sort all plugins in the list according to their rank"""
setting["enabled"] = False def cmp_func(x,y):
xRank = x.getRank()
yRank = y.getRank()
if xRank < yRank: return -1
elif xRank == yRank: return 0
else: return 1
self.plugins.sort(cmp = cmp_func)
def __distributeRanks(self):
"""evenly distribute the 'rank' values according to the current order of
the list"""
dist = 100/len(self.plugins)
for index,pl in enumerate(self.plugins):
try:
self.cbox.prefs.pluginConf[pl.getName()]["rank"] = dist*index
except KeyError:
self.cbox.prefs.pluginConf[pl.getName()] = {}
self.cbox.prefs.pluginConf[pl.getName()]["rank"] = dist*index
self.cbox.prefs.pluginConf.write()
def __move_up(self, plugin):
self.__sortPlugins()
try: try:
if args[name + "_enabled"]: index = self.plugins.index(plugin)
setting["enabled"] = True ## first elements may not move up
except KeyError: if index == 0:
pass return
setting["rank"] = "80" except ValueError:
return
self.plugins.remove(plugin)
self.plugins.insert(index-1, plugin)
self.__distributeRanks()
def __move_down(self, plugin):
self.__sortPlugins()
try:
index = self.plugins.index(plugin)
## last elements may not move down
if index == len(self.plugins) - 1:
return
except ValueError:
return
self.plugins.remove(plugin)
self.plugins.insert(index+1, plugin)
self.__distributeRanks()
def __setConfig(self, name, args):
import re
setting = {}
setting["visibility"] = []
## look for "_visible_" values and apply them
pattern = re.compile(u'%s_visible_([\w]+)$' % name)
for key in args.keys():
if key.startswith(name + "_visible_"):
(vis_type, ) = pattern.match(key).groups()
setting["visibility"].append(vis_type)
setting["rank"] = "50"
try: try:
r = int(args[name + "_rank"]) r = int(args[name + "_rank"])
if r>=0 and r<=100: if r>=0 and r<=100:
setting["rank"] = r setting["rank"] = r
except KeyError, ValueError: except (KeyError, ValueError):
pass pass
setting["requestAuth"] = False setting["requestAuth"] = False
try: try:
if args[name + "_auth"]: if args[name + "_auth"]:
setting["requestAuth"] = True setting["requestAuth"] = True
except KeyError, ValueError: except (KeyError, ValueError):
pass pass
self.cbox.prefs.pluginConf[name] = setting self.cbox.prefs.pluginConf[name] = setting

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

View file

@ -4,7 +4,8 @@ REDIRECT_DELAY = 180
class shutdown(CryptoBoxPlugin.CryptoBoxPlugin): class shutdown(CryptoBoxPlugin.CryptoBoxPlugin):
pluginCapabilities = [ "system", "menu" ] pluginCapabilities = [ "system" ]
pluginVisibility = [ "preferences", "menu" ]
requestAuth = False requestAuth = False
rank = 90 rank = 90

View file

@ -7,7 +7,7 @@
<?cs # sort the Plugins - using the most stupid way :) ?> <?cs # sort the Plugins - using the most stupid way :) ?>
<?cs loop: order = #0, #100, #1 <?cs loop: order = #0, #100, #1
?><?cs # plugins ?><?cs each:x = Settings.PluginList ?><?cs # plugins ?><?cs each:x = Settings.PluginList
?><?cs if:x.Enabled && x.Types.system && x.Rank == order ?> ?><?cs if:x.Types.system && x.Visible.preferences && x.Rank == order ?>
<?cs call:show_plugin(name(x), 'system') ?><?cs /if ?><?cs <?cs call:show_plugin(name(x), 'system') ?><?cs /if ?><?cs
/each ?><?cs /each ?><?cs
/loop ?> /loop ?>

View file

@ -2,7 +2,8 @@ import CryptoBoxPlugin
class system_preferences(CryptoBoxPlugin.CryptoBoxPlugin): class system_preferences(CryptoBoxPlugin.CryptoBoxPlugin):
pluginCapabilities = [ "menu" ] pluginCapabilities = [ "system" ]
pluginVisibility = [ "menu" ]
requestAuth = False requestAuth = False
rank = 20 rank = 20

View file

@ -5,6 +5,7 @@ RESERVED_USERS = [ "admin" ]
class user_manager(CryptoBoxPlugin.CryptoBoxPlugin): class user_manager(CryptoBoxPlugin.CryptoBoxPlugin):
pluginCapabilities = [ "system" ] pluginCapabilities = [ "system" ]
pluginVisibility = [ "preferences" ]
requestAuth = True requestAuth = True
rank = 45 rank = 45

View file

@ -4,6 +4,7 @@ import CryptoBoxPlugin
class volume_details(CryptoBoxPlugin.CryptoBoxPlugin): class volume_details(CryptoBoxPlugin.CryptoBoxPlugin):
pluginCapabilities = [ "volume" ] pluginCapabilities = [ "volume" ]
pluginVisibility = [ "volume" ]
requestAuth = False requestAuth = False
rank = 100 rank = 100

View file

@ -5,6 +5,7 @@ from CryptoBoxExceptions import *
class volume_mount(CryptoBoxPlugin.CryptoBoxPlugin): class volume_mount(CryptoBoxPlugin.CryptoBoxPlugin):
pluginCapabilities = [ "volume" ] pluginCapabilities = [ "volume" ]
pluginVisibility = [ "volume" ]
requestAuth = False requestAuth = False
rank = 0 rank = 0

View file

@ -5,6 +5,7 @@ from CryptoBoxExceptions import *
class volume_props(CryptoBoxPlugin.CryptoBoxPlugin): class volume_props(CryptoBoxPlugin.CryptoBoxPlugin):
pluginCapabilities = [ "volume" ] pluginCapabilities = [ "volume" ]
pluginVisibility = [ "volume" ]
requestAuth = False requestAuth = False
rank = 40 rank = 40