Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Windows server #12

Merged
merged 1 commit into from

2 participants

Max Shawabkeh Boris Smus
Max Shawabkeh

A simple port of the keysocket server to Windows. There's a pre-built installer in the github downloads of the fork, though I haven't tested on any machines other than the one where it was built.

Boris Smus
Owner

Thanks for the pull. I don't have windows, but I'd like your assurance that you've tested this well before pressing the big green button. Could you try it on another machine just to be sure?

Max Shawabkeh

Tested the pre-built version on another Windows machine (with no Python installed). Seems to be working fine.

Boris Smus borismus merged commit 8036692 into from
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jun 2, 2012
  1. Windows server.

    unknown authored
This page is out of date. Refresh to see the latest.
37 server-windows/broadcast.py
View
@@ -0,0 +1,37 @@
+from twisted.internet import reactor
+from autobahn.websocket import WebSocketServerFactory, WebSocketServerProtocol
+
+class BroadcastServerProtocol(WebSocketServerProtocol):
+ def onOpen(self):
+ self.factory.register(self)
+
+ def onMessage(self, msg, binary):
+ print "Received message '%s' from %s" % (msg, self.peerstr)
+
+ def connectionLost(self, reason):
+ WebSocketServerProtocol.connectionLost(self, reason)
+ self.factory.unregister(self)
+
+
+class BroadcastServerFactory(WebSocketServerFactory):
+ protocol = BroadcastServerProtocol
+
+ def __init__(self, url):
+ WebSocketServerFactory.__init__(self, url)
+ self.clients = []
+
+ def register(self, client):
+ if not client in self.clients:
+ print 'Registered', client.peerstr
+ self.clients.append(client)
+
+ def unregister(self, client):
+ if client in self.clients:
+ print 'Unregistered', client.peerstr
+ self.clients.remove(client)
+
+ def broadcast(self, msg):
+ print 'Broadcasting:', msg
+ for c in self.clients:
+ print ' Send to ' + c.peerstr
+ c.sendMessage(msg)
BIN  server-windows/icon.ico
View
Binary file not shown
25 server-windows/setup.py
View
@@ -0,0 +1,25 @@
+"""A distutils script to build KeySocket on Windows.
+
+Build into an exe with:
+ setup.py build
+Build into an installer with:
+ setup.py bdist_msi
+"""
+
+from cx_Freeze import setup, Executable
+
+
+if __name__ == '__main__':
+ exe = Executable(script='winapp.pyw',
+ base='Win32GUI',
+ targetName='KeySocket.exe',
+ icon='icon.ico',
+ copyDependentFiles=True,
+ shortcutDir='ProgramMenuFolder',
+ shortcutName='KeySocket')
+ setup(name='KeySocket',
+ version='1.0',
+ author='Max Shawabkeh',
+ description='A local web socket server for media keys.',
+ executables=[exe],
+ data_files=[('', ['icon.ico'])])
131 server-windows/winapp.pyw
View
@@ -0,0 +1,131 @@
+import os, sys, imp
+
+# Twisted and autobahn imports.
+try:
+ from twisted.internet import _threadedselect as threadedselectreactor
+except:
+ from twisted.internet import threadedselectreactor
+try:
+ threadedselectreactor.install()
+except:
+ pass
+from twisted.internet import reactor
+from broadcast import BroadcastServerFactory
+
+# Windows API modules.
+from win32api import *
+from win32gui import *
+import win32con
+import pyHook
+
+KEY_TO_MESSAGE = {
+ 'Media_Prev_Track': '20',
+ 'Media_Play_Pause': '16',
+ 'Media_Next_Track': '19'
+}
+TASKBAR_NOTIFY = win32con.WM_USER + 20
+
+def isFrozen():
+ return (hasattr(sys, "frozen") or # new py2exe
+ hasattr(sys, "importers") # old py2exe
+ or imp.is_frozen("__main__")) # tools/freeze
+
+class MediaKeysWindow(object):
+ def __init__(self):
+ msg_TaskbarRestart = RegisterWindowMessage('TaskbarCreated');
+ message_map = {
+ msg_TaskbarRestart: self.OnRestart,
+ win32con.WM_DESTROY: self.OnDestroy,
+ win32con.WM_COMMAND: self.OnCommand,
+ TASKBAR_NOTIFY: self.OnTaskbarNotify,
+ }
+
+ # Register the Window class.
+ wc = WNDCLASS()
+ hinst = wc.hInstance = GetModuleHandle(None)
+ wc.lpszClassName = "KeySocketMediaKeys"
+ wc.style = win32con.CS_VREDRAW | win32con.CS_HREDRAW;
+ wc.hCursor = LoadCursor(0, win32con.IDC_ARROW)
+ wc.hbrBackground = win32con.COLOR_WINDOW
+ wc.lpfnWndProc = message_map
+ classAtom = RegisterClass(wc)
+
+ # Create the Window.
+ style = win32con.WS_OVERLAPPED | win32con.WS_SYSMENU
+ self.hwnd = CreateWindow(
+ classAtom, "Key Socket Media Keys", style,
+ 0, 0, win32con.CW_USEDEFAULT, win32con.CW_USEDEFAULT,
+ 0, 0, hinst, None)
+ UpdateWindow(self.hwnd)
+ self._DoCreateIcons()
+
+ def _DoCreateIcons(self):
+ appPath = sys.executable if isFrozen() else __file__
+ if os.path.isfile(appPath):
+ hicon = LoadImage(GetModuleHandle(None),
+ os.path.join(os.path.dirname(appPath), "icon.ico" ),
+ win32con.IMAGE_ICON,
+ 0,
+ 0,
+ win32con.LR_LOADFROMFILE | win32con.LR_DEFAULTSIZE)
+ else:
+ hicon = LoadIcon(0, win32con.IDI_APPLICATION)
+ flags = NIF_ICON | NIF_MESSAGE | NIF_TIP
+ nid = (self.hwnd, 0, flags, TASKBAR_NOTIFY, hicon, "Key Socket Media Keys")
+ Shell_NotifyIcon(NIM_ADD, nid)
+
+ def OnRestart(self, unused_hwnd, unused_msg, unused_wparam, unused_lparam):
+ self._DoCreateIcons()
+
+ def Destroy(self):
+ self.OnDestroy(self.hwnd, None, None, None)
+
+ def OnDestroy(self, hwnd, unused_msg, unused_wparam, unused_lparam):
+ try:
+ Shell_NotifyIcon(NIM_DELETE, (self.hwnd, 0))
+ except Exception, e:
+ pass
+ PostQuitMessage(0)
+
+ def OnTaskbarNotify(self, hwnd, msg, wparam, lparam):
+ if lparam in (win32con.WM_LBUTTONUP, win32con.WM_RBUTTONUP):
+ menu = CreatePopupMenu()
+ AppendMenu(menu, win32con.MF_STRING, 1042, "Quit")
+ pos = GetCursorPos()
+ SetForegroundWindow(self.hwnd)
+ TrackPopupMenu(
+ menu, win32con.TPM_LEFTALIGN, pos[0], pos[1], 0, self.hwnd, None)
+ PostMessage(self.hwnd, win32con.WM_NULL, 0, 0)
+ return 1
+
+ def OnCommand(self, hwnd, unused_msg, wparam, unused_lparam):
+ if LOWORD(wparam) == 1042: DestroyWindow(self.hwnd)
+
+if __name__ == '__main__':
+ # Create Windows app.
+ window = MediaKeysWindow()
+
+ # Create server.
+ factory = BroadcastServerFactory("ws://localhost:1337")
+ reactor.listenTCP(1337, factory)
+
+ # Install hook.
+ def handleEvent(event):
+ if event.Key in KEY_TO_MESSAGE:
+ factory.broadcast(KEY_TO_MESSAGE[event.Key])
+ # Pass the event to other handlers
+ return True
+ hm = pyHook.HookManager()
+ hm.KeyUp = handleEvent
+ hm.HookKeyboard()
+
+ # Start twisted.
+ reactor.interleave(lambda next: next())
+ reactor.addSystemEventTrigger('after', 'shutdown', window.Destroy)
+
+ # Run Windows main loop.
+ PumpMessages()
+
+ # Kill twisted if it's still alive.
+ if reactor.running:
+ reactor.stop()
Something went wrong with that request. Please try again.