00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 import os
00030 import sys
00031 import imp
00032
00033 import traceback
00034
00035 import functions
00036
00037
00038 import gtk
00039 import gobject
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069 class Plugins():
00070
00071
00072
00073 def __init__(self, pyjama):
00074
00075 self.pyjama = pyjama
00076
00077
00078 self.loaded = {}
00079
00080 self.ignored = []
00081
00082 self.plugins_by_name = {}
00083
00084 self.pluginpath = os.path.join(os.path.dirname(imp.find_module("pyjama")[1]), "plugins/")
00085
00086 self.blacklisted_browser = False
00087 print("%s %s %s" % (30*"-", " <Plugins> ", 30*"-"))
00088 print ("Found Plugins in folder: %s" % self.pluginpath)
00089
00090
00091
00092 hardcoded_blacklist = ["PMC", "torrent-peer", "lastplayed", "catchERR", "bookmarks", "playlists"]
00093
00094
00095
00096
00097
00098 try:
00099 files = os.listdir(self.pluginpath)
00100 if ".py" in "".join(files):
00101 print "############################################################"
00102 print "# #"
00103 print "# Pyjama uses a new plugin system. For this reason, all #"
00104 print "# files in your plugin folder can be deleted. Please #"
00105 print "# delete the files listed below to save your disk space. #"
00106 print "# #"
00107 print "# !!The folders in the plugin dir should NOT be deleted!! #"
00108 print "# #"
00109 print "############################################################"
00110 for dat in files:
00111 dat_pos = os.path.join(self.pluginpath, dat)
00112 if not os.path.isdir(dat_pos) and dat != "README":
00113 print ("Don't know what to do with file %s" % dat_pos)
00114
00115 except:
00116 pass
00117
00118
00119
00120
00121
00122
00123 sys.path.insert(0, self.pluginpath[:-1])
00124
00125
00126 self.plugininfos = []
00127
00128
00129 for plugin in sorted(os.listdir(self.pluginpath)):
00130
00131 bl = self.pyjama.settings.get_value("PLUGINS", "blacklist", "")
00132 if os.path.exists(os.path.join(self.pluginpath, plugin, "%s.info" % plugin)) :
00133 item_infos = self.get_infos(plugin)
00134 if plugin in bl and item_infos["autoload"] == "false":
00135 bl = bl.replace(plugin, "")
00136 self.pyjama.settings.set_value("PLUGINS", "blacklist", bl)
00137 print ("Removed %s from blacklist - autoload=false" % plugin)
00138
00139
00140
00141
00142 if self.pyjama.settings.get_value("PYJAMA", "crashed", False) and (plugin == "mozplug" or plugin == "webkit-plugin") and self.pyjama.check_another_instance_running() != True:
00143 whitelist = self.pyjama.settings.get_value("PLUGINS", "whitelist", "")
00144 if plugin in whitelist:
00145 print ("Pyjama crashed on last start - removing '%s' from whitelist again" % plugin)
00146 whitelist = whitelist.replace(plugin, "")
00147 self.pyjama.settings.set_value("PLUGINS", 'whitelist', whitelist)
00148 self.blacklisted_browser = True
00149
00150 if plugin in hardcoded_blacklist:
00151 print("!!! %s found in 'hardcoded_blacklist'" % plugin)
00152 elif "noplugins" in sys.argv and not plugin+"+" in sys.argv:
00153 pass
00154 elif os.path.isdir(os.path.join(self.pluginpath, plugin)) and os.path.exists(os.path.join(self.pluginpath, plugin, "%s.info" % plugin)) and not plugin+"-" in sys.argv and not plugin in self.pyjama.settings.get_value("PLUGINS", 'blacklist', "") or plugin+"+" in sys.argv:
00155 if item_infos['autoload'] == "false":
00156 if plugin in self.pyjama.settings.get_value("PLUGINS", 'whitelist', "") or plugin+"+" in sys.argv:
00157 self.plugininfos.append(item_infos)
00158 self.plugins_by_name[plugin]= item_infos
00159 else:
00160 self.ignored.append(item_infos)
00161 self.plugins_by_name[plugin]= item_infos
00162 else:
00163 self.plugininfos.append(item_infos)
00164 self.plugins_by_name[plugin]= item_infos
00165 elif plugin+"-" in sys.argv or plugin in self.pyjama.settings.get_value("PLUGINS", 'blacklist'):
00166 try:
00167 self.ignored.append(item_infos)
00168 self.plugins_by_name[plugin]= item_infos
00169 except Exception, inst:
00170 print "Plugin '%s' does not meet the specification" % plugin
00171
00172
00173
00174
00175 for x in range(len(self.plugininfos)):
00176 for plugin in range(0, len(self.plugininfos)-1):
00177 if int(self.plugininfos[plugin]['order']) > int(self.plugininfos[plugin+1]['order']):
00178 self.plugininfos[plugin], self.plugininfos[plugin+1] = self.plugininfos[plugin+1], self.plugininfos[plugin]
00179
00180
00181
00182
00183
00184 self.imported_modules = []
00185 for plugin in self.plugininfos:
00186 name = plugin['name']
00187 filename = plugin['filename']
00188 order = plugin['order']
00189 version = plugin['version']
00190 if not name+"-" in sys.argv and not name in self.pyjama.settings.get_value("PLUGINS", 'blacklist') or name+"+" in sys.argv:
00191 try:
00192 mod = __import__ (plugin['filename'])
00193
00194
00195 self.imported_modules.append({'module':mod, 'name':name, 'order':order, 'version':version})
00196 except Exception:
00197 print traceback.format_exc()
00198 print "Error importing Plugin %s (%s)" % (name, filename)
00199 else:
00200 print "Plugin %s ignored" % name
00201
00202
00203
00204
00205 ev = self.pyjama.Events
00206 for plugin in self.imported_modules:
00207 module = plugin['module']
00208 name = plugin['name']
00209 order = plugin['order']
00210 version = plugin['version']
00211 mod_name = module.__name__
00212 try:
00213 self.loaded[mod_name] = module.main(self.pyjama)
00214 ev.raise_event('pluginloaded', name=name, version=version, order=order, mod_name=mod_name)
00215 except:
00216 print traceback.format_exc()
00217 print "Error calling Plugin %s (%s)" % (name, mod_name)
00218 print mod.__file__
00219
00220
00221 sys.path.pop(0)
00222 print("%s %s %s" % (30*"-", " </Plugins> ", 30*"-"))
00223
00224
00225
00226
00227
00228 def get_infos(self, plugin):
00229 fh = open(os.path.join(self.pluginpath, plugin, "%s.info" % plugin))
00230 content = fh.read()
00231 fh.close()
00232 infos = content.split("\n")
00233
00234 item_infos = {}
00235 item_infos['filename'] = plugin
00236 last_line = None
00237
00238 item_infos['name'], item_infos['version'], item_infos['order'], item_infos['author'], item_infos['homepage'], item_infos['description'], item_infos['copyright'], item_infos['license'], item_infos['autoload'] = "unnamed plugin", "0.1", "100", "", "", "", "", "", "true"
00239 for line in infos:
00240 cur_item = line[:line.find("=")].strip().lower()
00241 if cur_item == "name":
00242
00243 item_infos['name'] = line[line.find("=")+1:].strip()
00244 elif cur_item == "version":
00245
00246 item_infos['version'] = line[line.find("=")+1:].strip()
00247 elif cur_item == "order":
00248
00249 item_infos['order'] = line[line.find("=")+1:].strip()
00250 elif cur_item == "author":
00251
00252 item_infos['author'] = line[line.find("=")+1:].strip()
00253 elif cur_item == "homepage":
00254
00255 item_infos['homepage'] = line[line.find("=")+1:].strip()
00256 elif cur_item == "copyright":
00257
00258 item_infos['copyright'] = line[line.find("=")+1:].strip()
00259 elif cur_item == "autoload":
00260 item_infos['autoload'] = line[line.find("=")+1:].strip()
00261 elif cur_item == "license":
00262 item_infos['license'] = line[line.find("=")+1:].strip()
00263 elif cur_item == "description":
00264 last_line = "description"
00265 item_infos['description'] = line[line.find("=")+1:].strip()
00266 elif last_line is not None and line!="":
00267 item_infos[last_line] += "\n%s" % line.strip()
00268 return item_infos
00269
00270 (
00271 COLUMN_SELECTED,
00272 COLUMN_NAME,
00273 COLUMN_ID
00274 ) = range(3)
00275
00276
00277
00278
00279
00280
00281
00282 class PluginDialog(gtk.Dialog):
00283
00284
00285
00286 def __init__(self, pyjama):
00287
00288 self.pyjama = pyjama
00289
00290 gtk.Dialog.__init__(self, "", pyjama.window)
00291
00292 self.set_modal(True)
00293 self.set_title(_("Plugins"))
00294 self.set_border_width(5)
00295 self.set_size_request(500, 400)
00296 self.set_resizable(False)
00297
00298 label = gtk.Label(_("Deselect Plugins you don't want to be started with pyjama."))
00299 label.set_line_wrap(True)
00300 label.set_single_line_mode(False)
00301 self.vbox.pack_start(label, expand=False, fill=True)
00302
00303 hbox = gtk.HBox()
00304 self.vbox.pack_start(hbox)
00305
00306 sw = gtk.ScrolledWindow()
00307 sw.set_shadow_type(gtk.SHADOW_ETCHED_IN)
00308 sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
00309 hbox.pack_start(sw, True, True)
00310
00311
00312 self.model = self.__create_model()
00313
00314
00315 self.__treeview = gtk.TreeView(self.model)
00316 self.__treeview.set_rules_hint(True)
00317 self.__treeview.set_search_column(COLUMN_NAME)
00318 selection = self.__treeview.get_selection()
00319 selection.connect("changed", self.cb_treeview_selection_changed)
00320
00321 sw.add(self.__treeview)
00322
00323
00324 self.__add_columns(self.__treeview)
00325
00326
00327 buttonbox = gtk.VButtonBox()
00328 buttonbox.set_layout(gtk.BUTTONBOX_START)
00329 buttonbox.set_spacing(30)
00330 hbox.pack_end(buttonbox, False, True)
00331 bInfos = gtk.Button("", gtk.STOCK_ABOUT)
00332 bInfos.set_property("image-position", gtk.POS_TOP)
00333 bInfos.connect("clicked", self.cb_bInfos_clicked)
00334 buttonbox.pack_start(bInfos, False, True)
00335 self.__bConfigure = gtk.Button("", gtk.STOCK_PREFERENCES)
00336 self.__bConfigure.set_property("image-position", gtk.POS_TOP)
00337 self.__bConfigure.connect("clicked", self.cb_bConfigure_clicked)
00338 self.__bConfigure.set_sensitive(False)
00339 buttonbox.pack_start(self.__bConfigure, False, True)
00340 buttonbox.show_all()
00341
00342 self.add_button(gtk.STOCK_CANCEL, -1)
00343 self.add_button(gtk.STOCK_OK, 1)
00344
00345 self.populate_list()
00346
00347 self.show_all()
00348
00349
00350
00351
00352
00353
00354 def cb_treeview_selection_changed(self, treeselection):
00355
00356 model, iter = treeselection.get_selected()
00357
00358 if iter is not None:
00359 idstr = model.get(iter, 2)[0]
00360 plugin = self.get_plugin_by_filename(idstr)
00361 if plugin is not None:
00362 self.__bConfigure.set_sensitive(self.pyjama.preferences.has_preferences(idstr))
00363
00364
00365
00366
00367
00368
00369 def cb_bInfos_clicked(self, widget):
00370 selection = self.__treeview.get_selection()
00371 model, iter = selection.get_selected()
00372
00373 if iter is not None:
00374 idstr = model.get(iter, 2)[0]
00375 plugin = self.get_plugin_by_filename(idstr)
00376 if plugin is not None:
00377 icon = os.path.join(functions.install_dir(), "plugins", idstr, "%s.png" % idstr)
00378 if os.path.exists(icon):
00379 pb = gtk.gdk.pixbuf_new_from_file(icon)
00380 else:
00381 pb = gtk.gdk.pixbuf_new_from_file_at_size(os.path.join(functions.install_dir(), "images", "plugin.png"), 92, 92)
00382 dialog = gtk.AboutDialog()
00383 dialog.set_name(plugin['name'])
00384 dialog.set_logo(pb)
00385 dialog.set_version(plugin['version'])
00386 if plugin['copyright'] != "":
00387 dialog.set_copyright(plugin['copyright'])
00388 dialog.set_comments(plugin['description'])
00389 if plugin['license'] != "":
00390 dialog.set_license(functions.license2text(plugin['license']))
00391 if plugin['homepage'] != "":
00392 dialog.set_website(plugin['homepage'])
00393 dialog.set_authors(plugin['author'].split(","))
00394 dialog.set_logo(None)
00395 dialog.run()
00396 dialog.set_modal(True)
00397 dialog.destroy()
00398
00399
00400
00401
00402
00403 def get_plugin_by_filename(self, filename):
00404 if filename in self.pyjama.plugins.plugins_by_name:
00405 return self.pyjama.plugins.plugins_by_name[filename]
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417 def cb_bConfigure_clicked(self, widget):
00418 selection = self.__treeview.get_selection()
00419 model, iter = selection.get_selected()
00420
00421 if iter is not None:
00422 idstr = model.get(iter, 2)[0]
00423 plugin = self.get_plugin_by_filename(idstr)
00424 if plugin is not None:
00425 if self.pyjama.preferences.has_preferences(idstr):
00426 if not plugin['filename'] in self.pyjama.plugins.loaded:
00427 dia = gtk.MessageDialog(self.pyjama.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, _("This plugin was not loaded yet.\nIf you want to configure it, please check it and restart Pyjama."))
00428 dia.run()
00429 dia.destroy()
00430 else:
00431 self.pyjama.show_preferences(name=idstr)
00432
00433 def __create_model(self):
00434
00435
00436 model = gtk.ListStore(
00437 gobject.TYPE_BOOLEAN,
00438 gobject.TYPE_STRING,
00439 gobject.TYPE_STRING
00440 )
00441 return model
00442
00443 def __add_columns(self, treeview):
00444 model = treeview.get_model()
00445
00446
00447 renderer = gtk.CellRendererToggle()
00448 renderer.connect('toggled', self.select_toggled, model)
00449 column = gtk.TreeViewColumn(_('Load'), renderer, active=COLUMN_SELECTED)
00450 column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
00451 column.set_fixed_width(50)
00452 treeview.append_column(column)
00453
00454
00455
00456 column = gtk.TreeViewColumn('Name', gtk.CellRendererText(), text=COLUMN_NAME)
00457 column.set_sort_column_id(COLUMN_NAME)
00458 treeview.append_column(column)
00459
00460
00461
00462
00463
00464 def populate_list(self):
00465 lstore = self.__treeview.get_model()
00466 lstore.clear()
00467
00468 for plugin in self.pyjama.plugins.plugininfos:
00469 name = plugin['name']
00470 idstr = plugin['filename']
00471 description = plugin['description']
00472 if len(description)>40:description=description[:40]+"..."
00473 iter = lstore.append()
00474 selected = True
00475 if plugin['filename'] in self.pyjama.settings.get_value("PLUGINS", "blacklist", ""):
00476 selected = False
00477 lstore.set(iter,
00478 COLUMN_SELECTED, selected,
00479 COLUMN_NAME, "%s\n%s" % (name, description),
00480 COLUMN_ID, idstr
00481 )
00482
00483 for plugin in self.pyjama.plugins.ignored:
00484 name = plugin['name']
00485 idstr = plugin['filename']
00486 description = plugin['description']
00487 if len(description)>40:description=description[:40]+"..."
00488 iter = lstore.append()
00489 selected = False
00490 if not plugin['filename'] in self.pyjama.settings.get_value("PLUGINS", "blacklist", "") and not plugin['filename']+"-" in sys.argv:
00491 if plugin['autoload'] == "true" or plugin['filename'] in self.pyjama.settings.get_value("PLUGINS", "whitelist", ""):
00492 selected = True
00493 lstore.set(iter,
00494 COLUMN_SELECTED, selected,
00495 COLUMN_NAME, "%s\n%s" % (name, description),
00496 COLUMN_ID, idstr
00497 )
00498
00499 lstore.set_sort_column_id(COLUMN_NAME,gtk.SORT_ASCENDING)
00500
00501 return lstore
00502
00503
00504
00505
00506
00507
00508
00509
00510 def select_toggled(self, cell, path, model):
00511
00512 iter = model.get_iter((int(path),))
00513 fixed = model.get_value(iter, COLUMN_SELECTED)
00514
00515
00516 fixed = not fixed
00517
00518
00519 model.set(iter, COLUMN_SELECTED, fixed)
00520
00521
00522
00523
00524 def ShowPluginsDialog(pyjama):
00525 dialog = PluginDialog(pyjama)
00526 model = dialog.model
00527 result = dialog.run()
00528 dialog.destroy()
00529 if result == 1:
00530 blacklist = pyjama.settings.get_value("PLUGINS", 'blacklist', "")
00531 whitelist = pyjama.settings.get_value("PLUGINS", "whitelist", "")
00532 changes = None
00533 iter = model.get_iter_first()
00534
00535 activated_browser = ""
00536
00537 while iter:
00538 checked, name, idstr = ( model.get(iter, 0, 1, 2) )
00539 if checked == True:
00540 if pyjama.plugins.plugins_by_name[idstr]['autoload'] == "false" and not idstr in whitelist:
00541 whitelist += " %s" % idstr
00542 changes = True
00543 print "added %s to whitelist" % idstr
00544 if idstr == "mozplug":
00545 activated_browser += "mozplug"
00546 elif idstr == "webkit-plugin":
00547 activated_browser += "webkit-plugin"
00548 elif idstr in blacklist:
00549 blacklist = blacklist.replace(idstr, "")
00550 changes = True
00551 print "removed %s from blacklist" % idstr
00552 else:
00553 if pyjama.plugins.plugins_by_name[idstr]['autoload'] == "false":
00554 if idstr in whitelist:
00555 whitelist = whitelist.replace(idstr, "")
00556 changes = True
00557 print "removed %s from whitelist" % idstr
00558 elif not idstr in blacklist:
00559 changes = True
00560 blacklist += " %s" % idstr
00561 print "added %s to blacklist" % idstr
00562 iter = model.iter_next(iter)
00563 pyjama.settings.set_value("PLUGINS", 'blacklist', blacklist)
00564 pyjama.settings.set_value("PLUGINS", 'whitelist', whitelist)
00565 if changes is True:
00566 dia = gtk.MessageDialog(pyjama.window, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, _("You (un)selected some plugins.\nPlease note, that you will need to restart pyjama\nto let the changes take effect."))
00567 dia.run()
00568 dia.destroy()
00569
00570
00571
00572
00573
00574
00575