示例#1
0
 def createTrayIcon(self):
     if platform.linux_distribution()[0] == "Ubuntu":
         if not os.path.exists('/usr/share/icons/ubuntu-mono-light/status/24/lunchinator.svg') or \
            not os.path.exists('/usr/share/icons/ubuntu-mono-dark/status/24/lunchinator.svg'):
             result = QMessageBox.question(self.mainWindow,
                                           "Install Icons",
                                           "Do you want to install the Lunchinator icons into the Ubuntu theme folders? You will have to enter your sudo password.",
                                           buttons=QMessageBox.Yes | QMessageBox.No,
                                           defaultButton=QMessageBox.Yes)
             if result == QMessageBox.Yes:
                 if subprocess.call(['gksu', get_settings().get_resource('bin', 'install-lunch-icons.sh') + ' lunchinator']) == 0:
                     getCoreLogger().info("restarting after icons were installed")
                     restart(getCoreLogger())
                     return False
                 else:
                     QMessageBox.critical(self.mainWindow,
                                          "Error installing icons",
                                          "The icons were not installed, there was an error.",
                                          buttons=QMessageBox.Ok,
                                          defaultButton=QMessageBox.Ok)
                     getCoreLogger().info("icons were not installed because of an error")
     
     # initialize tray icon
     self.statusicon = QSystemTrayIcon(self.mainWindow)
     # _highlightIcon sets the default icon
     self._highlightIcon()
     contextMenu = self.init_menu(self.mainWindow)
     self.statusicon.activated.connect(self.trayActivated)
     self.statusicon.setContextMenu(contextMenu)
     self.statusicon.show()
     return True
示例#2
0
 def run(self):
     try:
         get_server().start_server()
     except:
         from lunchinator.log import getCoreLogger
         getCoreLogger().exception("Exception in Lunch Server")
         get_server().running = False
示例#3
0
 def changeNextLunchTime(self, begin = None, end = None):
     if begin == None:
         if self.mainWindow == None:
             getCoreLogger().error("mainWindow is not initialized")
             return
         from lunchinator.timespan_input_dialog import TimespanInputDialog
         dialog = TimespanInputDialog(self.mainWindow, "Change Lunch Time", "When are you free for lunch today?", get_settings().get_next_lunch_begin(), get_settings().get_next_lunch_end())
         dialog.exec_()
         if dialog.result() == QDialog.Accepted:
             get_settings().set_next_lunch_time(dialog.getBeginTimeString(), dialog.getEndTimeString())
         else:
             return        
     else:
         get_settings().set_next_lunch_time(begin, end) 
         
     if self.resetNextLunchTimeTimer != None:
         self.resetNextLunchTimeTimer.stop()
         self.resetNextLunchTimeTimer.deleteLater()
         
     td = get_settings().get_next_lunch_reset_time()
     if td > 0:
         self.resetNextLunchTimeTimer = QTimer(getValidQtParent())
         self.resetNextLunchTimeTimer.timeout.connect(self._resetNextLunchTime)
         self.resetNextLunchTimeTimer.setSingleShot(True)
         self.resetNextLunchTimeTimer.start(abs(td) + 1000)
         
     get_server().call_info()
    def _compress(self, value):
        import zlib

        compressedMsg = zlib.compress(value)
        self._statusByte = 0b00010000 | self._statusByte
        getCoreLogger().debug("Compression: %d -> %d"%(len(value), len(compressedMsg)))
        return compressedMsg
示例#5
0
 def activatePlugin(self, pluginInfo, save_state=True, checkDependencies=True):
     from lunchinator.utilities import handleMissingDependencies
     from lunchinator import get_server
     
     if checkDependencies:
         missing = self.checkActivation([pluginInfo])
         result = handleMissingDependencies(missing)
         if result == INSTALL_FAIL:
             # maybe there were dependencies installed, better re-check
             missing = self.checkActivation([pluginInfo])
             if missing:
                 self._logCannotLoad(pluginInfo, missing)
                 get_notification_center().emitPluginDeactivated(pluginInfo.name, pluginInfo.category)
                 return
         elif result == INSTALL_CANCEL:
             # user chose not to install -> deactivate
             get_notification_center().emitPluginDeactivated(pluginInfo.name, pluginInfo.category)
             self._deactivateMissing(missing)
             return
         elif result in (INSTALL_SUCCESS, INSTALL_IGNORE):
             missing = {}
         elif result == INSTALL_RESTART:
             # store that the plugin is activated now
             self.__addPluginToConfig(pluginInfo.category, pluginInfo.name)
             return
     
     getCoreLogger().info("Activating plugin '%s' of type '%s'", pluginInfo.name, pluginInfo.category)
     try:
         pluginInfo.plugin_object.setPluginName(pluginInfo.name)
         result = ConfigurablePluginManager.activatePluginByName(self, pluginInfo.name, category_name=pluginInfo.category, save_state=save_state)
         if self._emitSignals and result != None:
             get_notification_center().emitPluginActivated(pluginInfo.name, pluginInfo.category)
     except:
         getCoreLogger().exception("Error activating plugin '%s' of type '%s'", pluginInfo.name, pluginInfo.category)
示例#6
0
 def _checkLogMessage(self, record):
     try:
         if self._notAgain.checkState() == Qt.Checked:
             return
         if record.levelno >= logging.ERROR:
             recMsg = record.msg
             if not isinstance(recMsg, basestring):
                 recMsg = unicode(recMsg)
             err = convert_string(recMsg) % record.args
             component = record.name
             if component.startswith("lunchinator."):
                 component = component[12:]
                 
             msg = u"%s - In component %s (%s:%d):\n%s" % (strftime("%H:%M:%S", localtime(record.created)),
                                                           component,
                                                           record.pathname,
                                                           record.lineno,
                                                           err)
             if record.exc_info:
                 out = StringIO()
                 traceback.print_tb(record.exc_info[2], file=out)
                 msg += u"\nStack trace:\n" + out.getvalue() + formatException(record.exc_info) + u"\n"
                 
             self._errorLog.append(msg)
             self._empty = False
             if not self.isVisible():
                 self.showNormal()
                 self.raise_()
                 self.activateWindow()
     except:
         from lunchinator.log import getCoreLogger
         getCoreLogger().info(formatException())
示例#7
0
 def _build_info_string(self):
     from lunchinator.utilities import getPlatform, PLATFORM_LINUX, PLATFORM_MAC, PLATFORM_WINDOWS
     info_d = {u"avatar": get_settings().get_avatar_file(),
                u"name": get_settings().get_user_name(),
                u"group": get_settings().get_group(),
                u"ID": get_settings().get_ID(),
                u"next_lunch_begin":get_settings().get_default_lunch_begin(),
                u"next_lunch_end":get_settings().get_default_lunch_end(),
                u"version":get_settings().get_version(),
                u"version_commit_count":get_settings().get_commit_count(),
                u"platform": sys.platform}
     
     try:
         if getPlatform() == PLATFORM_LINUX:
             info_d[u"os"] = u" ".join(aString if type(aString) in (str, unicode) else "[%s]" % " ".join(aString) for aString in platform.linux_distribution())
         elif getPlatform() == PLATFORM_WINDOWS:
             info_d[u"os"] = u" ".join(aString if type(aString) in (str, unicode) else "[%s]" % " ".join(aString) for aString in platform.win32_ver())
         elif getPlatform() == PLATFORM_MAC:
             info_d[u"os"] = u" ".join(aString if type(aString) in (str, unicode) else "[%s]" % " ".join(aString) for aString in platform.mac_ver())
     except:
         getCoreLogger().exception("Error generating OS version string")
         
     if get_settings().get_next_lunch_begin():
         info_d[u"next_lunch_begin"] = get_settings().get_next_lunch_begin()
     if get_settings().get_next_lunch_end():
         info_d[u"next_lunch_end"] = get_settings().get_next_lunch_end()
     self.controller.extendMemberInfo(info_d)
     return json.dumps(info_d)      
示例#8
0
 def openWindowClicked(self, _=None):    
     if self.mainWindow == None:
         getCoreLogger().error("mainWindow is not initialized")
         return
     self.mainWindow.showNormal()
     self.mainWindow.raise_()
     self.mainWindow.activateWindow()
示例#9
0
 def __init__(self): 
     QObject.__init__(self)
     LunchServerController.__init__(self)
     
     getCoreLogger().info("Your PyQt version is %s, based on Qt %s", QtCore.PYQT_VERSION_STR, QtCore.QT_VERSION_STR)
     
     self._shuttingDown = False
     self.resetNextLunchTimeTimer = None
     self._updateAvailable = False
     self._repoUpdates = 0
     self._installUpdatesAction = None
     self._appUpdateStatusAction = None
     self._repoUpdateStatusAction = None
     self._restartAction = None
     self._restartStatusAction = None
     self._restartReason = u""
     self._highlightNewMessage = False
     self._highlightPeersReady = False
     
     self.exitCode = 0
     self.serverThread = None
     self.running = True
     get_server().initialize(self)
     
     self.pluginNameToMenuAction = {}
     
     # initialize main window
     self.mainWindow = LunchinatorWindow(self)
     self.settingsWindow = None
     self.errorDialog = ErrorLogDialog(self.mainWindow)
     self.setParent(self.mainWindow)
     
     if not self.createTrayIcon():
         return
     
     self.mainWindow.createMenuBar(self.pluginActions)
     
     # connect private signals
     self._initDone.connect(self.initDoneSlot)
     self._performCall.connect(self.performCallSlot)
     self._receiveFile.connect(self.receiveFileSlot)
     self._sendFile.connect(self.sendFileSlot)
     
     self._processEvent.connect(self.processEventSlot)
     self._processMessage.connect(self.processMessageSlot)
     self._updateRequested.connect(self.updateRequested)
     self._openWindow.connect(self.openWindowClicked)
     
     get_notification_center().connectApplicationUpdate(self._appUpdateAvailable)
     get_notification_center().connectOutdatedRepositoriesChanged(self._outdatedReposChanged)
     get_notification_center().connectUpdatesDisabled(self._updatesDisabled)
     get_notification_center().connectMessagePrepended(self._newMessage)
     get_notification_center().connectRestartRequired(self._restartRequired)
     get_notification_center().connectPluginActivated(self._pluginActivated)
     get_notification_center().connectPluginDeactivated(self._pluginDeactivated)
     
     self.serverThread = LunchServerThread(self)
     self.serverThread.finished.connect(self.serverFinishedUnexpectedly)
     self.serverThread.finished.connect(self.serverThread.deleteLater)
     self.serverThread.start()
示例#10
0
 def set_group(self, value, init=False):
     from lunchinator import get_server
     oldGroup = self._group
     self._group = value
     if not init:
         getCoreLogger().info("Changing Group: '%s' -> '%s'", oldGroup, self._group)
         get_server().changeGroup(unicode(value))
         get_notification_center().emitGroupChanged(oldGroup, self._group)
示例#11
0
 def _process_queued_messages(self, ip):
     with self.message_queues_lock:
         if ip in self._message_queues:
             if len(self._message_queues[ip][1]) > 0:
                 getCoreLogger().debug("Processing enqueued messages of IP %s", ip)
             for eventTime, xmsg in self._message_queues[ip][1]:
                 self._handle_event(xmsg, ip, eventTime, newPeer=False, fromQueue=True)
             del self._message_queues[ip]
示例#12
0
 def _deactivateMissing(self, missing):
     for component in missing.keys():
         pluginName, category = component
         pluginInfo = self._component.getPluginByName(pluginName, category)
         try:
             self.__removePluginFromConfig(pluginInfo.category, pluginInfo.name)
         except:
             getCoreLogger().exception("Error removing plugin %s (%s) from list of plugins to load", pluginInfo.name, pluginInfo.category)
示例#13
0
 def getOptionCategories(self):
     try:
         if get_settings().get_plugins_enabled():
             for pluginInfo in get_plugin_manager().getAllPlugins():
                 if pluginInfo.plugin_object.is_activated:
                     if pluginInfo.plugin_object.has_options():
                         yield (pluginInfo.name, pluginInfo.description)
     except:
         getCoreLogger().exception("while collecting option categories")
def showPeerActionsPopup(peerID, filterFunc, parent):
    from PyQt4.QtGui import QMenu, QCursor
    if get_peers() == None:
        getCoreLogger().warning("no lunch_peers instance available, cannot show peer actions")
        return
    if peerID:
        popupMenu = _fillPeerActionsMenu(QMenu(parent), peerID, filterFunc, parent)
        popupMenu.exec_(QCursor.pos())
        popupMenu.deleteLater()
def initializePeerActionsMenu(menu, peerID, filterFunc, parentWidget):
    menu.clear()
    if get_peers() == None:
        getCoreLogger().warning("no lunch_peers instance available, cannot show peer actions")
        return menu
    
    if peerID:
        _fillPeerActionsMenu(menu, peerID, filterFunc, parentWidget)
    return menu
def getCoreDependencies():
    try:
        req_file = get_settings().get_resource("requirements.txt")
        with open(req_file, "r") as f:
            requirements = f.readlines()
    except IOError:
        getCoreLogger().warning("requirements.txt does not exist")
        requirements = []
    return requirements
示例#17
0
 def get_option(self, o):
     """Get an option by its name."""
     methodname = "get_" + o
     if hasattr(self, methodname): 
         _member = getattr(self, methodname)
         return _member()
     else:
         getCoreLogger().warning("settings has no attribute called '%s'", o)
     return None
示例#18
0
 def _pluginActivated(self, pName, pCat):
     pName = convert_string(pName)
     pCat = convert_string(pCat)
     if pCat == "gui":
         try:
             pluginInfo = get_plugin_manager().getPluginByName(pName, u"gui")
             self.addPluginWidget(pluginInfo.plugin_object, pName)
         except:
             getCoreLogger().exception("while including plugins %s", str(sys.exc_info()))
示例#19
0
def handleMissingDependencies(missing, optionalCallback=lambda _req : True):
    """If there are missing dependencies, asks and installs them.
    
    Returns a list of components whose requirements were not fully
    installed.
    
    missing -- dictionary returned by checkRequirements(...)
    optionalCallbacl -- function that takes a requirement string and returns
                        True if the requirement is optional and False
                        otherwise.
    """
    if missing:
        if isPyinstallerBuild():
            canInstall = False
            text = u"There are missing dependencies in your PyInstaller build. " +\
                u"Unfortunately, you cannot install additional packages for a PyInstaller build."
            getCoreLogger().warning(text + u"\n The missing dependencies are: \n" + unicode(str(missing)))
        else:
            canInstall = True
            text = None
        
        if lunchinator_has_gui():
            from lunchinator.req_error_dialog import RequirementsErrorDialog
            from PyQt4.QtGui import QMessageBox
            requirements = []
            for _component, missingList in missing.iteritems():
                for dispName, req, reason, info in missingList:
                    if reason == REASON_PACKAGE_MISSING:
                        reasonStr = u"Not installed"
                    elif reason == REASON_VERSION_CONFLICT:
                        reasonStr = u"Wrong version (installed: %s)" % info.version
                    else:
                        reasonStr = u"Unknown"
                    requirements.append((req,
                                         dispName,
                                         reasonStr,
                                         optionalCallback(req)))
            f = RequirementsErrorDialog(requirements, None, canInstall, text)
            res = f.exec_()
            if res == RequirementsErrorDialog.Accepted:
                if not canInstall:
                    return INSTALL_NOT_POSSIBLE
                installRes = installDependencies(f.getSelectedRequirements())
                if installRes == INSTALL_FAIL:
                    QMessageBox.critical(None, "Install Failed", "Some dependencies could not be installed.")
                elif installRes == INSTALL_SUCCESS:
                    QMessageBox.information(None, "Install Succeeded", "Dependencies were successfully installed.")
                elif installRes == INSTALL_RESTART:
                    QMessageBox.information(None, "Install Finished", "Lunchinator needs to be restarted to complete the installation.")
                return installRes
            elif res == RequirementsErrorDialog.IGNORED:
                return INSTALL_IGNORE
            else:
                return INSTALL_CANCEL
        return INSTALL_FAIL
    return INSTALL_NOT_POSSIBLE
 def performAction(self, peerID, _peerInfo, _parent):
     try:
         from PyQt4.QtGui import QInputDialog
         oldName = get_peers().getDisplayedPeerName(pID=peerID)
         customName, ok = QInputDialog.getText(None, u"Custom Peer Name", u"Enter the displayed peer name:", text=oldName)
         if ok:
             customName = convert_string(customName)
             get_peers().setCustomPeerName(peerID, customName)
     except:
         getCoreLogger().exception("Error changing displayed peer name.")
 def extendMemberInfo(self, infoDict):
     """Add some specific information to the info dictionary"""
     if not get_settings().get_plugins_enabled():
         return
     for pluginInfo in get_plugin_manager().getAllPlugins():
         if pluginInfo.plugin_object.is_activated and pluginInfo.plugin_object.extendsInfoDict():
             try:
                 pluginInfo.plugin_object.extendInfoDict(infoDict)
             except:
                 getCoreLogger().exception(u"plugin error in %s while extending member info" % pluginInfo.name)
示例#22
0
 def _pluginWillBeDeactivated(self, pName, pCat):
     pName = convert_string(pName)
     pCat = convert_string(pCat)
     if pCat == "gui":
         pluginInfo = get_plugin_manager().getPluginByName(pName, pCat)
         try:
             pluginInfo.plugin_object.destroy_widget()
         except:
             getCoreLogger().exception("Error destroying plugin widget for plugin %s", pName)
         self.removePluginWidget(pName)
示例#23
0
 def sendFileSlot(self, addr, fileToSend, other_tcp_port, isData):
     addr = convert_string(addr)
     if isData:
         fileToSend = str(fileToSend)
         ds = DataSenderThread.sendData(addr, other_tcp_port, fileToSend, getCoreLogger(), parent=self)
     else:
         fileToSend = str(fileToSend).decode("utf-8")
         ds = DataSenderThread.sendSingleFile(addr, other_tcp_port, fileToSend, getCoreLogger(), parent=self)
     ds.finished.connect(ds.deleteLater)
     ds.start()
示例#24
0
    def __init__(self, controller):
        super(LunchinatorWindow, self).__init__(None)

        self.guiHandler = controller
        self.setWindowTitle("Lunchinator")
        self.setWindowIcon(QIcon(get_settings().get_resource("images", "lunchinator.png"))) 

        self.setDockNestingEnabled(True)
        self.setTabPosition(Qt.AllDockWidgetAreas, QTabWidget.North)
        
        self.pluginNameToDockWidget = {}
        self.objectNameToPluginName = {}
        self.pluginNameToMenus = {}
        self.settings = QSettings(get_settings().get_config("gui_settings.ini"), QSettings.IniFormat)
        
        savedGeometry = self.settings.value("geometry", None)
        savedState = self.settings.value("state", None)
        self.locked = self.settings.value("locked", QVariant(False)).toBool()
        
        self._prepareMenuBar()
        
        if savedState == None:
            # first run, create initial state
            get_plugin_manager().activatePluginByName(u"Simple View", "gui")
            get_plugin_manager().activatePluginByName(u"Auto Update", "general")
        
        # add plugins
        try:
            if get_settings().get_plugins_enabled():
                for pluginInfo in get_plugin_manager().getPluginsOfCategory("gui"):
                    if pluginInfo.plugin_object.is_activated:
                        self.addPluginWidget(pluginInfo.plugin_object, pluginInfo.name, noTabs=True)
        except:
            getCoreLogger().exception("while including plugins %s", str(sys.exc_info()))
        
        if savedGeometry != None:
            self.restoreGeometry(savedGeometry.toByteArray())
        else:
            self.centerOnScreen()
        
        if savedState != None:
            self.restoreState(savedState.toByteArray())

        get_notification_center().connectPluginActivated(self._pluginActivated)
        get_notification_center().connectPluginWillBeDeactivated(self._pluginWillBeDeactivated)
        
        if len(self.pluginNameToDockWidget) == 0 and get_settings().get_plugins_enabled():
            # no gui plugins activated, show about plugins
            get_plugin_manager().activatePluginByName(u"About Plugins", "gui")
        
        if self.locked:
            self.lockDockWidgets()
        
        # prevent from closing twice
        self.closed = False
示例#25
0
 def _check_lunch_time(self, new_value, old_value):
     if new_value == old_value:
         return new_value
     try:
         time = datetime.strptime(new_value, lunch_settings.LUNCH_TIME_FORMAT)
         if time:
             return new_value
     except:
         getCoreLogger().warning("Problem while checking the lunch time")
     getCoreLogger().warning("Illegal time format: %s", new_value)
     return old_value
示例#26
0
 def _enqueue_event(self, xmsg, ip, eventTime):
     getCoreLogger().debug("Peer of IP %s is unknown, enqueuing message", ip)
     
     with self.message_queues_lock:
         if ip in self._message_queues:
             queue = self._message_queues[ip]
         else:
             queue = (time(), [])
         
         queue[1].append((eventTime, xmsg))
         self._message_queues[ip] = queue
示例#27
0
def testReceive(openPort, targetPath, totalSize, sendDict):
    global errorReceive
    try:
        if sendDict is not None:
            dt = DataReceiverThreadBase.receive(SENDER, targetPath, openPort, sendDict, getCoreLogger())
        else:
            dt = DataReceiverThreadBase.receiveSingleFile(SENDER, targetPath, totalSize, openPort, getCoreLogger())
        dt.performReceive()
    except:
        errorReceive = True
        getCoreLogger().error(u"Error receiving: %s", formatException())
 def run(self):
     while True:
         req, args, kwargs = self.reqs.get()
         getCoreLogger().debug("processing Signal: %s", req)
         if req == 'exit': 
             break
         try:
             req(*args, **kwargs)
         except Exception, e:
             getCoreLogger().exception("Error in Signal handling; executed method: %s; Error: %s", str(req), str(e))
         except:
示例#29
0
 def get_next_lunch_reset_time(self):
     if self._next_lunch_end == None:
         return None
     
     from lunchinator.utilities import getTimeDelta
     # reset after next_lunch_end, but not before default_lunch_end
     
     tdn = getTimeDelta(self._next_lunch_end, getCoreLogger())
     tdd = getTimeDelta(self.get_default_lunch_end(), getCoreLogger())
     
     return max(tdn, tdd)
示例#30
0
 def toggle_plugin(self, p_name, p_cat, new_state):
     try:
         p_cat = convert_string(p_cat)
         p_name = convert_string(p_name)
         
         if new_state:
             get_plugin_manager().activatePluginByName(p_name, p_cat)
         else:
             get_plugin_manager().deactivatePluginByName(p_name, p_cat)
     except:
         getCoreLogger().exception("Error toggling plugin")