-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSchedulingTask.py
More file actions
164 lines (146 loc) · 6.21 KB
/
Copy pathSchedulingTask.py
File metadata and controls
164 lines (146 loc) · 6.21 KB
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
import time
import threading
import schedule
import winsound # Windows-only
from plyer import notification
import pyttsx3
import re
def words_to_numbers(text):
"""Convert spoken number words or digits to integer if possible."""
import re
text = text.lower().strip()
# Try direct int conversion first (handles "5", "10", "5.0", etc)
try:
# Remove all non-digit/decimal except dot and space
cleaned = re.sub(r"[^\d.\s]", "", text)
# Find all numbers in the cleaned string
numbers = re.findall(r"\d+(?:\.\d+)?", cleaned)
if numbers:
return int(float(numbers[0]))
except Exception:
pass
# Simple mapping for common numbers
numwords = {
"zero": 0, "one": 1, "two": 2, "three": 3, "four": 4, "five": 5,
"six": 6, "seven": 7, "eight": 8, "nine": 9, "ten": 10,
"eleven": 11, "twelve": 12, "thirteen": 13, "fourteen": 14,
"fifteen": 15, "sixteen": 16, "seventeen": 17, "eighteen": 18,
"nineteen": 19, "twenty": 20, "thirty": 30, "forty": 40,
"fifty": 50, "sixty": 60, "seventy": 70, "eighty": 80, "ninety": 90
}
# Try to parse number words
parts = re.split(r"[\s-]+", text)
total = 0
current = 0
for part in parts:
if part in numwords:
scale = numwords[part]
current += scale
elif part == "hundred":
current *= 100
elif part == "thousand":
current *= 1000
total += current
current = 0
else:
# Not a number word, try to extract digits from text (e.g. "5 minutes", "10.5")
digits = re.findall(r"\d+(?:\.\d+)?", part)
if digits:
current += int(float(digits[0]))
# else ignore, don't return None here
total += current
return total if total > 0 else None
class ReminderSystem:
def __init__(self, text_to_speech, get_voice_input, use_voice_input=True):
self.scheduled_jobs = {}
self.text_to_speech = text_to_speech
self.get_voice_input = get_voice_input
self.use_voice_input = use_voice_input
self._schedule_thread = None
self.ASSISTANT_NAME = "Snappy"
def speak(self, text):
engine = pyttsx3.init()
voices = engine.getProperty('voices')
engine.setProperty('voice', voices[1].id)
engine.setProperty('rate', 175)
engine.setProperty('volume', 1.0)
engine.say(text)
engine.runAndWait()
def play_alert_sound(self):
winsound.PlaySound("561352__ohhmye__cute-girl-02.wav", winsound.SND_FILENAME | winsound.SND_ASYNC)
def trigger_reminder(self, task):
threading.Thread(target=self.speak, args=(task,), daemon=True).start()
threading.Thread(target=self.play_alert_sound, daemon=True).start()
notification.notify(
title="Reminder",
message=task,
timeout=10
)
print(f"🔔 Reminder triggered: {task}")
def schedule_task(self, task, interval):
job = schedule.every(interval).minutes.do(self.trigger_reminder, task=task)
self.scheduled_jobs[task] = job
print(f"✅ Scheduled: '{task}' every {interval} minutes")
def cancel_task(self, task):
job = self.scheduled_jobs.pop(task, None)
if job:
schedule.cancel_job(job)
print(f"❌ Canceled: '{task}'")
else:
print(f"⚠️ Task '{task}' not found.")
def cancel_all_tasks(self):
for job in self.scheduled_jobs.values():
schedule.cancel_job(job)
self.scheduled_jobs.clear()
print("🧹 All tasks canceled.")
def run_schedule(self):
while True:
schedule.run_pending()
time.sleep(1)
def _get_voice_input(self, prompt=None):
if self.text_to_speech and prompt:
self.text_to_speech(prompt)
try:
return self.get_voice_input()
except Exception as e:
print(f"Voice input error: {e}")
return ""
def get_input(self, prompt):
if self.use_voice_input:
return self._get_voice_input(prompt)
else:
return input(prompt)
def start(self, command=None):
print("🎙️ Voice reminder system is active.")
self.text_to_speech("Reminder system started.")
while True:
action = self.get_input("Say 'add', 'cancel', 'cancel all', or 'exit': ").strip().lower()
if action == "add":
task = self.get_input("What should I remind you about?").strip()
interval_str = self.get_input("How often should I remind you, in minutes?")
while True:
try:
interval = words_to_numbers(interval_str)
self.schedule_task(task, interval)
self.text_to_speech(f"Got it. I will remind you to {task} every {interval} minutes.")
break
except ValueError:
self.text_to_speech("Please say a valid number.")
print("❗ Invalid interval")
elif action == "cancel":
task = self.get_input("Which task should I cancel?").strip()
self.cancel_task(task)
self.text_to_speech(f"Canceled task: {task}")
elif action == "cancel all":
self.cancel_all_tasks()
self.text_to_speech("All reminders have been canceled.")
elif action == "exit":
self.text_to_speech("Reminder system exiting.")
print("🚪 Exiting reminder system...")
# return all scheduled jobs
all_jobs = list(self.scheduled_jobs.keys())
# turn all_jobs into a string
all_jobs_str = f"{self.ASSISTANT_NAME} has set the following schedules successfully:\n" + (", ".join(all_jobs)) if all_jobs else "No scheduled tasks."
return all_jobs_str
else:
self.text_to_speech("Sorry, I didn't understand that.")