Johnniewhite commited on
Commit
30645dd
1 Parent(s): 8e7913e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +172 -121
app.py CHANGED
@@ -1,124 +1,175 @@
1
- import os
2
- import re
3
- from datetime import datetime, timedelta
4
- import openai
5
  import gradio as gr
6
- from ics import Calendar, Event
7
-
8
- # Set your OpenAI API key
9
- openai.api_key = ("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")
10
-
11
- # Define a custom calendar class
12
- class CustomCalendar:
13
- def __init__(self, file_path):
14
- self.file_path = file_path
15
- self.calendar = Calendar()
16
-
17
- def create_event(self, title, start_time, end_time):
18
- event = Event()
19
- event.name = title
20
- event.begin = start_time
21
- event.end = end_time
22
- self.calendar.events.add(event)
23
- self.save_to_file()
24
-
25
- def update_event(self, old_title, new_start_time, new_end_time):
26
- for event in self.calendar.events:
27
- if event.name == old_title:
28
- event.begin = new_start_time
29
- event.end = new_end_time
30
- self.save_to_file()
31
- break
32
-
33
- def get_events(self):
34
- return list(self.calendar.events)
35
-
36
- def save_to_file(self):
37
- with open(self.file_path, "w") as file:
38
- file.writelines(self.calendar)
39
-
40
- # Helper function to extract event details from the chatbot's response
41
- def extract_event_details(response):
42
- time_pattern = r"(\d{1,2})\s*([ap]m)"
43
- title_pattern = r"(for|about)\s+(.+)"
44
-
45
- time_match = re.search(time_pattern, response, re.IGNORECASE)
46
- title_match = re.search(title_pattern, response, re.IGNORECASE)
47
-
48
- if time_match:
49
- hour = int(time_match.group(1))
50
- meridiem = time_match.group(2).lower()
51
- if meridiem == "pm" and hour < 12:
52
- hour += 12
53
- elif meridiem == "am" and hour == 12:
54
- hour = 0
55
-
56
- if title_match:
57
- title = title_match.group(2)
58
-
59
- if time_match and title_match:
60
- start_time = datetime.now().replace(hour=hour, minute=0, second=0, microsecond=0)
61
- end_time = start_time + timedelta(hours=1)
62
- return title, start_time, end_time
63
-
64
- return None, None, None
65
-
66
- # Function to handle user messages
67
- def handle_message(texts):
68
- global calendar
69
- responses = []
70
-
71
- for text in texts:
72
- response = openai.ChatCompletion.create(
73
- model="gpt-3.5-turbo",
74
- messages=[{"role": "user", "content": text}],
75
- temperature=0.7,
76
- )
77
- response_text = response.choices[0].message.content
78
-
79
- # Check for event creation or adjustment
80
- title, start_time, end_time = extract_event_details(response_text)
81
- if title and start_time and end_time:
82
- if "create" in text or "set" in text or "make" in text:
83
- calendar.create_event(title, start_time, end_time)
84
- responses.append(f"Appointment created: {title} at {start_time.strftime('%I:%M %p')}")
85
- elif "change" in text or "adjust" in text or "modify" in text:
86
- old_title = None
87
- for event in calendar.get_events():
88
- if event.name.lower() in response_text.lower():
89
- old_title = event.name
90
- break
91
- if old_title:
92
- calendar.update_event(old_title, start_time, end_time)
93
- responses.append(f"Appointment updated: {old_title} to {start_time.strftime('%I:%M %p')}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
  else:
95
- responses.append("Sorry, I couldn't find the appointment you wanted to adjust.")
96
- elif "show" in response_text or "list" in response_text or "view" in response_text:
97
- events = calendar.get_events()
98
- if events:
99
- event_list = "\n".join([f"{event.name}: {event.begin.strftime('%I:%M %p')} - {event.end.strftime('%I:%M %p')}" for event in events])
100
- responses.append(f"Your appointments:\n{event_list}")
101
- else:
102
- responses.append("You don't have any appointments scheduled.")
 
 
 
 
 
 
 
 
 
103
  else:
104
- responses.append(response_text)
105
-
106
- return responses
107
-
108
- # Define calendar file path
109
- calendar_file_path = "calendar.ics"
110
-
111
- # Create a custom calendar instance
112
- calendar = CustomCalendar(calendar_file_path)
113
-
114
- # Define Gradio interface
115
- iface = gr.Interface(
116
- fn=handle_message,
117
- inputs=gr.Textbox(lines=3, label="Enter your messages (one per line)"),
118
- outputs="text",
119
- title="Calendar Chatbot",
120
- description="Interact with the chatbot to manage your calendar events.",
121
- )
122
-
123
- # Run the Gradio interface
124
- iface.launch(debug=True, share=True)
 
 
 
 
 
1
  import gradio as gr
2
+ from transformers import AutoModelForSequenceClassification, AutoTokenizer
3
+ import torch
4
+ import datetime
5
+ import re
6
+ import os
7
+ import pytz
8
+ import dateutil.parser
9
+
10
+ # Load the DistilBERT model and tokenizer
11
+ model = AutoModelForSequenceClassification.from_pretrained("distilbert-base-uncased")
12
+ tokenizer = AutoTokenizer.from_pretrained("distilbert-base-uncased")
13
+
14
+ # Initialize an empty list to store events
15
+ events = []
16
+
17
+ # Load events from file if it exists
18
+ if os.path.isfile("events.txt"):
19
+ with open("events.txt", "r") as f:
20
+ for line in f:
21
+ event_data = line.strip().split("|")
22
+ if len(event_data) == 4:
23
+ name, start_str, end_str, recurring = event_data
24
+ start = dateutil.parser.parse(start_str)
25
+ end = dateutil.parser.parse(end_str)
26
+ is_recurring = (recurring.lower() == "true")
27
+ events.append({"name": name, "start": start, "end": end, "recurring": is_recurring})
28
+ print(f"Loaded event: {name} ({start} - {end})")
29
+
30
+ def generate_response(prompt):
31
+ """
32
+ Generate a response using the DistilBERT model.
33
+ """
34
+ inputs = tokenizer(prompt, return_tensors="pt")
35
+ output = model(**inputs)[0] # get the logits
36
+ return tokenizer.decode(torch.argmax(output, dim=-1)[0], skip_special_tokens=True)
37
+
38
+ def list_events(start, end):
39
+ """
40
+ List events for the day between start and end times.
41
+ """
42
+ event_summaries = []
43
+ for event in events:
44
+ event_start = event["start"]
45
+ event_end = event["end"]
46
+ if event_start.tzinfo is None:
47
+ event_start = pytz.utc.localize(event_start)
48
+ if event_end.tzinfo is None:
49
+ event_end = pytz.utc.localize(event_end)
50
+ if start <= event_start < end:
51
+ event_summaries.append(f"{event['name']} ({event_start.strftime('%I:%M %p')} - {event_end.strftime('%I:%M %p')})")
52
+ if not event_summaries:
53
+ return "There are no events presently."
54
+ return ", ".join(event_summaries)
55
+
56
+ def create_event(summary, start, end, recurring=False):
57
+ """
58
+ Create a new event.
59
+ """
60
+ event = {"name": summary, "start": start, "end": end, "recurring": recurring}
61
+ events.append(event)
62
+ save_events()
63
+ return f"Event '{summary}' has been scheduled from {start.strftime('%I:%M %p')} to {end.strftime('%I:%M %p')}."
64
+
65
+ def save_events():
66
+ """
67
+ Save events to a text file.
68
+ """
69
+ with open("events.txt", "w") as f:
70
+ for event in events:
71
+ start_str = event["start"].strftime("%Y-%m-%d %H:%M:%S")
72
+ end_str = event["end"].strftime("%Y-%m-%d %H:%M:%S")
73
+ recurring_str = "True" if event["recurring"] else "False"
74
+ f.write(f"{event['name']}|{start_str}|{end_str}|{recurring_str}\n")
75
+
76
+ def process_input(user_input):
77
+ """
78
+ Process the user input and perform the corresponding action.
79
+ """
80
+ if any(keyword in user_input.lower() for keyword in ["schedule", "create"]):
81
+ summary, start, end, recurring = extract_event_details(user_input)
82
+ if summary and start and end:
83
+ response = create_event(summary, start, end, recurring)
84
+ return response
85
+ else:
86
+ return "I'm sorry, I couldn't understand the event details. Please try again."
87
+
88
+ elif any(keyword in user_input.lower() for keyword in ["list", "show"]):
89
+ start = datetime.datetime.now(pytz.utc).replace(hour=0, minute=0, second=0, microsecond=0, tzinfo=pytz.utc)
90
+ end = start + datetime.timedelta(days=1, seconds=-1, microseconds=-1)
91
+ existing_events = list_events(start, end)
92
+ return existing_events
93
+
94
+ else:
95
+ return "I'm sorry, I didn't understand your request. Please try again."
96
+
97
+ def extract_event_details(user_input):
98
+ """
99
+ Extract the event summary, start time, end time, and recurrence from the user input.
100
+ """
101
+ patterns = [
102
+ r"(schedule|create)(.*?)from\s*(\d+:\d+\s*[aApP][mM])\s*to\s*(\d+:\d+\s*[aApP][mM])\s*tomorrow",
103
+ r"(schedule|create)(.*?)from\s*(\d+:\d+\s*[aApP][mM])\s*to\s*(\d+:\d+\s*[aApP][mM])\s*on\s*(\w+)",
104
+ r"(schedule|create)(.*?)from\s*(\d+:\d+\s*[aApP][mM])\s*to\s*(\d+:\d+\s*[aApP][mM])\s*every\s*(\w+)",
105
+ r"(schedule|create)(.*?)from\s*(\d+:\d+\s*[aApP][mM])\s*to\s*(\d+:\d+\s*[aApP][mM])\s*on\s*the\s*(\w+)\s*of\s*every\s*(\w+)",
106
+ r"(schedule|create)(.*?)from\s*(\d+:\d+\s*[aApP][mM])\s*to\s*(\d+:\d+\s*[aApP][mM])\s*on\s*the\s*(last|first|second|third|fourth)\s*(\w+)\s*of\s*every\s*(\w+)",
107
+ ]
108
+ for pattern in patterns:
109
+ match = re.search(pattern, user_input, re.IGNORECASE)
110
+ if match:
111
+ summary = match.group(2).strip()
112
+ start_str = match.group(3).strip()
113
+ end_str = match.group(4).strip()
114
+ if match.group(5) is None:
115
+ tomorrow = datetime.date.today() + datetime.timedelta(days=1)
116
+ start = datetime.datetime.combine(tomorrow, datetime.datetime.strptime(start_str, "%I:%M %p").time())
117
+ end = datetime.datetime.combine(tomorrow, datetime.datetime.strptime(end_str, "%I:%M %p").time())
118
+ recurring = False
119
+ elif match.group(6):
120
+ day_of_week = match.group(6).lower()
121
+ start = datetime.datetime.combine(datetime.date.today(), datetime.datetime.strptime(start_str, "%I:%M %p").time())
122
+ while start.strftime("%A").lower() != day_of_week:
123
+ start += datetime.timedelta(days=1)
124
+ end = start + datetime.timedelta(hours=int(end_str.split(":")[0]) - int(start_str.split(":")[0]), minutes=int(end_str.split(":")[1]) - int(start_str.split(":")[1]))
125
+ recurring = (match.group(7) == "every")
126
+ elif match.group(8):
127
+ ordinal = match.group(8).lower()
128
+ weekday = match.group(9).lower()
129
+ month = match.group(10).lower()
130
+ start = datetime.datetime.combine(datetime.date.today(), datetime.datetime.strptime(start_str, "%I:%M %p").time())
131
+ next_month = start.replace(day=1) + datetime.timedelta(days=32)
132
+ while start.strftime("%B").lower() != month:
133
+ start = next_month
134
+ next_month = start.replace(day=1) + datetime.timedelta(days=32)
135
+ while start.strftime("%A").lower() != weekday:
136
+ start += datetime.timedelta(days=1)
137
+ if ordinal == "last":
138
+ while start.replace(day=1) + datetime.timedelta(days=32) > start.replace(month=start.month + 1, day=1):
139
+ start -= datetime.timedelta(days=7)
140
  else:
141
+ count = 1
142
+ while count < int(ordinal):
143
+ start += datetime.timedelta(days=7)
144
+ if start.strftime("%B").lower() != month:
145
+ break
146
+ count += 1
147
+ end = start + datetime.timedelta(hours=int(end_str.split(":")[0]) - int(start_str.split(":")[0]), minutes=int(end_str.split(":")[1]) - int(start_str.split(":")[1]))
148
+ recurring = (match.group(11) == "every")
149
+ start = pytz.utc.localize(start)
150
+ end = pytz.utc.localize(end)
151
+ return summary, start, end, recurring
152
+
153
+ # If the input doesn't match any pattern, try to parse it using dateutil
154
+ try:
155
+ date_strings = dateutil.parser.parse(user_input, fuzzy=True)
156
+ if isinstance(date_strings, list):
157
+ start, end = date_strings
158
  else:
159
+ start = end = date_strings
160
+ summary = "Event"
161
+ start = pytz.utc.localize(start)
162
+ end = pytz.utc.localize(end)
163
+ return summary, start, end, False
164
+ except (ValueError, OverflowError):
165
+ pass
166
+
167
+ return None, None, None, False
168
+
169
+ # Gradio interface
170
+ def chat(user_input):
171
+ response = process_input(user_input)
172
+ return response
173
+
174
+ iface = gr.Interface(chat, inputs="text", outputs="text", title="AI Scheduling Assistant")
175
+ iface.launch()