Beispiel #1
0
class RouteTableApp(QWidget):
    """
    Main view class
    This class composes the widgets for the user to choose the logs files 
    to compare and the options for the output
    """
    def __init__(self, parent=None, controller=None,  *args, **kwargs):
        super(RouteTableApp, self).__init__(parent, *args, **kwargs)
        self._parent = parent
        self._controller = controller
        self._options = self.__Options()
        self.initUI()
        logging.debug("Main RouteTableApp created {}".format(self))

    def initUI(self):
        self.setWindowTitle("Routa Table comparison")
        logo = QIcon('img/icon/logo.png')
        self.setWindowIcon(logo)

        self.qw_router1 = LogFileWidget(parent=self)
        self.qw_router1.setTitle("Previous info")
        self.qw_router2 = LogFileWidget(parent=self)
        self.qw_router2.setTitle("New info")

        self.btn_process = QPushButton("Process")
        self.btn_process.setMaximumWidth(70)
        # self.btn_process.setEnabled(False)
        self.btn_process.clicked.connect(self._process)

        self.chk_protocol = QCheckBox("include protocol?")
        self.chk_protocol.setChecked(self._options.getattribute("includeProtocolFlag"))
        self.chk_next = QCheckBox("include nexthop?")
        self.chk_next.setChecked(self._options.getattribute("includeNexthopFlag"))

        icon = QIcon('img/icon/process.svg')
        self.btn_process.setIcon(icon)

        self.menubar = QMenuBar(self)
        preferenceMenu = self.menubar.addMenu('Preferences')
        self.routerIdComparisonAction = QAction('Same Router Id', self)
        self.routerIdComparisonAction.setCheckable(True)
        self.routerIdComparisonAction.setChecked(self._options.getattribute("routerIdComparison"))
        preferenceMenu.addAction(self.routerIdComparisonAction)
        separatorMenu = preferenceMenu.addMenu("Separator")
        parserMenu = preferenceMenu.addMenu("Log type")

        # Parsers options
        self.parserAction = QActionGroup(self)
        autoAction = QAction('auto', self)
        autoAction.setCheckable(True)
        autoAction.setChecked("auto" == self._options.getattribute("parser"))
        timosAction = QAction('sros', self)
        timosAction.setCheckable(True)
        timosAction.setChecked("sros" == self._options.getattribute("parser"))
        timosBgpAction = QAction('sros bgp', self)
        timosBgpAction.setCheckable(True)
        timosBgpAction.setChecked("sros bgp" == self._options.getattribute("parser"))
        hvrpAction = QAction('hvrp', self)
        hvrpAction.setCheckable(True)
        hvrpAction.setChecked("hvrp" == self._options.getattribute("parser"))
        autoAction.triggered.connect(self._selectParser)
        timosAction.triggered.connect(self._selectParser)
        timosBgpAction.triggered.connect(self._selectParser)
        hvrpAction.triggered.connect(self._selectParser)
        self.parserAction.addAction(autoAction)
        self.parserAction.addAction(timosAction)
        self.parserAction.addAction(timosBgpAction)
        self.parserAction.addAction(hvrpAction)
        self.parserAction.setExclusive(True)
        parserMenu.addAction(autoAction)
        parserMenu.addAction(timosAction)
        parserMenu.addAction(timosBgpAction)
        parserMenu.addAction(hvrpAction)
        
        # set separators menu, mutually exclusive, and get persistent value
        self.separatorAction = QActionGroup(self)
        commaAction = QAction('comma (,)', self)
        commaAction.setCheckable(True)
        commaAction.setChecked("," in self._options.getattribute("separator"))
        semicolonAction = QAction('semicolon (;)', self)
        semicolonAction.setCheckable(True)
        semicolonAction.setChecked(";" in self._options.getattribute("separator"))
        spaceAction = QAction('space ( )', self)
        spaceAction.setCheckable(True)
        spaceAction.setChecked(" " in self._options.getattribute("separator"))
        self.separatorAction.addAction(commaAction)
        self.separatorAction.addAction(spaceAction)
        self.separatorAction.addAction(semicolonAction)
        self.separatorAction.setExclusive(True)
        commaAction.triggered.connect(self._selectSeparator)
        semicolonAction.triggered.connect(self._selectSeparator)
        spaceAction.triggered.connect(self._selectSeparator)
        separatorMenu.addAction(spaceAction)
        separatorMenu.addAction(commaAction)
        separatorMenu.addAction(semicolonAction)

        self.layout = QVBoxLayout()
        self.hlayout = QHBoxLayout()

        self.hlayout.addWidget(self.btn_process)
        self.hlayout.addWidget(self.chk_protocol)
        self.hlayout.addWidget(self.chk_next)

        self.layout.addWidget(self.menubar)
        self.layout.addWidget(self.qw_router1)
        self.layout.addWidget(self.qw_router2)
        self.layout.addLayout(self.hlayout)
        self.setLayout(self.layout)
        self.show()

    def _process(self):
        logging.debug("Button clicked {}".format(self.btn_process))
        self._controller.process()

    class __Options(object):
        """
        Hold local widget options
        """
        width = 200
        height = 100
        currentPath = ""
        compareByKey = True
        includeProtocolFlag = False
        includeNexthopFlag = False
        separator = " "
        parser = "auto"
        routerIdComparison = True

        def __init__(self):
            """
            Load default values then get the values from serialized file if any
            """
            import pickle
            try:
                with open('options.pickle', 'rb') as f:
                    self.__dict__ = pickle.load(f)
                    logging.debug("Load options widget. options {}".format(self.__dict__))
            except FileNotFoundError:
                pass

        def getattribute(self, name):
            return getattr(self, name)

        def setattr(self, name, value):
            setattr(self, name, value)
            logging.debug("Set Attr <{}> value <{}> object {}".format(name, value, self))

        def save(self):
            """
            Memento
            save class __dict__ over a persistent file
            """
            import pickle
            with open('options.pickle', 'wb') as f:
                pickle.dump(self.__dict__, f)

    def includeProtocol(self):
        return self.chk_protocol.isChecked()

    def includeNexthop(self):
        return self.chk_next.isChecked()

    def separatorChar(self):
        return self._options.separator

    def routerIdComparison(self):
        return self.routerIdComparisonAction.isChecked()

    def parserSelect(self):
        return self._options.parser
        
    def _selectSeparator(self):
        t = self.separatorAction.checkedAction().text()
        logging.debug("_selectSeparator separator <{}>".format(t))
        if ',' in t:
            self._options.setattr("separator", ',')
        elif ';' in t:
            self._options.setattr("separator", ';')
        else:
            self._options.setattr("separator", ' ')

    def _selectParser(self):
        t = self.parserAction.checkedAction().text()
        logging.debug("_selectParser parser <{}>".format(t))
        if 'auto' in t:
            self._options.setattr("parser", 'auto')
        elif 'sros' == t.strip():
            self._options.setattr("parser", 'sros')
        elif 'sros bgp' == t.strip():
            self._options.setattr("parser", 'sros bgp')
        elif 'hvrp' == t:
            self._options.setattr("parser", 'hvrp')
        else:
            self._options.setattr("parser", 'auto')
    
    def closeEvent(self, event):
        logging.debug("closing widget <{}> event <{}>".format(self, event))
        self._options.setattr("includeProtocolFlag", self.chk_protocol.isChecked())
        self._options.setattr("includeNexthopFlag", self.chk_next.isChecked())
        self._options.setattr("width", self.width())
        self._options.setattr("height", self.height())
        self._selectSeparator()
        self._selectParser()
        self._options.setattr("routerIdComparison", 
                              self.routerIdComparisonAction.isChecked())
        
        self._options.save()
        event.accept()
Beispiel #2
0
class LocationManager(QObject):  # {{{

    locations_changed = pyqtSignal()
    unmount_device = pyqtSignal()
    location_selected = pyqtSignal(object)
    configure_device = pyqtSignal()
    update_device_metadata = pyqtSignal()

    def __init__(self, parent=None):
        QObject.__init__(self, parent)
        self.free = [-1, -1, -1]
        self.count = 0
        self.location_actions = QActionGroup(self)
        self.location_actions.setExclusive(True)
        self.current_location = 'library'
        self._mem = []
        self.tooltips = {}

        self.all_actions = []

        def ac(name, text, icon, tooltip):
            icon = QIcon(I(icon))
            ac = self.location_actions.addAction(icon, text)
            setattr(self, 'location_' + name, ac)
            ac.setAutoRepeat(False)
            ac.setCheckable(True)
            receiver = partial(self._location_selected, name)
            ac.triggered.connect(receiver)
            self.tooltips[name] = tooltip

            m = QMenu(parent)
            self._mem.append(m)
            a = m.addAction(icon, tooltip)
            a.triggered.connect(receiver)
            if name != 'library':
                self._mem.append(a)
                a = m.addAction(QIcon(I('eject.png')), _('Eject this device'))
                a.triggered.connect(self._eject_requested)
                self._mem.append(a)
                a = m.addAction(QIcon(I('config.png')),
                                _('Configure this device'))
                a.triggered.connect(self._configure_requested)
                self._mem.append(a)
                a = m.addAction(QIcon(I('sync.png')),
                                _('Update cached metadata on device'))
                a.triggered.connect(
                    lambda x: self.update_device_metadata.emit())
                self._mem.append(a)

            else:
                ac.setToolTip(tooltip)
            ac.setMenu(m)
            ac.calibre_name = name

            self.all_actions.append(ac)
            return ac

        self.library_action = ac('library', _('Library'), 'lt.png',
                                 _('Show books in calibre library'))
        ac('main', _('Device'), 'reader.png',
           _('Show books in the main memory of the device'))
        ac('carda', _('Card A'), 'sd.png', _('Show books in storage card A'))
        ac('cardb', _('Card B'), 'sd.png', _('Show books in storage card B'))

    def set_switch_actions(self, quick_actions, rename_actions, delete_actions,
                           switch_actions, choose_action):
        self.switch_menu = self.library_action.menu()
        if self.switch_menu:
            self.switch_menu.addSeparator()
        else:
            self.switch_menu = QMenu()

        self.switch_menu.addAction(choose_action)
        self.cs_menus = []
        for t, acs in [(_('Quick switch'), quick_actions),
                       (_('Rename library'), rename_actions),
                       (_('Delete library'), delete_actions)]:
            if acs:
                self.cs_menus.append(QMenu(t))
                for ac in acs:
                    self.cs_menus[-1].addAction(ac)
                self.switch_menu.addMenu(self.cs_menus[-1])
        self.switch_menu.addSeparator()
        for ac in switch_actions:
            self.switch_menu.addAction(ac)

        if self.switch_menu != self.library_action.menu():
            self.library_action.setMenu(self.switch_menu)

    def _location_selected(self, location, *args):
        if location != self.current_location and hasattr(
                self, 'location_' + location):
            self.current_location = location
            self.location_selected.emit(location)
            getattr(self, 'location_' + location).setChecked(True)

    def _eject_requested(self, *args):
        self.unmount_device.emit()

    def _configure_requested(self):
        self.configure_device.emit()

    def update_devices(self, cp=(None, None), fs=[-1, -1, -1], icon=None):
        if icon is None:
            icon = I('reader.png')
        self.location_main.setIcon(QIcon(icon))
        had_device = self.has_device
        if cp is None:
            cp = (None, None)
        if isinstance(cp, (str, unicode)):
            cp = (cp, None)
        if len(fs) < 3:
            fs = list(fs) + [0]
        self.free[0] = fs[0]
        self.free[1] = fs[1]
        self.free[2] = fs[2]
        cpa, cpb = cp
        self.free[1] = fs[1] if fs[1] is not None and cpa is not None else -1
        self.free[2] = fs[2] if fs[2] is not None and cpb is not None else -1
        self.update_tooltips()
        if self.has_device != had_device:
            self.location_library.setChecked(True)
            self.locations_changed.emit()
            if not self.has_device:
                self.location_library.trigger()

    def update_tooltips(self):
        for i, loc in enumerate(('main', 'carda', 'cardb')):
            t = self.tooltips[loc]
            if self.free[i] > -1:
                t += u'\n\n%s ' % human_readable(self.free[i]) + _('available')
            ac = getattr(self, 'location_' + loc)
            ac.setToolTip(t)
            ac.setWhatsThis(t)
            ac.setStatusTip(t)

    @property
    def has_device(self):
        return max(self.free) > -1

    @property
    def available_actions(self):
        ans = [self.location_library]
        for i, loc in enumerate(('main', 'carda', 'cardb')):
            if self.free[i] > -1:
                ans.append(getattr(self, 'location_' + loc))
        return ans
Beispiel #3
0
class LocationManager(QObject):  # {{{

    locations_changed = pyqtSignal()
    unmount_device = pyqtSignal()
    location_selected = pyqtSignal(object)
    configure_device = pyqtSignal()
    update_device_metadata = pyqtSignal()

    def __init__(self, parent=None):
        QObject.__init__(self, parent)
        self.free = [-1, -1, -1]
        self.count = 0
        self.location_actions = QActionGroup(self)
        self.location_actions.setExclusive(True)
        self.current_location = 'library'
        self._mem = []
        self.tooltips = {}

        self.all_actions = []

        def ac(name, text, icon, tooltip):
            icon = QIcon(I(icon))
            ac = self.location_actions.addAction(icon, text)
            setattr(self, 'location_'+name, ac)
            ac.setAutoRepeat(False)
            ac.setCheckable(True)
            receiver = partial(self._location_selected, name)
            ac.triggered.connect(receiver)
            self.tooltips[name] = tooltip

            m = QMenu(parent)
            self._mem.append(m)
            a = m.addAction(icon, tooltip)
            a.triggered.connect(receiver)
            if name != 'library':
                self._mem.append(a)
                a = m.addAction(QIcon(I('eject.png')), _('Eject this device'))
                a.triggered.connect(self._eject_requested)
                self._mem.append(a)
                a = m.addAction(QIcon(I('config.png')), _('Configure this device'))
                a.triggered.connect(self._configure_requested)
                self._mem.append(a)
                a = m.addAction(QIcon(I('sync.png')), _('Update cached metadata on device'))
                a.triggered.connect(lambda x : self.update_device_metadata.emit())
                self._mem.append(a)

            else:
                ac.setToolTip(tooltip)
            ac.setMenu(m)
            ac.calibre_name = name

            self.all_actions.append(ac)
            return ac

        self.library_action = ac('library', _('Library'), 'lt.png',
                _('Show books in calibre library'))
        ac('main', _('Device'), 'reader.png',
                _('Show books in the main memory of the device'))
        ac('carda', _('Card A'), 'sd.png',
                _('Show books in storage card A'))
        ac('cardb', _('Card B'), 'sd.png',
                _('Show books in storage card B'))

    def set_switch_actions(self, quick_actions, rename_actions, delete_actions,
            switch_actions, choose_action):
        self.switch_menu = self.library_action.menu()
        if self.switch_menu:
            self.switch_menu.addSeparator()
        else:
            self.switch_menu = QMenu()

        self.switch_menu.addAction(choose_action)
        self.cs_menus = []
        for t, acs in [(_('Quick switch'), quick_actions),
                (_('Rename library'), rename_actions),
                (_('Delete library'), delete_actions)]:
            if acs:
                self.cs_menus.append(QMenu(t))
                for ac in acs:
                    self.cs_menus[-1].addAction(ac)
                self.switch_menu.addMenu(self.cs_menus[-1])
        self.switch_menu.addSeparator()
        for ac in switch_actions:
            self.switch_menu.addAction(ac)

        if self.switch_menu != self.library_action.menu():
            self.library_action.setMenu(self.switch_menu)

    def _location_selected(self, location, *args):
        if location != self.current_location and hasattr(self,
                'location_'+location):
            self.current_location = location
            self.location_selected.emit(location)
            getattr(self, 'location_'+location).setChecked(True)

    def _eject_requested(self, *args):
        self.unmount_device.emit()

    def _configure_requested(self):
        self.configure_device.emit()

    def update_devices(self, cp=(None, None), fs=[-1, -1, -1], icon=None):
        if icon is None:
            icon = I('reader.png')
        self.location_main.setIcon(QIcon(icon))
        had_device = self.has_device
        if cp is None:
            cp = (None, None)
        if isinstance(cp, (str, unicode)):
            cp = (cp, None)
        if len(fs) < 3:
            fs = list(fs) + [0]
        self.free[0] = fs[0]
        self.free[1] = fs[1]
        self.free[2] = fs[2]
        cpa, cpb = cp
        self.free[1] = fs[1] if fs[1] is not None and cpa is not None else -1
        self.free[2] = fs[2] if fs[2] is not None and cpb is not None else -1
        self.update_tooltips()
        if self.has_device != had_device:
            self.location_library.setChecked(True)
            self.locations_changed.emit()
            if not self.has_device:
                self.location_library.trigger()

    def update_tooltips(self):
        for i, loc in enumerate(('main', 'carda', 'cardb')):
            t = self.tooltips[loc]
            if self.free[i] > -1:
                t += u'\n\n%s '%human_readable(self.free[i]) + _('available')
            ac = getattr(self, 'location_'+loc)
            ac.setToolTip(t)
            ac.setWhatsThis(t)
            ac.setStatusTip(t)

    @property
    def has_device(self):
        return max(self.free) > -1

    @property
    def available_actions(self):
        ans = [self.location_library]
        for i, loc in enumerate(('main', 'carda', 'cardb')):
            if self.free[i] > -1:
                ans.append(getattr(self, 'location_'+loc))
        return ans