3 from coldcall import ColdCall
9 ## create the coldcall object
12 class ColdCallBot (discord.Client):
13 async def on_ready(self):
14 print(f'Logged on as {self.user}! Ready for class!')
16 async def on_message(self, message, voice_channel = 'Class Sessions'):
17 if message.author == self.user:
20 if message.content.startswith('$next'):
21 if message.channel.category:
22 if cc.course != message.channel.category:
23 cc.update_course(message.channel.category)
24 classroom = [x for x in message.guild.voice_channels if x.name == voice_channel and x.category_id == message.channel.category_id][0]
27 for member in classroom.members:
28 if 'Students' in [r.name for r in member.roles]:
29 present_students.append(re.sub(r'^(.*)\#.*$', r'\1', member.name))
32 print(f'currently online: {",".join(present_students)}')
34 if len(present_students) < 1:
35 msg_text = "I don't see any students currently in the Classroom Voice channel!"
37 msg_text = cc.coldcall(present_students)
39 await message.channel.send(msg_text)
40 # TODO: Only let admin send this command
41 if (message.content.startswith('$network game')) and ('Teachers' in [r.name for r in message.author.roles]):
42 print("Starting the game")
43 if message.channel.category:
44 if cc.course != message.channel.category:
45 cc.update_course(message.channel.category)
46 classroom = [x for x in message.guild.voice_channels if x.name == voice_channel and x.category_id == message.channel.category_id][0]
49 for member in classroom.members:
50 if 'Students' in [r.name for r in member.roles]:
51 present_students.append(member)
53 self.assignments = get_assignments(present_students, edgelist = './network_game/test_edgelist.csv')
54 # Build a mapping from names to user objects so that people can refer to users
55 self.active_list = {x.name: x for x in self.assignments}
56 self.observers = [x for x in classroom.members if x not in self.assignments]
57 if self.assignments is not None:
58 for student in self.assignments:
59 await student.send(f"You are allowed to talk to:")
60 for neighbor in self.assignments[student]['neighbors']:
61 await student.send(f"{neighbor.mention}")
62 await student.send(f"You have these resources: {self.assignments[student]['has']}.")
63 await student.send(f"You need: {self.assignments[student]['needs']}.")
65 for student in present_students:
66 await student.send("Not enough students to play")
68 if message.content.startswith('$send'):
70 _, resource, u_to = message.content.split(' ')
72 await message.author.send("Badly formed command. It has to be '$send resource @user'")
73 if u_to not in self.active_list:
74 await message.author.send(f"I can't find {u_to} in the list of users. Make sure the command is formatted as $send resource @user")
76 u_to = self.active_list[u_to]
77 gave_resource = self.give_resource(resource, message.author, u_to)
78 if gave_resource == True:
79 finished = self.is_finished(u_to)
80 await message.author.send(f"{resource} sent to {u_to}")
81 await message.author.send(f"You now have {self.assignments[message.author]['has']} and you need {self.assignments[message.author]['needs']}")
83 await u_to.send("You have everything you need! Well done! You can keep passing resources and talking with your 'neighbors' if you like. Just make sure to keep the resources that you need!")
85 await u_to.send(f"You now have {self.assignments[u_to]['has']} and you need {self.assignments[u_to]['needs']}")
87 for o in self.observers:
88 await o.send(f"{message.author.name} sent {resource} to {u_to.name}")
90 await o.send(f"{u_to.name} has everything they need!!!")
93 await message.author.send(f"Resource not sent. Are you sure you have {resource}?")
94 def is_finished(self, u_to):
95 if set(self.assignments[u_to]['needs']) <= set(self.assignments[u_to]['has']):
104 def give_resource(self, resource, u_from, u_to):
105 if resource not in self.assignments[u_from]['has']:
108 self.assignments[u_from]['has'].remove(resource)
109 self.assignments[u_to]['has'].append(resource)
113 def get_assignments(student_list,
114 edgelist = './network_game/edgelist.csv',
115 resource_prefix = './network_game/resources_'
119 def _add_connection(node1, node2):
122 for i in range(len(mapping[node1])):
123 s1 = mapping[node1][i]
124 s2 = mapping[node2][i]
125 if s1 in assignments:
126 assignments[s1]['neighbors'].append(s2)
128 assignments[s1] = {'neighbors': [s2]}
130 def _add_resources():
131 fn = f"{resource_prefix}{group_size}.csv"
132 with open(fn, 'r') as f:
134 for line in f.readlines():
135 resources = line.strip().split(',')
136 curr_students = mapping[i]
137 for s in curr_students:
138 assignments[s]['has'] = resources[:3]
139 assignments[s]['needs'] = resources[3:]
145 group_size = _get_group_size(len(student_list))
146 if len(student_list) < group_size:
148 mapping = _make_mapping(student_list, group_size)
149 with open(edgelist, 'r') as f:
150 for line in f.readlines():
151 node1, node2 = line.strip().split(',')
152 if int(node2) <= group_size:
153 _add_connection(node1, node2)
154 _add_connection(node2, node1)
160 def _make_mapping(students, group_size):
161 random.shuffle(students)
162 n_observers = len(students) % group_size
165 mapping['observers'] = students[-n_observers:]
166 for i, student in enumerate(students[-n_observers:]):
170 mapping[idx].append(student)
172 mapping[idx] = [student]
176 def _get_group_size(n):
178 for x in range(7,10):
180 if min_observers is None or observers < min_observers:
182 min_observers = observers
189 # this is necessary to get information about who is online
190 intents = discord.Intents.default()
191 intents.members = True
192 intents.presences = True
194 ccb = ColdCallBot(intents=intents)