seventeen 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,40 @@
1
+ Metadata-Version: 2.4
2
+ Name: seventeen
3
+ Version: 1.0.0
4
+ Summary: AutoTyper + AI Screen Answer Tool — type clipboard text and get AI answers from your screen
5
+ License: MIT
6
+ Keywords: autotyper,ai,screen,ocr,hotkey,automation
7
+ Requires-Python: >=3.9
8
+ Description-Content-Type: text/markdown
9
+ Requires-Dist: keyboard
10
+ Requires-Dist: pyperclip
11
+ Requires-Dist: pyautogui
12
+ Requires-Dist: pytesseract
13
+ Requires-Dist: requests
14
+ Requires-Dist: pillow
15
+ Requires-Dist: pystray
16
+
17
+ # seventeen
18
+
19
+ AutoTyper + AI Screen Answer Tool for Windows.
20
+
21
+ ## Install
22
+
23
+ ```
24
+ pip install seventeen
25
+ ```
26
+
27
+ > Also install Tesseract OCR: https://github.com/UB-Mannheim/tesseract/wiki
28
+
29
+ ## Run
30
+
31
+ ```
32
+ seventeen
33
+ ```
34
+
35
+ - **F9** — Start / Pause / Resume typing clipboard text
36
+ - **F10** — Scan screen, get AI answer, copy to clipboard
37
+ - **F8** — Auto-type the AI answer at cursor
38
+ - **Ctrl+F10** — Quit
39
+
40
+ A green icon appears in your system tray when running.
@@ -0,0 +1,24 @@
1
+ # seventeen
2
+
3
+ AutoTyper + AI Screen Answer Tool for Windows.
4
+
5
+ ## Install
6
+
7
+ ```
8
+ pip install seventeen
9
+ ```
10
+
11
+ > Also install Tesseract OCR: https://github.com/UB-Mannheim/tesseract/wiki
12
+
13
+ ## Run
14
+
15
+ ```
16
+ seventeen
17
+ ```
18
+
19
+ - **F9** — Start / Pause / Resume typing clipboard text
20
+ - **F10** — Scan screen, get AI answer, copy to clipboard
21
+ - **F8** — Auto-type the AI answer at cursor
22
+ - **Ctrl+F10** — Quit
23
+
24
+ A green icon appears in your system tray when running.
@@ -0,0 +1,27 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "seventeen"
7
+ version = "1.0.0"
8
+ description = "AutoTyper + AI Screen Answer Tool — type clipboard text and get AI answers from your screen"
9
+ readme = "README.md"
10
+ requires-python = ">=3.9"
11
+ license = {text = "MIT"}
12
+ keywords = ["autotyper", "ai", "screen", "ocr", "hotkey", "automation"]
13
+ dependencies = [
14
+ "keyboard",
15
+ "pyperclip",
16
+ "pyautogui",
17
+ "pytesseract",
18
+ "requests",
19
+ "pillow",
20
+ "pystray",
21
+ ]
22
+
23
+ [project.scripts]
24
+ seventeen = "seventeen.cli:main"
25
+
26
+ [tool.setuptools.packages.find]
27
+ where = ["."]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,2 @@
1
+ # seventeen - AutoTyper + AI Screen Answer Tool
2
+ __version__ = "1.0.0"
@@ -0,0 +1,30 @@
1
+ import sys
2
+ import os
3
+ import subprocess
4
+
5
+
6
+ def main():
7
+ """Entry point: runs seventeen as admin with no terminal window."""
8
+ script = os.path.join(os.path.dirname(__file__), "main.py")
9
+
10
+ # Check if already admin
11
+ try:
12
+ import ctypes
13
+ is_admin = ctypes.windll.shell32.IsUserAnAdmin()
14
+ except Exception:
15
+ is_admin = False
16
+
17
+ if not is_admin:
18
+ # Re-launch as admin
19
+ import ctypes
20
+ ctypes.windll.shell32.ShellExecuteW(
21
+ None, "runas", sys.executable, f'"{script}"', None, 0
22
+ )
23
+ else:
24
+ # Already admin — run directly
25
+ from seventeen.main import run
26
+ run()
27
+
28
+
29
+ if __name__ == "__main__":
30
+ main()
@@ -0,0 +1,214 @@
1
+ import keyboard
2
+ import pyperclip
3
+ import threading
4
+ import time
5
+ import requests
6
+ import pyautogui
7
+ import pytesseract
8
+ import subprocess
9
+ import os
10
+ import sys
11
+ import traceback
12
+ import re
13
+ import pystray
14
+ from PIL import Image, ImageDraw
15
+
16
+ # ===== settings =====
17
+ TYPE_TOGGLE_KEY = "f9"
18
+ AI_KEY = "f10"
19
+ TYPE_ANSWER_KEY = "f8"
20
+ QUIT_KEY = "ctrl+f10"
21
+ CHAR_DELAY = 0.0
22
+ START_DELAY = 2.0
23
+ GROQ_API_KEY = "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"
24
+ GROQ_MODEL = "openai/gpt-oss-20b"
25
+ GROQ_URL = "https://api.groq.com/openai/v1/chat/completions"
26
+ # ====================
27
+
28
+ # Try to find tesseract
29
+ TESS_PATHS = [
30
+ r"C:\Program Files\Tesseract-OCR\tesseract.exe",
31
+ r"C:\Program Files (x86)\Tesseract-OCR\tesseract.exe",
32
+ r"C:\Users\%s\AppData\Local\Programs\Tesseract-OCR\tesseract.exe" % os.getenv("USERNAME",""),
33
+ ]
34
+ for p in TESS_PATHS:
35
+ if os.path.exists(p):
36
+ pytesseract.pytesseract.tesseract_cmd = p
37
+ break
38
+
39
+ LOG_FILE = os.path.join(os.path.expanduser("~"), "seventeen_log.txt")
40
+
41
+ stop_event = threading.Event()
42
+ typing_lock = threading.Lock()
43
+ ai_lock = threading.Lock()
44
+ typing_active = False
45
+ current_text = ""
46
+ current_pos = 0
47
+ latest_answer = ""
48
+ tray_icon = None
49
+
50
+
51
+ def log(msg):
52
+ line = f"[{time.strftime('%H:%M:%S')}] {msg}"
53
+ print(line, flush=True)
54
+ try:
55
+ with open(LOG_FILE, "a", encoding="utf-8") as f:
56
+ f.write(line + "\n")
57
+ except Exception:
58
+ pass
59
+
60
+
61
+ def make_icon(color="green"):
62
+ img = Image.new("RGB", (64, 64), color=(30, 30, 30))
63
+ draw = ImageDraw.Draw(img)
64
+ c = (0, 200, 0) if color == "green" else (200, 200, 0) if color == "yellow" else (200, 0, 0)
65
+ draw.ellipse([8, 8, 56, 56], fill=c)
66
+ return img
67
+
68
+
69
+ def toast(message):
70
+ log(f"TOAST: {message}")
71
+ if tray_icon:
72
+ def _n():
73
+ try:
74
+ tray_icon.notify(message, "AutoTyper")
75
+ except Exception as e:
76
+ log(f"Toast error: {e}")
77
+ threading.Thread(target=_n, daemon=True).start()
78
+
79
+
80
+ def type_character(char):
81
+ if char == '\n':
82
+ keyboard.press_and_release('shift+enter')
83
+ elif char == '\t':
84
+ keyboard.press_and_release('tab')
85
+ else:
86
+ keyboard.write(char, delay=0)
87
+
88
+
89
+ def auto_type(text_override=None):
90
+ global typing_active, current_text, current_pos
91
+ if not typing_lock.acquire(blocking=False):
92
+ return
93
+ typing_active = True
94
+ stop_event.clear()
95
+ try:
96
+ if text_override is not None:
97
+ current_text = text_override
98
+ current_pos = 0
99
+ elif current_pos == 0 or current_pos >= len(current_text):
100
+ current_text = pyperclip.paste()
101
+ current_pos = 0
102
+ if not current_text:
103
+ toast("Clipboard empty!")
104
+ return
105
+ time.sleep(START_DELAY)
106
+ while current_pos < len(current_text):
107
+ if stop_event.is_set():
108
+ return
109
+ type_character(current_text[current_pos])
110
+ current_pos += 1
111
+ toast("✅ Done")
112
+ current_text = ""
113
+ current_pos = 0
114
+ except Exception:
115
+ log(traceback.format_exc())
116
+ finally:
117
+ typing_active = False
118
+ typing_lock.release()
119
+
120
+
121
+ def toggle_typing():
122
+ global typing_active
123
+ if typing_active:
124
+ stop_event.set()
125
+ toast("⏸ Paused")
126
+ else:
127
+ remaining = len(current_text) - current_pos if current_text else 0
128
+ toast("▶ Resuming..." if remaining > 0 else "▶ Typing...")
129
+ threading.Thread(target=auto_type, daemon=True).start()
130
+
131
+
132
+ def extract_and_answer():
133
+ if not ai_lock.acquire(blocking=False):
134
+ return
135
+ toast("🔍 Scanning...")
136
+ threading.Thread(target=_do_ai, daemon=True).start()
137
+
138
+
139
+ def _do_ai():
140
+ global latest_answer
141
+ try:
142
+ image = pyautogui.screenshot()
143
+ screen_text = pytesseract.image_to_string(image).strip()[:3000]
144
+ if not screen_text:
145
+ toast("No text found")
146
+ return
147
+ resp = requests.post(
148
+ GROQ_URL,
149
+ headers={"Authorization": f"Bearer {GROQ_API_KEY}"},
150
+ json={
151
+ "model": GROQ_MODEL,
152
+ "messages": [
153
+ {
154
+ "role": "system",
155
+ "content": (
156
+ "You are a direct answer engine. "
157
+ "If the question has multiple choice options (A, B, C, D), reply with ONLY the correct option letter. "
158
+ "If it is a coding or text question, reply with ONLY the answer, no explanation. "
159
+ "Never add extra text."
160
+ )
161
+ },
162
+ {"role": "user", "content": screen_text}
163
+ ],
164
+ "temperature": 0.1
165
+ },
166
+ timeout=60
167
+ )
168
+ resp.raise_for_status()
169
+ latest_answer = resp.json()["choices"][0]["message"]["content"].strip()
170
+ pyperclip.copy(latest_answer)
171
+ mcq = re.match(r'^([A-Da-d])[\.\):]?$', latest_answer.strip())
172
+ toast(mcq.group(1).upper() if mcq else "✅")
173
+ except Exception as e:
174
+ log(traceback.format_exc())
175
+ toast(f"❌ {str(e)[:50]}")
176
+ finally:
177
+ ai_lock.release()
178
+
179
+
180
+ def type_answer():
181
+ if latest_answer:
182
+ toast("⌨ Typing...")
183
+ threading.Thread(target=auto_type, args=(latest_answer,), daemon=True).start()
184
+ else:
185
+ toast("Press F10 first!")
186
+
187
+
188
+ def quit_app(icon, item):
189
+ icon.stop()
190
+ os._exit(0)
191
+
192
+
193
+ def run():
194
+ global tray_icon
195
+ log("seventeen AutoTyper starting...")
196
+ keyboard.add_hotkey(TYPE_TOGGLE_KEY, toggle_typing)
197
+ keyboard.add_hotkey(AI_KEY, extract_and_answer)
198
+ keyboard.add_hotkey(TYPE_ANSWER_KEY, type_answer)
199
+
200
+ icon_img = make_icon("green")
201
+ menu = pystray.Menu(
202
+ pystray.MenuItem("seventeen AutoTyper", None, enabled=False),
203
+ pystray.MenuItem("F9=Type | F10=AI | F8=Answer", None, enabled=False),
204
+ pystray.Menu.SEPARATOR,
205
+ pystray.MenuItem("Quit", quit_app)
206
+ )
207
+ tray_icon = pystray.Icon("seventeen", icon_img, "seventeen 🟢", menu)
208
+
209
+ def _startup():
210
+ time.sleep(2)
211
+ toast("🟢 Running! F9=Type F10=AI F8=Answer")
212
+ threading.Thread(target=_startup, daemon=True).start()
213
+
214
+ tray_icon.run()
@@ -0,0 +1,40 @@
1
+ Metadata-Version: 2.4
2
+ Name: seventeen
3
+ Version: 1.0.0
4
+ Summary: AutoTyper + AI Screen Answer Tool — type clipboard text and get AI answers from your screen
5
+ License: MIT
6
+ Keywords: autotyper,ai,screen,ocr,hotkey,automation
7
+ Requires-Python: >=3.9
8
+ Description-Content-Type: text/markdown
9
+ Requires-Dist: keyboard
10
+ Requires-Dist: pyperclip
11
+ Requires-Dist: pyautogui
12
+ Requires-Dist: pytesseract
13
+ Requires-Dist: requests
14
+ Requires-Dist: pillow
15
+ Requires-Dist: pystray
16
+
17
+ # seventeen
18
+
19
+ AutoTyper + AI Screen Answer Tool for Windows.
20
+
21
+ ## Install
22
+
23
+ ```
24
+ pip install seventeen
25
+ ```
26
+
27
+ > Also install Tesseract OCR: https://github.com/UB-Mannheim/tesseract/wiki
28
+
29
+ ## Run
30
+
31
+ ```
32
+ seventeen
33
+ ```
34
+
35
+ - **F9** — Start / Pause / Resume typing clipboard text
36
+ - **F10** — Scan screen, get AI answer, copy to clipboard
37
+ - **F8** — Auto-type the AI answer at cursor
38
+ - **Ctrl+F10** — Quit
39
+
40
+ A green icon appears in your system tray when running.
@@ -0,0 +1,11 @@
1
+ README.md
2
+ pyproject.toml
3
+ seventeen/__init__.py
4
+ seventeen/cli.py
5
+ seventeen/main.py
6
+ seventeen.egg-info/PKG-INFO
7
+ seventeen.egg-info/SOURCES.txt
8
+ seventeen.egg-info/dependency_links.txt
9
+ seventeen.egg-info/entry_points.txt
10
+ seventeen.egg-info/requires.txt
11
+ seventeen.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ seventeen = seventeen.cli:main
@@ -0,0 +1,7 @@
1
+ keyboard
2
+ pyperclip
3
+ pyautogui
4
+ pytesseract
5
+ requests
6
+ pillow
7
+ pystray
@@ -0,0 +1,2 @@
1
+ dist
2
+ seventeen