-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.py
More file actions
184 lines (157 loc) · 7.28 KB
/
main.py
File metadata and controls
184 lines (157 loc) · 7.28 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
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
import datetime
import json
import re
import interactions
from sys import argv
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError
from google.oauth2 import service_account
import timezone
bot = interactions.Client(token=argv[1])
SCOPES = ['https://www.googleapis.com/auth/calendar.readonly']
CALENDARID = 'c_bl50f8rco2lngfb3vru2l7fiso@group.calendar.google.com'
SERVICE_ACCOUNT_FILE = 'credentials.json'
creds = service_account.Credentials.from_service_account_file(SERVICE_ACCOUNT_FILE, scopes=SCOPES)
service = build('calendar', 'v3', credentials=creds)
@bot.command(name="update_events", description="populate the discord with this week's hours")
async def update_events(ctx: interactions.CommandContext):
await ctx.send("Events updated!")
# gets a list of scheduled events for easy iterating
async def get_scheduled_events(ctx: interactions.CommandContext) -> list[interactions.ScheduledEvents]:
return list(map(
lambda event: interactions.ScheduledEvents(**event),
await ctx.client.get_scheduled_events(ctx.guild_id, False)
))
@bot.command(name="clear_events", description="clear all events created by this bot")
async def clear_events(ctx: interactions.CommandContext):
guild = await ctx.get_guild()
res = ""
for event in await get_scheduled_events(ctx):
# fixme this deletes all events unconditionally.
if event.creator_id == ctx.application_id:
await guild.delete_scheduled_event(event.id)
if res:
res += "\n"
res += f"deleted {event.name} for {event.scheduled_start_time}"
if not res:
res = "No events deleted."
await ctx.send(res)
@bot.command(name="get_hours",
description="get the events corresponding to a given user's DA hours",
options=[
interactions.Option(name="user",
description="Departmental Assistance holding the hours",
type=interactions.OptionType.USER,
required=True)
])
async def get_hours(ctx: interactions.CommandContext, user: interactions.User):
await ctx.get_guild()
# event description starts with the DA user
matches = filter(lambda event: event.description.startswith(user.mention), (await get_scheduled_events(ctx))[::-1])
res = str.join('\n', map(lambda e: 'https://discord.gg/whW3SsZUqG?event=' + str(e.id), matches))
await ctx.send(res if res else f"No events found for {user.mention}")
def __relative_date(day: int):
today = datetime.date.today()
days_from_today = ((day + 7) - today.weekday()) % 7
# calculate new date
return today + datetime.timedelta(days=days_from_today)
time_format_m = re.compile("(?P<hour>1[0-2]|[1-9])(:(?P<min>[0-5]\\d)|)(?P<m>[a|p]m)")
def __time12(time_str):
match = time_format_m.fullmatch(time_str)
if match:
groups: dict = match.groupdict()
hour = int(groups['hour'])
if groups['m'] == 'pm':
hour += 12
hour %= 24
minutes = groups.get('min')
return datetime.time(hour, int(minutes) if minutes is not None else 0, tzinfo=timezone.Pacific)
return None
def __datetime(date: datetime.date, time: datetime.time) -> datetime.datetime:
return datetime.datetime(date.year, date.month, date.day, time.hour, time.minute, time.second, time.microsecond,
time.tzinfo)
day_of_week = interactions.Option(
name="day", description="day being held",
type=interactions.OptionType.INTEGER,
required=True,
choices=[
interactions.Choice(name=day, value=index)
for (index, day) in
enumerate(("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"))
])
@bot.command(name="add",
description="Add hours",
options=[
interactions.Option(name="user",
description="person holding the hours",
type=interactions.OptionType.USER,
required=True,
),
day_of_week,
interactions.Option(name="start_time",
description="time at which the hours start",
type=interactions.OptionType.STRING,
required=True,
),
interactions.Option(name="end_time",
description="time at which the hours end",
type=interactions.OptionType.STRING,
required=True,
),
])
async def add(ctx: interactions.CommandContext,
user: interactions.User, day, start_time, end_time, location = "D13"):
# todo move to own method logic
date = __relative_date(day)
# calculate proper start time
start_time = __datetime(date, __time12(start_time))
end_time = __datetime(date, __time12(end_time))
if start_time.replace(tzinfo=None) < datetime.datetime.now():
# todo determine if we want to simply specify a duration instead of an end time.
start_time += datetime.timedelta(weeks=1)
end_time += datetime.timedelta(weeks=1)
if start_time is not None and end_time is not None:
await ctx.get_guild()
discordEvent = await ctx.guild.create_scheduled_event(
"DA Hours", interactions.EntityType.EXTERNAL,
start_time.isoformat(), end_time.isoformat(),
interactions.EventMetadata(location=location),
description=f"{user.mention} will be holding DA hours.",
)
service = build('calendar', 'v3', credentials=creds)
gCalBody = json.dumps(
{"attachments": "None",
"attendees": "None",
"created": datetime.datetime.now(timezone.Pacific).__str__(),
"creator":
{"displayName": ctx.user.__str__(),
"email": "None",
"id": "None"},
"description": discordEvent.id.__str__(),
"end":
{"dateTime": end_time.__str__(),
"timeZone": "America/Los_Angeles"},
"eventType": "default",
"location": location,
"organizer":
{"displayName": ctx.user.__str__(),
"email": "None",
"id": "None"},
"reminders":
{"useDefault": True},
"source":
{"title": "CSC@CLU Discord Bot",
"url": "none"},
"start":
{"dateTime": start_time.__str__(),
"timeZone": "America/Los_Angeles"},
"summary": user.__str__() + "'s DA hours",
"updated": datetime.datetime.now(timezone.Pacific).__str__()})
service.events().insert(calendarId=CALENDARID, body=gCalBody).execute()
msg = f"Added hours for {user.mention} on " \
+ start_time.strftime("%a %m/%d from %I:%M%p") \
+ " to " + end_time.strftime("%I:%M%p")
await ctx.send(msg)
else:
await ctx.send("Invalid time entry")
bot.start()