def _load_configured_handlers(self): """Forge an URLhandler plugin and hide it in the available ones.""" me = sys.modules[__name__] # Current module. config = Config() for key, handler in [(key, self.cmd_list[key]) for key in sorted(self.cmd_list.keys())]: # Forge a hidden/managed plugin # (names starting with an underscore will not be displayed in the preference/plugins window). rcom_name = "_RunCmdOnMatch_{}".format( key) # key is just the index # Make a handler class. RCOM = MetaRCOM(rcom_name, handler["regexp"], handler["command"]) # Instanciate the class. setattr(me, rcom_name, RCOM) if rcom_name not in AVAILABLE: AVAILABLE.append(rcom_name) dbg("add {} to the list of URL handlers: '{}' -> '{}'".format( rcom_name, RCOM.match, RCOM.cmd)) if handler['enabled'] and rcom_name not in config[ "enabled_plugins"]: config["enabled_plugins"].append(rcom_name) config.save()
def _save_config(self): config = Config() i = 0 length = len(self.cmd_list) while i < length: name = self.cmd_list[i]['name'] command = self.cmd_list[i]['command'] item = {} item['name'] = name item['command'] = command config.plugin_set(self.__class__.__name__, name, item) config.save() i = i + 1
def _save_config(self): config = Config() i = 0 length = len(self.cmd_list) while i < length: enabled = self.cmd_list[i]['enabled'] name = self.cmd_list[i]['name'] command = self.cmd_list[i]['command'] item = {} item['enabled'] = enabled item['name'] = name item['command'] = command config.plugin_set(self.__class__.__name__, name, item) config.save() i = i + 1
def _save_config(self): config = Config() config.plugin_del_config(self.__class__.__name__) i = 0 for command in [ self.cmd_list[key] for key in sorted(self.cmd_list.keys()) ] : enabled = command['enabled'] name = command['name'] command = command['command'] item = {} item['enabled'] = enabled item['name'] = name item['command'] = command item['position'] = i config.plugin_set(self.__class__.__name__, name, item) i = i + 1 config.save()
def _save_config(self): log_debug("_save_config") config = Config() config.plugin_del_config(self.__class__.__name__) i = 0 for ssh_conf in self.cmd_list : ip = ssh_conf['ip'] user = ssh_conf['user'] port = ssh_conf['port'] last_time = ssh_conf['last_time'] passwd = ssh_conf['passwd'] item = { 'ip': ip, 'user': user, 'port': port, 'last_time': last_time, 'passwd': passwd} ssh_key = user+"@"+ip config.plugin_set(self.__class__.__name__, ssh_key, item) i = i + 1 config.save()
def _save_config(self): config = Config() config.plugin_del_config(self.__class__.__name__) i = 0 for command in [ self.cmd_list[key] for key in sorted(self.cmd_list.keys()) ]: enabled = command['enabled'] regexp = command['regexp'] command = command['command'] item = {} item['enabled'] = enabled item['regexp'] = regexp item['command'] = command item['position'] = i config.plugin_set(self.__class__.__name__, regexp, item) i = i + 1 config.save() self._load_configured_handlers()
class JiraUrlPlugin(plugin.URLHandler): capabilties = ["url_handler"] handler_name = "jira_ticket" config = None plugin_name = "JiraUrlPlugin" def __init__(self): self.config = Config() if self.config.plugin_get_config(self.plugin_name) is None: for key, value in CONFIG_DEFAULTS.iteritems(): self.config.plugin_set(self.plugin_name, key, value) self.config.save() self.match = self.config.plugin_get(self.plugin_name, "match") self.jira_url = self.config.plugin_get(self.plugin_name, "jira_url") def callback(self, url): if not (self.match or self.jira_url): return for item in re.findall(self.match, url): return("%s/%s" % (self.jira_url, item))
class Online_Servers(plugin.MenuItem): capabilities = ['terminal_menu'] config_file = os.path.join(get_config_dir(), 'online_Servers') def __init__(self): self.config = Config() if not isinstance( self.config.plugin_get_config( self.__class__.__name__), dict): self.config.plugin_set_config(self.__class__.__name__, {}) self.config.save() self._authorization = dict(Authorization='Bearer ' + TOKEN) self._base_api_url = 'https://api.online.net/api/v1' self._servers_infos_file_name = '/tmp/online_servers_infos' def callback(self, menuitems, menu, terminal): item = gtk.MenuItem('Serveurs online.net') menuitems.append(item) submenu = gtk.Menu() item.set_submenu(submenu) menuitem = gtk.MenuItem('Préferences') menuitem.connect('activate', self.settings) submenu.append(menuitem) submenu.append(gtk.SeparatorMenuItem()) for server in self._load_servers_infos(): config = self.config.plugin_get_config(self.__class__.__name__) if server['hostname'] in config: port = config[server['hostname']]['port'] if config[server['hostname']]['port'] != '' else '22' user = config[server['hostname']]['user'] + '@' if config[server['hostname']]['user'] != '' else '' if config[server['hostname']]['iface'] == 'private': ip = server['ippriv'] else: ip = server['ippub'] else: port = 22 user = '' ip = server['ippub'] menuitem = gtk.MenuItem(server['hostname']) menuitem.connect( 'activate', self._execute, {'terminal' : terminal, 'command' : 'ssh -p {} {}{}'.format( port, user, ip)}) submenu.append(menuitem) menuitems.append(submenu) def settings(self, widget): dbox = gtk.Dialog( 'Configuration', None, gtk.DIALOG_MODAL, (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT)) servers_list = gtk.ListStore(str) def serverList(widget=None, overwrite=False): servers_list.clear() for server in self._load_servers_infos(overwrite=overwrite): servers_list.append([server['hostname']]) serverList() tree = gtk.TreeView(servers_list) selection = tree.get_selection() selection.set_mode(gtk.SELECTION_SINGLE) renderer = gtk.CellRendererText() column = gtk.TreeViewColumn("Serveurs", renderer, text=0) tree.append_column(column) button_box = gtk.VBox() button_edit = gtk.Button('Modifier', stock=gtk.STOCK_EDIT) button_edit.set_sensitive(False) button_edit.connect('clicked', self._edit, tree) selection.connect("changed", self._on_selection_changed, button_edit) button_refresh = gtk.Button('Rafraichir') button_refresh.connect('clicked', serverList, True) HBox = gtk.HBox() HBox.pack_start(tree) button_box.pack_start(button_edit, False, False) button_box.pack_start(button_refresh, False, False) HBox.pack_start(button_box) dbox.vbox.pack_start(HBox) dbox.show_all() if dbox.run() == gtk.RESPONSE_REJECT: dbox.destroy() return def _on_selection_changed(self, selection, data=None): data.set_sensitive(True) return def _edit(self, button, treeview): selection = treeview.get_selection() (store, iter) = selection.get_selected() selected_value = store.get_value(iter, 0) config = self.config.plugin_get_config( self.__class__.__name__) in_config = False if selected_value not in config else True dialog = gtk.Dialog( 'Paramètres liés au serveur', None, gtk.DIALOG_MODAL, ( gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, gtk.STOCK_OK, gtk.RESPONSE_ACCEPT ) ) table = gtk.Table(1, 3) label = gtk.Label('Interface:') table.attach(label, 0, 1, 0, 1) r1 = gtk.RadioButton(None, label='Privée') r2 = gtk.RadioButton(r1, label='Publique') if in_config: if config[selected_value]['iface'] == 'private': r1.set_active(1) else: r2.set_active(1) else: r2.set_active(1) table.attach(r1, 1, 2, 0, 1) table.attach(r2, 2, 3, 0, 1) dialog.vbox.pack_start(table) table = gtk.Table(1, 2) label = gtk.Label('Utilisateur:') table.attach(label, 0, 1, 1, 2) user = gtk.Entry() if in_config: user.set_text(config[selected_value]['user']) else: user.set_text('') table.attach(user, 1, 2, 1, 2) label = gtk.Label('Port:') table.attach(label, 0, 1, 2, 3) port = gtk.Entry() if in_config: port.set_text(config[selected_value]['port']) else: port.set_text('') table.attach(port, 1, 2, 2, 3) dialog.vbox.pack_start(table) dialog.show_all() data = dict() run = dialog.run() if run == gtk.RESPONSE_REJECT: dialog.destroy() if run == gtk.RESPONSE_ACCEPT: if r1.get_active(): data['iface'] = 'private' else: data['iface'] = 'public' data['user'] = user.get_text() data['port'] = port.get_text() if in_config: self.config.plugin_set_config( self.__class__.__name__, {}) self.config.save() config[selected_value] = data else: config.update({selected_value: data}) self.config.plugin_set_config( self.__class__.__name__, config) self.config.save() dialog.destroy() def _execute(self, widget, data): data['terminal'].vte.feed_child(data['command'] + '\n') @property def _servers_list(self): url = self._base_api_url + '/server' servers = requests.get( url, headers=self._authorization) servers = [server.strip(url) for server in loads(servers.text)] return servers @property def _servers_infos(self): servers = list() servers_list = self._servers_list for i, server in enumerate(servers_list): request = requests.get( self._base_api_url + '/server/' + server, headers=self._authorization) servers.append(loads(request.text)) for i, server in enumerate(list(servers)): servers[i] = dict( hostname=server['hostname'], ippub=server['network']['ip'][0] if server['network']['ip'] != [] else '', ippriv=server['network']['private'][0] if server['network']['private'] != [] else '') return servers def _save_servers_infos(self): infos = self._servers_infos pickle.dump(infos, open(self._servers_infos_file_name, 'wb+')) return infos def _load_servers_infos(self, overwrite=False): if os.path.isfile(self._servers_infos_file_name) and not overwrite: servers = pickle.load(open(self._servers_infos_file_name, 'rb')) else: servers = self._save_servers_infos() return servers
class Container(object): """Base class for Terminator Containers""" terminator = None immutable = None children = None config = None signals = None signalman = None def __init__(self): """Class initialiser""" self.children = [] self.signals = [] self.cnxids = Signalman() self.config = Config() def register_signals(self, widget): """Register gobject signals in a way that avoids multiple inheritance""" existing = GObject.signal_list_names(widget) for signal in self.signals: if signal['name'] in existing: dbg('Container:: skipping signal %s for %s, already exists' % (signal['name'], widget)) else: dbg('Container:: registering signal for %s on %s' % (signal['name'], widget)) try: GObject.signal_new(signal['name'], widget, signal['flags'], signal['return_type'], signal['param_types']) except RuntimeError: err('Container:: registering signal for %s on %s failed' % (signal['name'], widget)) def connect_child(self, widget, signal, handler, *args): """Register the requested signal and record its connection ID""" self.cnxids.new(widget, signal, handler, *args) return def disconnect_child(self, widget): """De-register the signals for a child""" self.cnxids.remove_widget(widget) def get_offspring(self): """Return a list of direct child widgets, if any""" return (self.children) def get_child_metadata(self, widget): """Return metadata that would be useful to recreate ourselves after our child is .remove()d and .add()ed""" return None def split_horiz(self, widget, cwd=None): """Split this container horizontally""" return (self.split_axis(widget, True, cwd)) def split_vert(self, widget, cwd=None): """Split this container vertically""" return (self.split_axis(widget, False, cwd)) def split_axis(self, widget, vertical=True, cwd=None, sibling=None, siblinglast=None): """Default axis splitter. This should be implemented by subclasses""" raise NotImplementedError('split_axis') def rotate(self, widget, clockwise): """Rotate children in this container""" raise NotImplementedError('rotate') def add(self, widget, metadata=None): """Add a widget to the container""" raise NotImplementedError('add') def remove(self, widget): """Remove a widget from the container""" raise NotImplementedError('remove') def replace(self, oldwidget, newwidget): """Replace the child oldwidget with newwidget. This is the bare minimum required for this operation. Containers should override it if they have more complex requirements""" if not oldwidget in self.get_children(): err('%s is not a child of %s' % (oldwidget, self)) return self.remove(oldwidget) self.add(newwidget) def hoover(self): """Ensure we still have a reason to exist""" raise NotImplementedError('hoover') def get_children(self): """Return an ordered list of the children of this Container""" raise NotImplementedError('get_children') def closeterm(self, widget): """Handle the closure of a terminal""" try: if self.get_property('term_zoomed'): # We're zoomed, so unzoom and then start closing again dbg('Container::closeterm: terminal zoomed, unzooming') self.unzoom(widget) widget.close() return (True) except TypeError: pass if not self.remove(widget): dbg('Container::closeterm: self.remove() failed for %s' % widget) return (False) self.terminator.deregister_terminal(widget) widget.close() self.terminator.group_hoover() return (True) def resizeterm(self, widget, keyname): """Handle a keyboard event requesting a terminal resize""" raise NotImplementedError('resizeterm') def toggle_zoom(self, widget, fontscale=False): """Toggle the existing zoom state""" try: if self.get_property('term_zoomed'): self.unzoom(widget) else: self.zoom(widget, fontscale) except TypeError: err('Container::toggle_zoom: %s is unable to handle zooming, for \ %s' % (self, widget)) def zoom(self, widget, fontscale=False): """Zoom a terminal""" raise NotImplementedError('zoom') def unzoom(self, widget): """Unzoom a terminal""" raise NotImplementedError('unzoom') def construct_confirm_close(self, window, reqtype): """Create a confirmation dialog for closing things""" # skip this dialog if applicable if self.config['suppress_multiple_term_dialog']: return Gtk.ResponseType.ACCEPT dialog = Gtk.Dialog(_('Close?'), window, Gtk.DialogFlags.MODAL) dialog.set_resizable(False) dialog.add_button(Gtk.STOCK_CANCEL, Gtk.ResponseType.REJECT) c_all = dialog.add_button(Gtk.STOCK_CLOSE, Gtk.ResponseType.ACCEPT) c_all.get_children()[0].get_children()[0].get_children()[1].set_label( _('Close _Terminals')) primary = Gtk.Label( label=_('<big><b>Close multiple terminals?</b></big>')) primary.set_use_markup(True) primary.set_alignment(0, 0.5) if reqtype == 'window': label_text = _('This window has several terminals open. Closing \ the window will also close all terminals within it.') elif reqtype == 'tab': label_text = _('This tab has several terminals open. Closing \ the tab will also close all terminals within it.') else: label_text = '' secondary = Gtk.Label(label=label_text) secondary.set_line_wrap(True) labels = Gtk.VBox() labels.pack_start(primary, False, False, 6) labels.pack_start(secondary, False, False, 6) image = Gtk.Image.new_from_stock(Gtk.STOCK_DIALOG_WARNING, Gtk.IconSize.DIALOG) image.set_alignment(0.5, 0) box = Gtk.HBox() box.pack_start(image, False, False, 6) box.pack_start(labels, False, False, 6) dialog.vbox.pack_start(box, False, False, 12) checkbox = Gtk.CheckButton(_("Do not show this message next time")) dialog.vbox.pack_end(checkbox, True, True, 0) dialog.show_all() result = dialog.run() # set configuration self.config.base.reload() self.config['suppress_multiple_term_dialog'] = checkbox.get_active() self.config.save() dialog.destroy() return (result) def propagate_title_change(self, widget, title): """Pass a title change up the widget stack""" maker = Factory() parent = self.get_parent() title = widget.get_window_title() if maker.isinstance(self, 'Notebook'): self.update_tab_label_text(widget, title) elif maker.isinstance(self, 'Window'): self.title.set_title(widget, title) if maker.isinstance(parent, 'Container'): parent.propagate_title_change(widget, title) def get_visible_terminals(self): """Walk the widget tree to find all of the visible terminals. That is, any terminals which are not hidden in another Notebook pane""" if not hasattr(self, 'cached_maker'): self.cached_maker = Factory() maker = self.cached_maker terminals = {} for child in self.get_offspring(): if not child: continue if maker.isinstance(child, 'Terminal'): terminals[child] = child.get_allocation() elif maker.isinstance(child, 'Container'): terminals.update(child.get_visible_terminals()) else: err('Unknown child type %s' % type(child)) return (terminals) def describe_layout(self, count, parent, global_layout, child_order): """Describe our current layout""" layout = {} maker = Factory() mytype = maker.type(self) if not mytype: err('unable to detemine own type. %s' % self) return ({}) layout['type'] = mytype layout['parent'] = parent layout['order'] = child_order if hasattr(self, 'get_position'): position = self.get_position() if hasattr(position, '__iter__'): position = ':'.join([str(x) for x in position]) layout['position'] = position if hasattr(self, 'ismaximised'): layout['maximised'] = self.ismaximised if hasattr(self, 'isfullscreen'): layout['fullscreen'] = self.isfullscreen if hasattr(self, 'ratio'): layout['ratio'] = self.ratio if hasattr(self, 'get_size'): layout['size'] = self.get_size() if hasattr(self, 'title'): layout['title'] = self.title.text if mytype == 'Notebook': labels = [] last_active_term = [] for tabnum in xrange(0, self.get_n_pages()): page = self.get_nth_page(tabnum) label = self.get_tab_label(page) labels.append(label.get_custom_label()) last_active_term.append( self.last_active_term[self.get_nth_page(tabnum)]) layout['labels'] = labels layout['last_active_term'] = last_active_term layout['active_page'] = self.get_current_page() else: if hasattr( self, 'last_active_term') and self.last_active_term is not None: layout['last_active_term'] = self.last_active_term if mytype == 'Window': if self.uuid == self.terminator.last_active_window: layout['last_active_window'] = True else: layout['last_active_window'] = False name = 'child%d' % count count = count + 1 global_layout[name] = layout child_order = 0 for child in self.get_children(): if hasattr(child, 'describe_layout'): count = child.describe_layout(count, name, global_layout, child_order) child_order = child_order + 1 return (count) def create_layout(self, layout): """Apply settings for our layout""" raise NotImplementedError('create_layout')
#!/usr/bin/env python import os import sys from terminatorlib.config import Config from terminatorlib.util import get_config_dir class Opts(object): pass opts = Opts() opts.config = os.path.join(get_config_dir(), 'config') config = Config() config.options_set(opts) # misc options config['word_chars'] = '-A-Za-z0-9,./?%&_~' config['scrollback_lines'] = 500000 config['scroll_on_output'] = False config['use_system_font'] = False config['font'] = 'Ubuntu Mono 9' config.save()