Beispiel #1
0
 def key_pressed(self, e) -> None:
     if not self.collecting or keyboard.is_modifier(e.scan_code):
         return
     hk = keyboard.get_hotkey_name()
     for m in MODIFIERS:
         if keyboard.is_pressed(m) and not keyboard.is_modifier(hk) and hk not in ALL_SHORTCUTS:
             self.count += 1
             logging.debug(f"Shortcut: {hk}")
             return
Beispiel #2
0
    def run(self, **kwargs):
        assert "log_time" in kwargs, "Missing keyword agument log_time!"
        assert "buffer" in kwargs, "Missing keyword argument buffer!"

        log_time = int(kwargs.get("log_time"))
        buffer = int(kwargs.get("buffer"))

        assert log_time > 0, "Log time must be greater than 0!"
        assert buffer > 0, "Buffer must be greater than 0!"

        from queue import Queue, Empty
        import datetime
        import keyboard

        start_time = datetime.datetime.now()
        time_delta = datetime.timedelta(minutes=log_time)
        que = Queue(maxsize=1)
        self.hook = keyboard.hook(que.put)
        self._run.set()
        self._logger.info("Started KeyLogger task!")

        while self._run.is_set():
            try:
                event: keyboard.KeyboardEvent = que.get(timeout=1)
            except Empty:
                event = None

            if event and event.event_type == keyboard.KEY_DOWN:
                if keyboard.is_modifier(event.name) or event.name in ["enter", "space", "backspace", "delete", "tab"]:
                    event.name = " <" + event.name.upper() + "> "

                if len(self.buffer) >= buffer:
                    self.data.append(self.buffer)
                    self.buffer = ""
                else:
                    self.buffer = self.buffer + event.name

            if datetime.datetime.now() - start_time > time_delta:
                self.data.append(self.buffer)
                self.buffer = ""
                break
        return self.data
    def key_press_handler(self, key):
        if keyboard.is_modifier(key.scan_code):
            self.modifier |= MODIFIER[key.scan_code]
        self.key_hold = SCAN_CODES_HID_USAGEID_MAPPING[key.scan_code]
        if self.key_hold != self.macro_key:
            self.bt.send_report(
                modifier=self.modifier, code=(self.key_hold, 0x00, 0x00, 0x00, 0x00, 0x00)
            )

        # replaying, press macro again to stop
        if self.replaying:
            if self.key_hold == self.macro_key:
                self.replaying = False
        else:
            if self.recording:
                # macro: stop record
                if self.key_hold == self.macro_key:
                    try:
                        # the first 2 elements is F1 down, F1 up
                        self.replay_buf = keyboard.stop_recording()[2:]
                    except ValueError:  # if not keyboard.start_recording()
                        pass
                    finally:
                        self.recording = False
            else:
                # F6: assign macro key
                if self.pre_key == 0x3f:
                    self.macro_key = self.key_hold
                # F7: start record, prevent nested recording
                elif self.key_hold == 0x40:
                    keyboard.start_recording()
                    self.recording = True
                # macro: play the record
                elif self.key_hold == self.macro_key:
                    self.replaying = True
                
        self.pre_key = self.key_hold
 def test_is_modifier_scan_code(self):
     for i in range(10):
         self.assertEqual(keyboard.is_modifier(i), i in [4, 5, 6, 7])
 def test_is_modifier_name(self):
     for name in keyboard.all_modifiers:
         self.assertTrue(keyboard.is_modifier(name))
 def key_release_handler(self, key):
     if keyboard.is_modifier(key.scan_code):
         self.modifier &= ~MODIFIER[key.scan_code]
     if self.key_hold != self.macro_key:
         self.bt.send_report(self.modifier)  # send empty data packet
Beispiel #7
0
    def custom_direct_callback(self, event):
        print("Custom")
        """
        This function is called for every OS keyboard event and decides if the
        event should be blocked or not, and passes a copy of the event to
        other, non-blocking, listeners.
    
        There are two ways to block events: remapped keys, which translate
        events by suppressing and re-emitting; and blocked hotkeys, which
        suppress specific hotkeys.
        """
        # Pass through all fake key events, don't even report to other handlers.
        if self.is_replaying:
            return True
        """
        MODIFIED PART
        captures keyboard events even if a hook is suppressing
        
        if the hook is not suppressing some issues happen because of hotkey recursion
        """
        event_type = event.event_type
        scan_code = event.scan_code

        # Update tables of currently pressed keys and modifiers.
        with _pressed_events_lock:
            if event_type == KEY_DOWN:
                if is_modifier(scan_code): self.active_modifiers.add(scan_code)
                _pressed_events[scan_code] = event
            hotkey = tuple(sorted(_pressed_events))
            if event_type == KEY_UP:
                self.active_modifiers.discard(scan_code)
                if scan_code in _pressed_events: del _pressed_events[scan_code]

        if not all(hook(event) for hook in self.blocking_hooks):
            return False

        # Mappings based on individual keys instead of hotkeys.
        for key_hook in self.blocking_keys[scan_code]:
            if not key_hook(event):
                return False

        # Default accept.
        accept = True

        if self.blocking_hotkeys:
            if self.filtered_modifiers[scan_code]:
                origin = 'modifier'
                modifiers_to_update = set([scan_code])
            else:
                modifiers_to_update = self.active_modifiers
                if is_modifier(scan_code):
                    modifiers_to_update = modifiers_to_update | {scan_code}
                callback_results = [
                    callback(event)
                    for callback in self.blocking_hotkeys[hotkey]
                ]
                if callback_results:
                    accept = all(callback_results)
                    origin = 'hotkey'
                else:
                    origin = 'other'

            for key in sorted(modifiers_to_update):
                transition_tuple = (self.modifier_states.get(key, 'free'),
                                    event_type, origin)
                should_press, new_accept, new_state = self.transition_table[
                    transition_tuple]
                if should_press: press(key)
                if new_accept is not None: accept = new_accept
                self.modifier_states[key] = new_state

        if accept:
            if event_type == KEY_DOWN:
                _logically_pressed_keys[scan_code] = event
            elif event_type == KEY_UP and scan_code in _logically_pressed_keys:
                del _logically_pressed_keys[scan_code]

        # Queue for handlers that won't block the event.
        self.queue.put(event)

        return accept
def print_pressed_keys(e):
    global script
    global lastevent
    global actualLine
    global dontprint
        
    if e.scan_code in scan_codes:
        e.name = scan_codes[e.scan_code]
    if e.name in rev_canonical_names:
        e.name = rev_canonical_names[e.name]
    
    if output_log_file is not None:
        with open(output_log_file, "a") as af:
            af.write(_getjson(e) + ",")
    
    e.name = (e.name.upper(), e.name)[len(e.name) == 1]
    
    if lastevent is not None:
        if lastevent.event_type == "up" and e.event_type == "down":
            delay = round((e.time-lastevent.time)*1000)
            if delay >= delay_threshold:
                if actualLine is not None and actualLine.startswith("STRING"):
                    script.append(actualLine)
                    actualLine = None
                script.append("DELAY %s" % delay)
    
    if e.event_type == "down":
        dontprint = False
        if len(e.name) == 1 and not e.modifiers and not keyboard.is_modifier(e.scan_code):
            if actualLine is None:
                actualLine = "STRING "
            elif e.name in actualLine and not actualLine.startswith("STRING"):
                pass
            actualLine = actualLine + e.name
        
        else:
            if actualLine is not None:
                if e.name in actualLine:
                    pass
                if actualLine.startswith("STRING"):
                    if actualLine is not None:
                        script.append(actualLine)
                    actualLine = e.name
                else:
                    if e.name not in actualLine:
                        actualLine = actualLine + " " + e.name
            else:
                actualLine = e.name
        
    else: #up
        if actualLine is not None:
            if not actualLine.startswith("STRING"):
                if e.name in actualLine:
                    if not dontprint:
                        script.append(actualLine)
                    
                    actualLine = actualLine.replace(e.name, "").replace("  "," ").strip()
                    actualLine = (actualLine, None)[actualLine == ""]
                    if actualLine is not None:
                        dontprint = True

    lastevent = e
    i = actualLine
Beispiel #9
0
 def test_is_modifier_scan_code(self):
     for i in range(10):
         self.assertEqual(keyboard.is_modifier(i), i in [4, 5, 6, 7])
Beispiel #10
0
 def test_is_modifier_name(self):
     for name in keyboard.all_modifiers:
         self.assertTrue(keyboard.is_modifier(name))