-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.py
202 lines (169 loc) · 8.36 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
import subprocess
from pynput.keyboard import Key, Listener
# import logging
import time
# from datetime import datetime
# import os
# TODO: Add option for user to disable qwerty check, add option to add max WPM
with open("words.txt") as f:
file = f.read()
file = file.split('\n')
def in_qwerty(word):
for f_word in file:
if word == f_word and word != "":
print(f"word: {word}")
print(f"file word: {f_word}")
return True
return False
class State:
def __init__(self):
# The word bit will be used for checking if they're trying to use qwerty
self.keys_arr = []
self.word = ""
# Adds some more variables
self.count = 0 # Counts how many characters have been pressed
self.start_time = time.time() # Gets time the user started typing
self.time = 0 # Time it's taken to type however many characters
self.time_started = False # Tracks whether it's started tracking the time
self.time_finished = 0 # Time the user finished typing last
self.running = True # In case something goes wrong with the script and it keeps locking you out, change
# this to false
self.finished = False # After chars before check is reached this will
# become true to stop checking for another time
self.special_key = False # Whether the last key pressed was a special character
self.last_press = time.time() # The last time a key was pressed
self.min_wpm = 60 # The minimum wpm that must be reached
self.chars_before_check = 50 # The characters before the check will be implemented
self.time_to_recheck = 30 # How long after the user stops typing before it rechecks their speed
self.time_to_stop = 1 # How long between characters does it stop counting the time
self.qwerty = False
def check(self):
if self.qwerty:
subprocess.run("i3lock")
# this will only be visible after the user logs in again, just making
# it helpful to figure out what was going on
print("Warning: attempt to type in qwerty detected, locking")
# prints the word the program thinks was typed in qwerty, meaning if
# it's a real word, the user can remove it from the word list
print(f"The word typed that set this off was: {self.word}")
else:
# If the time has started, stop it, and get get the total
# time the user was typing for
if self.time_started:
self.time += (time.time() - self.start_time)
# self.time += (time.time() - self.time_started) % 60
# Just prints some stats, helpful for debugging
print(f'start_time: {self.start_time}')
print(f'time.time(): {time.time()}')
print(f'WPM: {self.count / self.time * 60 / 5}')
print(f'self.time = {self.time}')
# If the calculated wpm is less than the minimum wpm, lock
# the system
if (self.count / self.time * 60 / 5) < self.min_wpm:
subprocess.run("i3lock")
print("Warning: Type speed exceeded, locking")
# Resets variables
self.finished = True
self.time_finished = time.time()
self.count = 0
self.time_started = False
self.time = 0
def on_press(self, key):
if self.running:
# print(self.keys_arr)
# print(key)
# print(self.finished)
# If the time between now and the last time the user entered
# input is greater than the set time to recheck, start the script
# again
if self.finished:
# TODO: Currently this counts after when the check was ran, rather
# than when the last keypress was—fix this
# if time.time() - self.last_press > self.time_to_recheck:
if time.time() - self.time_finished > self.time_to_recheck:
self.time = 0
self.finished = False
# print("first")
# else:
# # Set the last time pressed to the current time
# self.last_press = time.time()
if not self.finished:
# If the count is greater than the amount of characters set
# to check, do the check
if self.count > self.chars_before_check:
self.check()
# Else if the time since the last press is greater than the
# chosen time to stop, remove the time since the last press
# from the time. i.e. if you are typing and then stop for
# 5 seconds to think, this will not be incorporated into the
# wpm calculation
elif time.time() - self.last_press > self.time_to_stop and not self.special_key and self.time_started:
print(time.time())
print(self.last_press)
print(self.start_time)
self.start_time += (time.time() - self.last_press)
print(self.start_time)
self.last_press = time.time()
print("Time issue")
# If the last key pressed was a special key, ignore the next one
elif self.special_key:
print("Key ignored - special before")
self.special_key = False
# Else get the character of the key pressed
elif getattr(key, "char", None):
print("Key accepted")
# If the time hasn't started, start it
if not self.time_started:
self.start_time = time.time()
self.time_started = True
# Add the character just pressed to the word, this will be
# useful when we add in the keyboard check later
self.word += key.char
# Increase count by 1
self.count += 1
# Set the last time pressed to the current time
self.last_press = time.time()
# Checks if a space was pressed
elif key == Key.space:
print("Space")
# print(self.word)
# keys_array += word
# Before implementing this check, if you hit space, stopped, and then hit space again,
# time.time() - self.start_time would be added to self.time both times you hit the
# space bar, leading to the wpm to be wildly incorrect
if self.time_started:
# Add the time to the total time
self.time += (time.time() - self.start_time)
# Stop the timer
self.time_started = False
# Append the word to the array, will be handy when we
# add the keyboard check
self.keys_arr.append(self.word)
if in_qwerty(self.word):
print(self.word)
self.qwerty = True
self.check()
self.word = ""
# If the last key pressed was backspace, remove the last char
# from the word
elif key == Key.backspace:
print("Backspace")
self.word = self.word[:-1]
# Otherwise, the key pressed must be a special key, so we check
# if the last key pressed was also a special key. If not, we
# set the special key value and do the same stuff as when we
# hit space with the timer
elif not self.special_key:
print("Special key")
self.special_key = True
# same issue as with hitting space
if self.time_started:
self.time += time.time() - self.start_time
self.time_started = False
# Prints the current count (useful for debugging)
print(self.count)
# Calls the State class
state = State()
# Upon a key being pressed call the function
with Listener(on_press=state.on_press) as listener:
listener.join()