def eventTap(self, proxy, type_, event, refcon): import utils if type_ < 0 or type_ > 0x7fffffff: print "eventTrap: got", hex(type_) # This might be kCGEventTapDisabledByTimeout. # If we would just pass it, we would get an exception in runEventsCapture like: # error: NSInternalInconsistencyException - Invalid parameter not satisfying: cgsEvent.type > 0 && cgsEvent.type <= kCGSLastEventType # See <http://stackoverflow.com/q/16190680/133374>. # However, just passing None is also not a solution because this event tap # is disabled from now on. Thus we must restart it. def doRestart(): self.stop() self.start() utils.daemonThreadCall(doRestart) return None from AppKit import NSKeyUp, NSEvent # Convert the Quartz CGEvent into something more useful keyEvent = NSEvent.eventWithCGEvent_(event) if keyEvent.subtype() is 8: # subtype 8 is media keys data = keyEvent.data1() keyCode = (data & 0xFFFF0000) >> 16 keyState = (data & 0xFF00) >> 8 if keyCode in self._keyControls: if keyState == NSKeyUp: # debug timeout #import time #time.sleep(1) # We want to avoid timeouts, so do this in another thread. utils.daemonThreadCall(self.onMediaKeyUp, args=(self._keyControls[keyCode], ), name="onMediaKeyUp") return None # consume event return event # pass through
def eventTap(self, proxy, type_, event, refcon): import utils if type_ < 0 or type_ > 0x7fffffff: print "eventTrap: got", hex(type_) # This might be kCGEventTapDisabledByTimeout. # If we would just pass it, we would get an exception in runEventsCapture like: # error: NSInternalInconsistencyException - Invalid parameter not satisfying: cgsEvent.type > 0 && cgsEvent.type <= kCGSLastEventType # See <http://stackoverflow.com/q/16190680/133374>. # However, just passing None is also not a solution because this event tap # is disabled from now on. Thus we must restart it. def doRestart(): self.stop() self.start() utils.daemonThreadCall(doRestart) return None from AppKit import NSKeyUp, NSEvent # Convert the Quartz CGEvent into something more useful keyEvent = NSEvent.eventWithCGEvent_(event) if keyEvent.subtype() is 8: # subtype 8 is media keys data = keyEvent.data1() keyCode = (data & 0xFFFF0000) >> 16 keyState = (data & 0xFF00) >> 8 if keyCode in self._keyControls: if keyState == NSKeyUp: # debug timeout #import time #time.sleep(1) # We want to avoid timeouts, so do this in another thread. utils.daemonThreadCall(self.onMediaKeyUp, args=(self._keyControls[keyCode],), name="onMediaKeyUp") return None # consume event return event # pass through
def listenThread(): print "socketcontrol: listening on", sockfilename while True: conn, address = s.accept() print "socketcontrol: accepted", address utils.daemonThreadCall(lambda: handleConnection(conn), name="socketcontrol.handleConnection")
def socketcontrolMain(): import tempfile tmpdir = tempfile.gettempdir() or "/tmp" sockfilename = "%s/%s-%i-socketcontrol" % (tmpdir, appinfo.appid, os.getpid()) globals()["socketfile"] = sockfilename # copy import socket s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) s.bind(sockfilename) os.chmod(sockfilename, 0700) s.listen(1) def listenThread(): print "socketcontrol: listening on", sockfilename while True: conn, address = s.accept() handleConnection(conn, address) conn, address = None, None # remove refs here utils.daemonThreadCall(listenThread, name="socketcontrol.listen") from State import state for ev,args,kwargs in state.updates.read(): pass try: s.shutdown(socket.SHUT_RDWR) except Exception: pass try: s.close() except Exception: pass try: os.unlink(sockfilename) except Exception: pass
def listenThread(s): import socket while s: try: conn, addr = s.accept() except socket.timeout: continue except socket.error: break utils.daemonThreadCall(handleConnection, args=(conn, addr), name="mpdBackend.handleConnection") conn, addr = None, None # remove refs here
def _startSearch(self, txt): def search(): with self._lock: if self._searchText != txt: return res = songdb.search(txt) with self._lock: if self._searchText == txt: self._searchResults = res self.searchResults_updateEvent.push() with self._lock: self._searchText = txt utils.daemonThreadCall(search, name="Song DB search")
def _startSearch(self, txt): def search(): with self._lock: if self._searchText != txt: return res = songdb.search(txt) with self._lock: if self._searchText == txt: self._searchResults = res self.__class__.searchResults.updateEvent(self).push() with self._lock: self._searchText = txt utils.daemonThreadCall(search, name="Song DB search")
def socketcontrolMain(): import tempfile tmpdir = tempfile.gettempdir() or "/tmp" sockfilename = "%s/%s-%i-socketcontrol" % (tmpdir, appinfo.appid, os.getpid()) globals()["socketfile"] = sockfilename # copy import socket s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) s.bind(sockfilename) os.chmod(sockfilename, 0700) s.listen(1) def listenThread(): print "socketcontrol: listening on", sockfilename while True: conn, address = s.accept() print "socketcontrol: accepted", address utils.daemonThreadCall(lambda: handleConnection(conn), name="socketcontrol.handleConnection") utils.daemonThreadCall(listenThread, name="socketcontrol.listen") from State import state for ev, args, kwargs in state.updates.read(): pass try: s.shutdown(socket.SHUT_RDWR) except Exception: pass try: s.close() except Exception: pass try: os.unlink(sockfilename) except Exception: pass
def songdbMain(): # This is heavy, ugly, etc... # But it's simple nice hack for now to index everything. def indexAll(): import appinfo for dir in appinfo.musicdirs: utils.asyncCall(lambda: indexSearchDir(dir), name="create search index", mustExec=True) utils.daemonThreadCall(indexAll, name="create search index") # Reindex played songs. from State import state from player import PlayerEventCallbacks for ev,args,kwargs in state.updates.read(): try: if ev is PlayerEventCallbacks.onSongChange: newSong = kwargs["newSong"] insertSearchEntry(newSong) except Exception: import sys sys.excepthook(*sys.exc_info()) flush()
def songdbMain(): # This is heavy, ugly, etc... # But it's simple nice hack for now to index everything. def indexAll(): import appinfo for dir in appinfo.musicdirs: utils.asyncCall(lambda: indexSearchDir(dir), name="create search index") utils.daemonThreadCall(indexAll, name="create search index") # Reindex played songs. from State import state from player import PlayerEventCallbacks for ev,args,kwargs in state.updates.read(): try: if ev is PlayerEventCallbacks.onSongChange: newSong = kwargs["newSong"] insertSearchEntry(newSong) except Exception: import sys sys.excepthook(*sys.exc_info()) flush()
def mpdBackendMain(): import appinfo if not appinfo.config.mpdBackend: return host = appinfo.config.mpdBindHost port = appinfo.config.mpdBindPort import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) s.bind((host,port)) s.listen(1) s.settimeout(0.1) print "mpdBackend listening on %s:%i" % (host,port) t = utils.daemonThreadCall(listenThread, args=(s,), name="mpdBackend.listen") # wait for exit from State import state for ev,args,kwargs in state.updates.read(): pass s.close() t.join()
def start(self): import utils utils.daemonThreadCall(self.runEventsCapture, name = "mediakeys runEventsCapture")
def start(self): import utils utils.daemonThreadCall(self.runEventsCapture, name="mediakeys runEventsCapture")
fn = utils.convertToUnicode(fn) yield (fn, rating) if __name__ == "__main__": for fn, rating in ratingsIter(): print rating, repr(fn) sys.exit() def loadRatings(): def doCalc(queue): for fn, rating in ratingsIter(): queue.put((fn,rating)) queue.put((None,None)) from utils import AsyncTask queue = AsyncTask(func=doCalc, name="iTunes load ratings") while True: fn, rating = queue.get() if fn is None: return ratings[fn] = rating # do some extra check in case we are reloading this module. don't reload the ratings. takes too long try: loadRatingsThread except NameError: ratings = {} from utils import daemonThreadCall daemonThreadCall(loadRatings, name = "iTunes ratings loader")
def click(self, sender): attr = self.userAttr.__get__(self.inst) utils.daemonThreadCall(attr, name="%r click handler" % (self.userAttr))
def handleConnection(conn, address): print "socketcontrol: accepted", address utils.daemonThreadCall(lambda: _handleConnection(conn), name="socketcontrol.handleConnection")