how to record between key input delay? - python

When I run the code below, I have noticed that what key is entered is recorded.
But there is one more thing I want.
That's for example, assuming I typed a and b, I want the time between a and b to be recorded between the keys as well.
import pynput, time
from pynput.keyboard import Key, Listener
count = 0
keys = []
def on_press(key):
global keys, count
keys.append(key)
count += 1
print("{0} pressed".format(key))
if count >= 10:
count = 0
write_file(keys)
keys = []
def write_file(keys):
with open("log.txt", "w") as f:
for key in keys:
k = str(key).replace("'", "")
if k.find("space") > 0:
f.write('\n')
elif k.find("Key") == -1:
f.write(k)
def on_release(key):
if key == Key.esc:
return False
with Listener(on_press=on_press, on_release=on_release) as listener:
listener.join()
I sloved question.
Thanks for everyone.
# From: https://github.com/moses-palmer/pynput
from pynput.keyboard import Key, Listener
import logging
import keyboard, sys, os
import time
on_press_previous = 0
log_dir = ""
os.remove(log_dir + 'key_log.txt')
logging.basicConfig(filename=(log_dir + "key_log.txt"), level=logging.DEBUG, format='%(message)s')
def on_press(key):
global on_press_previous
on_press_current = time.time()
delta = round(on_press_current - on_press_previous, 3)
on_press_previous = on_press_current
logging.info('{0}'.format(key))
logging.info('{0}'.format(delta))
if keyboard.is_pressed("F7"):
sys.exit()
with Listener(on_press=on_press) as listener:
listener.join()

Here is a Timer class I use to count / record time when writing programs:
class Timer:
def __init__(self):
self.start_time = None
self.on = False
def start(self):
# start counting
self.start_time = time.time()
self.on = True
def value(self):
# --- return current value ---
if self.on:
return time.time() - self.start_time
return 0
def tostr(self):
# --- return value as {min:sec} format ---
val = math.floor(self.value())
mins = '0' + str(int(val / 60)) if len(str(int(val / 60))) == 1 else str(int(val / 60))
secs = '0' + str(val % 60) if len(str(val % 60)) == 1 else str(val % 60)
return "{}:{}".format(mins, secs)
def stop(self):
# --- stop counting ---
self.__init__()

Use timeit module (import timeit):
Put this two lines in on_press:
print("The time difference is :", timeit.default_timer() - start)
start = timeit.default_timer()
Now it will print out time difference between two button clicks:
count = 0
keys = []
start = timeit.default_timer()
def on_press(key):
global keys, count, start
...
...
Also you will have to declare new global variable start.

You can track the time for the on_press event, store it, and then calculated the difference. Here I am using a global variable just for simplicity and consistency with your existing code. Library function time.time_ns() should give plenty of resolution.
import pynput, time
from pynput.keyboard import Key, Listener
count = 0
keys = []
on_press_previous = 0
def on_press(key):
global keys, count, on_press_previous
# current timestamp in nanoseconds
on_press_current = time.time_ns()
# calculate delta from previous on_press event
delta = on_press_current - on_press_previous
# store the current timestamp for the next round
on_press_previous = on_press_current
keys.append((key,delta))
count += 1
print("{} pressed {} nanoseconds from previous".format(key, delta))
if count >= 10:
count = 0
write_file(keys)
keys = []
def write_file(keys):
with open("log.txt", "w") as f:
for key,delta in keys:
k = str(key).replace("'", "")
if k.find("space") > 0:
f.write('\n')
elif k.find("Key") == -1:
f.write(k)
f.write(str(delta))
def on_release(key):
if key == Key.esc:
return False
with Listener(on_press=on_press, on_release=on_release) as listener:
listener.join()

Related

Keylogger not logging keys to txt file

I recently started coding using Python and I'm trying to create a simple keylogger.
However the keys I pressed do not get logged into the actual txt file.
Heres the code :
import pynput
from pynput.keyboard import Key, Listener
count = 0
keys = []
def pressed(key):
global keys, count
keys.append(key)
count += 1
print("{0} pressed".format(key))
if count >= 10:
count = 0
write_file(keys)
keys = []
def write_file(keys):
with open ('Keylogger\log.txt', 'a') as f:
for key in keys:
k = str(key).replace("'","")
if k.find("space") > 0:
f.write('\n')
elif k.find("Key") == -1:
f.write(k)
def released(key):
if key == Key.esc:
return False
with Listener(on_press=pressed, on_release=released) as listener:
listener.join()
I would greatly appreciate any help!

The write file function doesn't work. It doesn't create or write into the file

import pynput
from pynput.keyboard import Key, Listener
count = 0
Keys = []
def on_press(key):
global keys, count
keys.append(key)
count +=1
print("{0} pressed".format (key))
if count >= 5
count = 0
write_file(keys)
keys = []
def write_file(keys):
with open("USERAGREEMENTS.txt", "a") as f:
for key in keys:
k = str(key).replace("'" ",")
if k.find("space") > 0:
f.write("\n")
elif k.find("Key") == -1:
f.write(k)
"if k.find("Key.space") > 0:"
def on_press(key):
print("{0} pressed".format(key))
def on_release(key):
if key == Key.esc:
return False
with Listener(on_press=on_press, on_release=on_release) as listener:
listener.join()
There are so much infect hell of problems in your code so after removing
Syntax Errors
Logical Errors
Indentation Problems
Removing duplicate on_press event
the final working version of your code is following
import pynput
from pynput.keyboard import Key, Listener
count = 0
Keys = []
def on_press(key):
global Keys, count
Keys.append(key)
count += 1
print("{0} pressed".format(key))
if count >= 5:
count = 0
write_file(Keys)
Keys = []
def write_file(keys):
with open("USERAGREEMENTS.txt", "a") as f:
for key in keys:
k = str(key).replace("'", "")
if k.find("space") > 0:
f.write("\n")
elif k.find("Key") == -1:
f.write(k)
def on_release(key):
if key == Key.esc:
write_file(Keys)
return False
with Listener(on_press=on_press, on_release=on_release) as listener:
listener.join()

Stop running function once mouse key is released

I have a function that runs when the mouse key is pressed down. I would like to cancel it once it's released. How would I do that using pynput? For some assistance, here is the code I used to do this but it does not work as it waits for the on_click function to finish or that is my guess.
running = False
i = 0
f = 4
delta_x = [1,2,3]
delta_y = [3,2,1]
def wasd(l):
global f
f = f + l
print(f)
if (f == 5):
return True
else:
return False
def logging_mouse(running, i):
while (running and i < len(delta_x)):
print(delta_x[i],delta_y[i])
if wasd(0) == True: break
i = i+1
running = False
def on_click(*args):
global running
global i
print(running)
i = args[3]
if args[-1]:
if not running:
running = True
threading.Thread(target=logging_mouse(running,i)).start()
else:
running = False
wasd(1)
f = 4
i = 0
with Listener(on_release=wasd(1),on_click=lambda event1,event2,event3,event4: on_click(event1,event2,event3,i,event4)) as listener:
listener.join()
while True:
def on_press_start(*args):
if args[-1]:
return False
def on_press_loop(*args):
if not args[-1]:
return False
i = 0
with Listener(on_click=on_press_start) as listener:
listener.join()
with Listener(on_click=on_press_loop) as listener:
for i in range(len(delta_x)):
print(delta_x[i],delta_y[i])
if not listener.running:
break
print(i)

Keylogger no longer saves test in textfile

I made my first keylogger in Python and it was showing each keystroke to the designated text log awhile back, but now it isn't working for some reason. I want to understand why?
import pynput
from pynput.keyboard import Key, Listener
count = 0
keys = []
def on_press(key):
global keys, count
keys.append(str(key))
count += 1
print("{0} pressed".format(key))
if count >= 10:
count = 0
write_file(keys)
keys = []
def write_file(keys):
with open("alltexts", "a") as f:
for key in keys:
k = str(key).replace("'"," ")
if k.find("space") > 0:
f.write('\n')
elif k.find("Key") == -1:
f.write(k)
def on_release(key):
if key == Key.esc:
return False
with Listener(on_press=on_press, on_release=on_release) as listener:
listener.join()

Timer for Python game

I'm trying to create a simple game where the point is to collect as many blocks as you can in a certain amount of time, say 10 seconds. How can I get a timer to begin ticking at the start of the program and when it reaches 10 seconds, do something (in this case, exit a loop)?
import time
now = time.time()
future = now + 10
while time.time() < future:
# do stuff
pass
Alternatively, if you've already got your loop:
while True:
if time.time() > future:
break
# do other stuff
This method works well with pygame, since it pretty much requires you to have a big main loop.
Using time.time()/datetime.datetime.now() will break if the system time is changed (the user changes the time, it is corrected by a timesyncing services such as NTP or switching from/to dayligt saving time!).
time.monotonic() or time.perf_counter() seems to be the correct way to go, however they are only available from python 3.3. Another possibility is using threading.Timer. Whether or not this is more reliable than time.time() and friends depends on the internal implementation. Also note that creating a new thread is not completely free in terms of system resources, so this might be a bad choice in cases where a lot of timers has to be run in parallel.
I use this function in my python programs. The input for the function is as example:
value = time.time()
def stopWatch(value):
'''From seconds to Days;Hours:Minutes;Seconds'''
valueD = (((value/365)/24)/60)
Days = int (valueD)
valueH = (valueD-Days)*365
Hours = int(valueH)
valueM = (valueH - Hours)*24
Minutes = int(valueM)
valueS = (valueM - Minutes)*60
Seconds = int(valueS)
print Days,";",Hours,":",Minutes,";",Seconds
start = time.time() # What in other posts is described is
***your code HERE***
end = time.time()
stopWatch(end-start) #Use then my code
The threading.Timer object (documentation) can count the ten seconds, then get it to set an Event flag indicating that the loop should exit.
The documentation indicates that the timing might not be exact - you'd have to test whether it's accurate enough for your game.
In this example the loop is run every second for ten seconds:
import datetime, time
then = datetime.datetime.now() + datetime.timedelta(seconds=10)
while then > datetime.datetime.now():
print 'sleeping'
time.sleep(1)
For a StopWatch helper class, here is my solution which gives you precision on output and also access to the raw start time:
class StopWatch:
def __init__(self):
self.start()
def start(self):
self._startTime = time.time()
def getStartTime(self):
return self._startTime
def elapsed(self, prec=3):
prec = 3 if prec is None or not isinstance(prec, (int, long)) else prec
diff= time.time() - self._startTime
return round(diff, prec)
def round(n, p=0):
m = 10 ** p
return math.floor(n * m + 0.5) / m
Asks you when to stop [seconds]
Adds '0' at starting [1-9]
import time
import sys
stop = int(input('> '))
second = 0
print('> Stopwatch Started.')
while stop > second:
if second < 9:
second = second + 1
time.sleep(1)
sys.stdout.write('\r> ' + '0' + str(second))
else:
second += 1
time.sleep(1)
sys.stdout.write('\r' + '> ' + str(second))
print('\n> Stopwatch Stopped.')
As a learning exercise for myself, I created a class to be able to create several stopwatch timer instances that you might find useful (I'm sure there are better/simpler versions around in the time modules or similar)
import time as tm
class Watch:
count = 0
description = "Stopwatch class object (default description)"
author = "Author not yet set"
name = "not defined"
instances = []
def __init__(self,name="not defined"):
self.name = name
self.elapsed = 0.
self.mode = 'init'
self.starttime = 0.
self.created = tm.strftime("%Y-%m-%d %H:%M:%S", tm.gmtime())
Watch.count += 1
def __call__(self):
if self.mode == 'running':
return tm.time() - self.starttime
elif self.mode == 'stopped':
return self.elapsed
else:
return 0.
def display(self):
if self.mode == 'running':
self.elapsed = tm.time() - self.starttime
elif self.mode == 'init':
self.elapsed = 0.
elif self.mode == 'stopped':
pass
else:
pass
print "Name: ", self.name
print "Address: ", self
print "Created: ", self.created
print "Start-time: ", self.starttime
print "Mode: ", self.mode
print "Elapsed: ", self.elapsed
print "Description:", self.description
print "Author: ", self.author
def start(self):
if self.mode == 'running':
self.starttime = tm.time()
self.elapsed = tm.time() - self.starttime
elif self.mode == 'init':
self.starttime = tm.time()
self.mode = 'running'
self.elapsed = 0.
elif self.mode == 'stopped':
self.mode = 'running'
#self.elapsed = self.elapsed + tm.time() - self.starttime
self.starttime = tm.time() - self.elapsed
else:
pass
return
def stop(self):
if self.mode == 'running':
self.mode = 'stopped'
self.elapsed = tm.time() - self.starttime
elif self.mode == 'init':
self.mode = 'stopped'
self.elapsed = 0.
elif self.mode == 'stopped':
pass
else:
pass
return self.elapsed
def lap(self):
if self.mode == 'running':
self.elapsed = tm.time() - self.starttime
elif self.mode == 'init':
self.elapsed = 0.
elif self.mode == 'stopped':
pass
else:
pass
return self.elapsed
def reset(self):
self.starttime=0.
self.elapsed=0.
self.mode='init'
return self.elapsed
def WatchList():
return [i for i,j in zip(globals().keys(),globals().values()) if '__main__.Watch instance' in str(j)]
This is the Shortest Way I know of doing it:
def stopWatch():
import time
a = 0
hours = 0
while a < 1:
for minutes in range(0, 60):
for seconds in range(0, 60):
time.sleep(1)
print(hours,":", minutes,":", seconds)
hours = hours + 1
New to the python world!
I need a System Time independent Stopwatch so I did translate my old C++ class into Python:
from ctypes.wintypes import DWORD
import win32api
import datetime
class Stopwatch:
def __init__(self):
self.Restart()
def Restart(self):
self.__ulStartTicks = DWORD(win32api.GetTickCount()).value
def ElapsedMilliSecs(self):
return DWORD(DWORD(win32api.GetTickCount()).value-DWORD(self.__ulStartTicks).value).value
def ElapsedTime(self):
return datetime.timedelta(milliseconds=self.ElapsedMilliSecs())
This has no 49 days run over issue due to DWORD math but NOTICE that GetTickCount has about 15 milliseconds granularity so do not use this class if your need 1-100 milliseconds elapsed time ranges.
Any improvement or feedback is welcome!

Categories