Python capture Keystrokes values in text file on OS X

前端 未结 2 892
醉话见心
醉话见心 2021-02-10 16:28

I am trying to monitor keystrokes on my Macbook on order to build a statistics analyzer. But how can I isolate the chars from \"event\" which is more something like :

相关标签:
2条回答
  • 2021-02-10 16:34
    #!/usr/bin/python2.6
    
    #  You _must_ turn on assistive devices under Accessibility prefpane 
    # for any of this code to work. Otherwise it won't do anything.
    
    from Cocoa import *
    from Foundation import *
    from PyObjCTools import AppHelper
    import keycode
    import string
    import sys
    
    class AppDelegate(NSObject):
        def applicationDidFinishLaunching_(self, aNotification):
            NSEvent.addGlobalMonitorForEventsMatchingMask_handler_(NSKeyDownMask, handler)
    
    def handler(event):
        if event.type() == NSKeyDown and keycode.tostring(event.keyCode()) in string.printable:
            print keycode.tostring(event.keyCode())
    
    def main():
        app = NSApplication.sharedApplication()
        delegate = AppDelegate.alloc().init()
        NSApp().setDelegate_(delegate)
        AppHelper.runEventLoop()
    
    
    if __name__ == '__main__':
       main()
    

    I dug around a bit and found github user 'gurgeh's OSX modifications for selfspy in his branch - https://github.com/gurgeh/selfspy/blob/new_activity/sniff_cocoa.py.

    I put a few of my own ideas into it and this is the result. Kudos to gurgeh for figuring out how to capture window change events - this makes the key logger much more interesting since you could basically ignore apps that don't provide interesting events, or for the statistically minded, graph out which apps you use the most and what you're doing in them..

    #!/usr/bin/python2.6
    
    import exceptions
    import sys
    from Foundation import NSObject, NSLog
    from AppKit import NSApplication, NSApp, NSWorkspace
    from Cocoa import *
    from Quartz import CGWindowListCopyWindowInfo, kCGWindowListOptionOnScreenOnly, kCGNullWindowID
    from PyObjCTools import AppHelper
    import keycode
    
    evtypes = dict(
        NSLeftMouseDown     = 1,
        NSLeftMouseUp       = 2,
        NSRightMouseDown    = 3,
        NSRightMouseUp      = 4,
        NSMouseMoved        = 5,
        NSLeftMouseDragged  = 6,
        NSRightMouseDragged = 7,
        NSMouseEntered      = 8,
        NSMouseExited       = 9,
        NSKeyDown           = 10,
        NSKeyUp             = 11,
        NSFlagsChanged      = 12,
        NSAppKitDefined     = 13,
        NSSystemDefined     = 14,
        NSApplicationDefined = 15,
        NSPeriodic          = 16,
        NSCursorUpdate      = 17,
        NSScrollWheel       = 22,
        NSTabletPoint       = 23,
        NSTabletProximity   = 24,
        NSOtherMouseDown    = 25,
        NSOtherMouseUp      = 26,
        NSOtherMouseDragged = 27
    )
    
    evtypes_rev = dict([[v,k] for k,v in evtypes.items()])
    
    class Hooker(object):
        def __call__(self, *args, **kwargs):
            try:
                evt = kwargs.get('event')
                del kwargs['event'] 
                items = ' '.join( [ x[0]+"="+unicode(x[1]) for x in kwargs.iteritems()] )
                print "%20s | %22s | %s" % ( self.__class__.__name__, evtypes_rev[evt.type()], items)
            except Exception as e:
                print 'Horrific error!', e
                AppHelper.stopEventLoop()
                sys.exit(0)
    
    class KeyHooker(Hooker): pass
    class MouseButtonHooker(Hooker): pass
    class MouseMoveHooker(Hooker): pass
    class ScreenHooker(Hooker): pass
    
    class SniffCocoa:
    
        def __init__(self):
    
            self.key_hook = KeyHooker()
            self.mouse_button_hook = MouseButtonHooker()
            self.mouse_move_hook = MouseMoveHooker()
            self.screen_hook = ScreenHooker()
            self.currentApp = None
    
        def createAppDelegate (self) :
    
            sc = self
            class AppDelegate(NSObject):
                def applicationDidFinishLaunching_(self, notification):
                    mask = (
                              NSKeyDownMask 
                            | NSKeyUpMask
                            | NSLeftMouseDownMask 
                            | NSLeftMouseUpMask
                            | NSRightMouseDownMask 
                            | NSRightMouseUpMask
                            | NSMouseMovedMask 
                            | NSScrollWheelMask
                           )
                    NSEvent.addGlobalMonitorForEventsMatchingMask_handler_(mask, sc.handler)
            return AppDelegate
    
        def run(self):
            NSApplication.sharedApplication()
            delegate = self.createAppDelegate().alloc().init()
            NSApp().setDelegate_(delegate)
            self.workspace = NSWorkspace.sharedWorkspace()
            AppHelper.runEventLoop()
    
        def cancel(self):
            AppHelper.stopEventLoop()
    
        def handler(self, event):
    
            try:
                activeApps = self.workspace.runningApplications()
                for app in activeApps:
                    if app.isActive():
                        if app.localizedName() != self.currentApp:
                            self.currentApp = app.localizedName()
                            options = kCGWindowListOptionOnScreenOnly 
                            windowList = CGWindowListCopyWindowInfo(options, kCGNullWindowID)
    
                            for window in windowList:
                                if window['kCGWindowOwnerName'] == self.currentApp:
                                    geom = window['kCGWindowBounds'] 
                                    self.screen_hook( event=event,
                                                    name = window['kCGWindowName'],
                                                    owner = window['kCGWindowOwnerName'],
                                                    x = geom['X'], 
                                                    y = geom['Y'], 
                                                    w = geom['Width'], 
                                                    h = geom['Height'])
                                    break
                        break
    
                loc = NSEvent.mouseLocation()
    
                # mouse clicky buttons
                if event.type() in ( NSLeftMouseDown, NSRightMouseDown, NSLeftMouseUp, NSRightMouseUp):
                    self.mouse_button_hook(event=event, x=loc.x, y=loc.y)
    
                # mouse scrolly buttons 
                elif event.type() == NSScrollWheel:
                    if event.deltaY() > 0 and event.deltaY() < 0:
                        self.mouse_button_hook(event=event, x=loc.x, y=loc.y)
                    if event.deltaX() > 0 and event.deltaX() < 0:
                        self.mouse_button_hook(event=event, x=loc.x, y=loc.y)
    
                # keys down
                elif event.type() in ( NSKeyDown, NSKeyUp ):
    
                    flags = event.modifierFlags()
                    modifiers = [] # OS X api doesn't care it if is left or right
                    if (flags & NSControlKeyMask):
                        modifiers.append('CONTROL')
                    if (flags & NSAlternateKeyMask):
                        modifiers.append('ALTERNATE')
                    if (flags & NSCommandKeyMask):
                        modifiers.append('COMMAND')
    
                    self.key_hook(event=event, key=event.keyCode(), char=keycode.tostring( event.keyCode() ), mods=modifiers, is_repeat=event.isARepeat())
    
                # Mouse moved
                elif event.type() == NSMouseMoved:
                    self.mouse_move_hook(event=event, x=loc.x, y=loc.y)
                else:
                    pass
    
            except ( KeyboardInterrupt ) as e:
                print 'handler', e
                AppHelper.stopEventLoop()
    
    if __name__ == '__main__':
        sc = SniffCocoa()
        sc.run()
    
    0 讨论(0)
  • 2021-02-10 16:48

    For using Keycode module. Just clone it from here and run "sudo setup.py install" . You will have keycode module https://github.com/abarnert/pykeycode

    0 讨论(0)
提交回复
热议问题