def addHostClicked(self, hostn):
     try:
         ip = socket.gethostbyname(hostn.strip())
         get_server().call_request_info([ip])
     except:
         d = QMessageBox(QMessageBox.Critical, "Error adding host", "Cannot add host: Hostname unknown: %s" % hostn, QMessageBox.Ok, self.mainWindow)
         d.exec_()
Beispiel #2
0
 def __init__(self):
     cmd.Cmd.__init__(self)
     LunchServerController.__init__(self)
     
     self.logger = newLogger("cli")
     self.prompt = "> "
     self.commands = set(["exit"])
     self.addModule(CLIMessageHandling())  
     self.addModule(CLIOptionHandling())
     self.addModule(CLIPluginHandling(self))
     self.addModule(CLIPrivacyHandling())
     self.addModule(CLILoggingHandling())
     
     get_server().initialize(self)
     
     if get_settings().get_plugins_enabled():
         for pluginInfo in get_plugin_manager().getAllPlugins():
             if pluginInfo.plugin_object.is_activated:
                 self.addModule(pluginInfo.plugin_object)
             
     get_notification_center().connectApplicationUpdate(self.notifyUpdates)
             
     self.exitCode = 0
     # if serverStopped is called, we can determine if it was a regular exit.
     self.cleanExit = False
     self.initialized = False
Beispiel #3
0
def restartWithCommands(commands, logger):
    """
    Restart Lunchinator and execute commands in background while it is stopped.
    commands: lunchinator.commands.Commands instance
    """
    from lunchinator import get_server
    try:
        # copy restart script to safe place
        shutil.copy(get_settings().get_resource("bin", "restart.py"), get_settings().get_main_config_dir())
        
        startCmd = _getStartCommand(logger)
        args = [_getPythonInterpreter(), get_settings().get_config("restart.py"),
                "--lunchinator-path", get_settings().get_main_package_path(),
                "--start-cmd", json.dumps(startCmd),
                "--pid", str(os.getpid())]
        if commands != None:
            args.extend(["--commands", commands.toString()])
        
        spawnProcess(args, logger)
    except:
        logger.exception("Error in restartWithCommands")
        return
    if get_server().getController() != None:
        get_server().getController().shutdown()
    else:
        sys.exit(0)
Beispiel #4
0
 def performAction(self, peerID, peerInfo, parent):
     from PyQt4.QtGui import QFileDialog
     fname = QFileDialog.getOpenFileName(parent, 'Pipe file')
     
     with open(fname, 'r') as f:        
         data = f.read()
     get_server().call("HELO_PIPE "+data, peerIDs=[peerID])
 def announce_pic(self,account_name,url_text_tuple, peerIDs = []):        
     if len(url_text_tuple[0]):
         with contextlib.closing(StringIO()) as strOut:
             writer = csv.writer(strOut, delimiter = ' ', quotechar = '"')
             writer.writerow([url_text_tuple[0].encode("utf-8"), 
                              url_text_tuple[1].encode("utf-8"), account_name])
             get_server().call('HELO_REMOTE_PIC %s' % strOut.getvalue(), peerIDs)
    def _find_remote_calls(self):
        import twitter
        get_server().call("HELO_TWITTER_REMOTE %s"%self._own_screen_name)          
        with self._lock:      
            try:  
                if 0 == self._mentions_since_id:
                    #determine the start
                    ments = self._twitter_api.GetMentions(count=1)
                    if len(ments):
                        self._mentions_since_id = ments[0].GetId()
                    else:
                        self._mentions_since_id = 1
                    self.logger.debug("Twitter: Starting with mentions ID %s", self._mentions_since_id)
                    return    
                
                ments = self._twitter_api.GetMentions(since_id=self._mentions_since_id)
                if 0==len(ments):
                    self.logger.debug("Twitter: Nobody mentioned me since %s", self._mentions_since_id)
                    return
                self._mentions_since_id = ments[0].GetId()
                for m in ments:
                    self.logger.debug("Twitter: I was mentioned: %s %s", m.GetUser(), m.GetText())
                    s_name = m.GetUser().GetScreenName()
                    if s_name not in self._remote_callers:
                        self.logger.debug("Twitter: I do not know him")
#                         self._twitter_api.PostUpdate(u"@"+s_name+u" Sorry, I do not know you", m.GetId())
                        continue
                    get_server().call("Remote call by @%s: %s"%(s_name,m.GetText()))
                    self._twitter_api.PostUpdate(u"@"+s_name+u" OK, I forwarded your message", m.GetId())
            except twitter.TwitterError as t:
                if t[0][0][u'code']==88:
                    raise
                else:
                    self.logger.error("Twitter: Error while trying to retrieve mentions %s", str(t))   
 def sendMessage(self, otherID, msgHTML, msgID=None, msgTime=None, isNoResend=False):
     otherID = convert_string(otherID)
     msgHTML = convert_string(msgHTML)
     
     if msgID == None:
         msgID = self._getNextMessageID()
         isResend = False
     else:
         isResend = True
         
     if isNoResend:
         isResend = False
     
     if msgTime == None:
         msgTime = time()
     
     msgDict = {u"id": msgID,
                u"format": u"html",
                u"data": msgHTML,
                u"time": msgTime}
     
     try:
         msgDictJSON = json.dumps(msgDict)
     except:
         self.logger.exception("Error serializing private message: %s", msgDict)
         return
     
     get_server().call("HELO_PM " + msgDictJSON, peerIDs=[otherID])
     self._waitingForAck[msgID] = (otherID,
                                   time() if isResend else msgTime,
                                   msgHTML,
                                   isResend)
Beispiel #8
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
 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()
 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()
Beispiel #11
0
def getValidQtParent():
    from lunchinator import get_server
    from PyQt4.QtCore import QObject
    if isinstance(get_server().controller, QObject):
        return get_server().controller
    elif isinstance(qtParent, QObject):
        return qtParent
    raise Exception("Could not find a valid QObject instance")
 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)
 def _checkSendInfoDict(self, pluginName, category):
     pluginName = convert_string(pluginName)
     category = convert_string(category)
     pi = get_plugin_manager().getPluginByName(pluginName, category)
     if pi != None:
         po = pi.plugin_object
         if po.extendsInfoDict():
             get_server().call_info()
Beispiel #14
0
 def activate(self):
     iface_called_plugin.activate(self)
     '''do something when the user activates the plugin'''     
     
     '''to send a message'''
     get_server().call_all_members("this is a message sent by the example plugin")
     
     '''to send an event'''
     get_server().call_all_members("HELO_EXAMPLE an event of typ HELO_EXAMPLE")
Beispiel #15
0
 def create_widget(self, parent):
     from rot13.rot13box import rot13box
     
     w = rot13box(parent)
     with get_server().get_messages():
         if len(get_server().get_messages()) > 0:
             w.encodeText(get_server().get_messages().getLatest()[2])
         
     return w
Beispiel #16
0
 def callForLunch(self):
     optmsg = ""
     if self.sendMessageField != None:
         optmsg = convert_string(self.sendMessageField.text())
         self.sendMessageField.clear()
         
     if len(optmsg) > 0:
         get_server().call_all_members(optmsg)
     else:
         get_server().call_all_members(get_settings().get_lunch_trigger())
Beispiel #17
0
def displayNotification(name, msg, logger, icon=None):
    if msg == None:
        msg = u""
    myPlatform = getPlatform()
    try: 
        from lunchinator import get_server
        if not lunchinator_has_gui():
            print time.strftime("%Y-%m-%d %H:%M"),name, msg
    except:
        print time.strftime("%Y-%m-%d %H:%M"),name, msg
    
    try:
        if myPlatform == PLATFORM_LINUX:
            fileToClose = None
            if icon is None or not os.path.exists(icon):
                icon = ""
            elif _mustScaleNotificationIcon():
                import Image
                im = Image.open(icon)
                im.thumbnail((64,64), Image.ANTIALIAS)
                fileToClose = NamedTemporaryFile(suffix='.png', delete=True)
                im.save(fileToClose, "PNG")
                fileToClose.flush()
                icon = fileToClose.name
            subprocess.call(["notify-send","--icon="+icon, name, msg])
            if fileToClose is not None:
                fileToClose.close()
        elif myPlatform == PLATFORM_MAC:
            fh = open(os.path.devnull,"w")
            exe = getBinary("terminal-notifier", os.path.join("bin", "terminal-notifier.app", "Contents", "MacOS"))
            if not exe:
                logger.warning("terminal-notifier not found.")
                return
            
            call = [exe, "-title", "Lunchinator: %s" % name, "-message", msg]
            if False and checkBundleIdentifier(_LUNCHINATOR_BUNDLE_IDENTIFIER): # no sender until code signing is fixed (probably never)
                call.extend(["-sender", _LUNCHINATOR_BUNDLE_IDENTIFIER])
                
            logger.debug(call)
            try:
                subprocess.call(call, stdout=fh, stderr=fh)
            except OSError as e:
                if e.errno == errno.EINVAL:
                    logger.warning("Ignoring invalid value on Mac")
                else:
                    raise
            except:
                logger.exception("Error calling %s", call)
        elif myPlatform == PLATFORM_WINDOWS:
            from lunchinator import get_server
            if hasattr(get_server().controller, "statusicon"):
                get_server().controller.statusicon.showMessage(name,msg)
    except:
        logger.exception("error displaying notification")
 def request_log(self, member=None, logNum=0):
     if member == None:
         member = self.get_selected_log_member()
     if member != None:
         self.logger.debug("Requesting log %d from %s", logNum, member)
         get_server().call(
             "HELO_REQUEST_LOGFILE %s %d" % (DataReceiverThread.getOpenPort(category="log%s" % member), logNum),
             set([member]),
         )
     else:
         self.log_area.setText("No Member selected!")
Beispiel #19
0
 def do_call(self, args):
     """
     Call for lunch.
     Usage: call                             - Call all members
            call <member1> [<member2> [...]] - Call specific members 
     """
     args = args.decode('utf-8')
     args = self.getArguments(args)
     try:
         get_server().call("lunch", peerIPs=self.getHostList(args))
     except:
         getCoreLogger().exception("Error calling")
Beispiel #20
0
def stopWithCommands(args, logger):
    """
    Stops Lunchinator and execute commands
    """
    from lunchinator import get_server
    try:        
        spawnProcess(args, logger)
    except:
        logger.exception("Error in stopWithCommands")
        return
    if get_server().getController() != None:
        get_server().getController().shutdown()
Beispiel #21
0
 def sendRemotePicture(self, peerID, peerInfo, parent):
     from remote_pictures.remote_pictures_dialog import RemotePicturesDialog
     dialog = RemotePicturesDialog(parent, peerID, peerInfo)
     result = dialog.exec_()
     if result == RemotePicturesDialog.Accepted:
         data = [dialog.getURL().encode('utf-8')]
         if dialog.getDescription():
             data.append(dialog.getDescription().encode('utf-8'))
             if dialog.getCategory():
                 data.append(dialog.getCategory().encode('utf-8'))
         with contextlib.closing(StringIO()) as strOut:
             writer = csv.writer(strOut, delimiter = ' ', quotechar = '"')
             writer.writerow(data)
             get_server().call("HELO_REMOTE_PIC " + strOut.getvalue(), peerIDs=[peerID])
Beispiel #22
0
 def parse_json(self, http_result):
     if not http_result:
         return False
     
     j = json.loads(http_result)
     
     oldurl = self.pic_url
     self.pic_url = j['response']['posts'][0]['photos'][0]['original_size']['url']
     if oldurl != self.pic_url:
         self.logger.info("TDT: New picture! Yeay!")
         get_server().call("HELO_TDTNOTIFY_NEW_PIC " + self.pic_url)
         with contextlib.closing(StringIO()) as strOut:
             writer = csv.writer(strOut, delimiter=' ', quotechar='"')
             writer.writerow([self.pic_url, "new picture from %s" % time.strftime("%b %d %Y %H:%M"), "TDT"])
             get_server().call('HELO_REMOTE_PIC %s' % strOut.getvalue())
 def settingsDialogAction(self, saved):
     if not get_settings().get_plugins_enabled():
         return
     for pluginInfo in get_plugin_manager().getAllPlugins():
         if pluginInfo.plugin_object.is_activated and self.settingsWindow.isOptionsWidgetLoaded(pluginInfo.name):
             if saved:
                 try:
                     pluginInfo.plugin_object.save_options_widget_data(sendInfoDict=False)
                 except:
                     getCoreLogger().exception("was not able to save data for plugin %s", pluginInfo.name)
             else:
                 pluginInfo.plugin_object.discard_changes()
     get_settings().write_config_to_hd()
         
     get_server().call_info()      
Beispiel #24
0
def restart(logger):
    """Restarts the Lunchinator"""
    try:
        #on Windows with pyinstaller we use this special handling for now
        if getPlatform()==PLATFORM_WINDOWS:  
            frozen = getattr(sys, 'frozen', '')
            if frozen:
                logger.debug("Trying to spawn %s", sys.executable)
                from lunchinator import get_server
                get_server().stop_server()
                subprocess.Popen(sys.executable, creationflags=subprocess.CREATE_NEW_PROCESS_GROUP, close_fds=True)
                
        restartWithCommands(None, logger)
    except:
        logger.exception("Error restarting")
Beispiel #25
0
 def process_event(self, cmd, value, ip, member_info, _prep):
     if len(value)==0:
         return
     
     if cmd == "HELO_TWITTER_USER":
         screen_name = value[1:] if value[0] == "@" else value
         if not self.other_twitter_users.has_key(ip) or self.other_twitter_users[ip] != screen_name:
             self.other_twitter_users[ip] = screen_name        
     
     elif cmd == "HELO_TWITTER_REMOTE":
         screen_name = value[1:] if value[0] == "@" else value
         self.remote_account = screen_name
         self.remote_member = member_info['name'] if member_info and member_info.has_key("name") else ip
         get_server().call("HELO_TWITTER_USER %s" % self.options["twitter_account"])
         self.set_widget_message()
Beispiel #26
0
 def updateMsgMenu(self):
     self.msgMenu.clear()
     messages = get_server().get_messages()
     with messages:
         for i in xrange(len(messages) - 1, len(messages) - 1 - min(10, len(messages)), -1):
             message = messages[i]
             self.msgMenu.addAction(message[2], partial(self.encodeText, message[2]))
def sendMessage(msg, cli):
    if msg == None:
        msg = "lunch"

    get_settings().set_plugins_enabled(False)
    recv_nr = get_server().perform_call(msg, peerIDs=[], peerIPs=[cli])
    print "sent to", recv_nr, "clients"
Beispiel #28
0
 def do_send(self, args):
     """
     Send a message.
     Usage: send <message>                             - Send message to all members
            send <message> <member1> [<member2> [...]] - Send message to specific members 
     """
     if len(args) == 0:
         self.printHelp("send")
         return False
     
     args = self.getArguments(args)
     message = args.pop(0)
     try:
         get_server().call(message, peerIPs=self.getHostList(args))
     except:
         getCoreLogger().exception("Error sending")
Beispiel #29
0
 def statsDB(self):
     stats = get_server().getDBConnection()
     if stats == None and not self.statDBErrorLogged:
         self.statDBErrorLogged = True
         log_error(
             "Lunch Statistics Plugin: No database connection available.")
     return stats
 def _transferCanceled(self, thread):
     peerID, transferID = thread.getUserData()
     sendCancel = False
     isUpload = False
     if type(thread) is DataSenderThread:
         if transferID in self._outgoing:
             del self._outgoing[transferID]
             sendCancel = True
             isUpload = True
     else:
         if (peerID, transferID) in self._incoming:
             del self._incoming[(peerID, transferID)]
             sendCancel = True
     if sendCancel:
         cancelDict = {u"id" : transferID,
                       u"up" : isUpload}
         get_server().call("HELO_FT_CANCEL %s" % json.dumps(cancelDict), peerIDs=[peerID])
 def quit(self, exitCode=0):
     if self.mainWindow is not None:
         self.mainWindow.close()
     if self.settingsWindow is not None:
         self.settingsWindow.close()
     
     if self.serverThread != None and not sip.isdeleted(self.serverThread) and self.serverThread.isRunning():
         self.serverThread.finished.disconnect(self.serverFinishedUnexpectedly)
         get_server().stop_server()
         getCoreLogger().info("Waiting maximal 30s for server to stop...")
         # wait maximal 30s 
         if self.serverThread.wait(30000):
             getCoreLogger().info("server stopped")
         else:
             getCoreLogger().warning("server not stopped properly")
     else:
         getCoreLogger().info("server not running")
     
     if self.running:
         if get_settings().get_plugins_enabled():
             get_plugin_manager().deactivatePlugins(get_plugin_manager().getAllPlugins(), save_state=False)
             getCoreLogger().info("all plug-ins deactivated")
         if self.mainWindow is not None:
             self.mainWindow.finish()
         if self.settingsWindow is not None:
             self.settingsWindow.finish()
         self.running = False
         
     finalExitCode = 0
     if exitCode != 0:
         finalExitCode = exitCode
     elif self.exitCode != 0:
         finalExitCode = self.exitCode
     else:
         finalExitCode = get_server().exitCode
         
     get_settings().write_config_to_hd()
     DataReceiverThread.cleanup()
         
     self.exitCode = finalExitCode
     
     self._coldShutdown(finalExitCode)
     return finalExitCode
Beispiel #32
0
 def take_picture(self):
     import time
     import picamera
     
     filename = "raspicam.png"
     
     with picamera.PiCamera() as camera:
         camera.resolution = (1024, 768)
         camera.start_preview()
         # Camera warm-up time
         time.sleep(2)
         camera.capture(os.path.join(self.options["picture_path"], filename))
         self.logger.debug("Picture taken with camera")
     
     if self.options["http_server"]:
         with contextlib.closing(StringIO()) as strOut:
             writer = csv.writer(strOut, delimiter=' ', quotechar='"')
             #add the time to the URL to make remote picture aware of this being a new picture but still overwrite the old one
             pic_url = "http://%s:%d/%s?time=%d" % (self.options["http_hostname"], self.options["http_port"], filename, int(time.time()))
             writer.writerow([pic_url, "Picamera picture taken at %s" % time.strftime("%b %d %Y %H:%M"), "raspicam"])
             get_server().call('HELO_REMOTE_PIC %s' % strOut.getvalue())
 def send_command(self, cmd, peerID=None):
     if peerID:
         get_server().call("HELO_USBROCKET %s" % cmd, peerIDs=[peerID])
     else:
         get_server().call("HELO_USBROCKET %s" % cmd)
Beispiel #34
0
class panic_button_listener(Thread):
    idVendor = None
    idProduct = None
    running = True
    msg = "lunch panic"

    def __init__(self, idV, idP, msg):
        super(panic_button_listener, self).__init__()
        self.idVendor = idV
        self.idProduct = idP
        self.msg = msg

    def findButton(self):
        for bus in usb.busses():
            for dev in bus.devices:
                if dev.idVendor == self.idVendor and dev.idProduct == self.idProduct:
                    return dev
        return None

    def run(self):
        dev = self.findButton()
        if dev == None:
            log_error("Cannot find panic button device")
            return
        handle = dev.open()
        interface = dev.configurations[0].interfaces[0][0]
        endpoint = interface.endpoints[0]

        try:
            handle.detachKernelDriver(interface)
        except Exception, _:
            # It may already be unloaded.
            pass

        handle.claimInterface(interface)

        unbuffer = False
        while self.running:
            # USB setup packet. I think it's a USB HID SET_REPORT.
            result = handle.controlMsg(
                requestType=0x21,  # OUT | CLASS | INTERFACE
                request=0x09,  # SET_REPORT
                value=0x0200,  # report type: OUTPUT
                buffer="\x00\x00\x00\x00\x00\x00\x00\x02")

            try:
                result = handle.interruptRead(endpoint.address,
                                              endpoint.maxPacketSize)
                if 22 == result[0]:
                    if not unbuffer:
                        log_info("pressed the Panic Button")
                        get_server().call_all_members(self.msg)
                    unbuffer = True
                else:
                    unbuffer = False
                #print [hex(x) for x in result]
            except Exception, _:
                # Sometimes this fails. Unsure why.
                pass

            time.sleep(endpoint.interval / float(1000))