def get_current_streams(): """Returns a list of streams (with only relevant keys)""" streams = list() afreeca_url = 'http://live.afreecatv.com:8057/afreeca/broad_list_api.php' # afreeca_url = 'http://localhost:8000/broad_list_api.php' afreeca_response = utils.fetch_url(afreeca_url) afreeca_json_str = format_afreeca_response_to_json(afreeca_response) json_object = json.loads(afreeca_json_str) time_format = '%Y-%m-%d %H:%M' time_offset = 9 for info in json_object['CHANNEL']['REAL_BROAD']: id = info['user_id'] viewers = int(info['total_view_cnt']) locked = info['is_password'] == 'Y' online_since = utils.get_utc_time(info['broad_start'], time_format, time_offset) image = info['broad_img'] stream = { 'type': 'afreeca', 'id': id, 'viewers': viewers, 'online_since': online_since, 'image': image, 'locked': locked } streams.append(stream) return streams
async def create_poll(self, ctx, duration, *, title): """ Allows a user to create a poll. """ duration = await self.parse_time_as_delta(duration) if not duration: await ctx.send("Poll must have a valid duration " "that is greater than zero") return end_date = ut.get_utc_time() + duration embed = await self.create_poll_embed(title, end_date, False) message = await ctx.send(embed=embed) # Adds control emojis for emoji in POLL_CONTROL_EMOJI: await message.add_reaction(emoji) # Deletes the original command message await ctx.message.delete() poll = Poll.create(title=title, creator_id=ctx.author.id, message_id=message.id, channel_id=message.channel.id, end_date=end_date) await self.update_response_counts(poll)
def put(self, *args, **kwargs): if 'user' not in kwargs or not args: self.raise401() update = {} user = kwargs['user'] task_id = parse_path(args[0])[0] task = Task.objects(id=task_id).first() project = task.project if not project or user not in project.members: self.raise401() category = self.get_argument('category', None) description = self.get_argument('description', None) project_name = self.get_argument('project', None) status = self.get_argument('status', None) priority = self.get_argument('priority', None) assign_to = self.get_argument('assign_to', None) due = self.get_argument('due', None) tags = self.get_argument('tags', None) if category: update['set__category'] = category if description: update['set__description'] = description if project_name: project = Project.objects(name=project_name).first() if not project or user not in project.members: self.raise401() update['set__project'] = project if assign_to: assign_to_list = [] for member in parse_listed_strs(assign_to): u = User.objects(username=member).first() if not u: continue assign_to_list.append(u) update['set__assign_to'] = assign_to_list if status: update['set__status'] = status if priority: update['set__priority'] = priority if due: try: due_day = int(due) except ValueError: due_day = 0 due_time = get_utc_time(due_day * 24 * 3600) update['set__due'] = due_time if tags: tags_list = parse_listed_strs(tags) update['set__tags'] = tags_list try: Task.objects(id=task_id).update_one(**update) task = Task.objects(id=task_id).first() task_data = document_to_json(task, filter_set=_FILTER) self.set_status(201) self.write(task_data) except Exception as e: reason = e.message self.raise400(reason=reason)
async def poll_daemon(self): """ Task loop that update response counts and ends polls that need to be ended """ ongoing_polls = Poll.where('ended', False).get() for poll in ongoing_polls: if ut.get_utc_time() >= poll.end_date: await self.end_poll(poll)
def validate_bearer_token(self, token, scopes, request): # Remember to check expiration and scope membership t = Token.objects(access_token=request.access_token).first() if t: valid = (set(t.scopes) & set(scopes)) valid = valid and t.expires_at > get_utc_time() request.user = valid and t.user or None return valid return False
class Team(Document): from user import User name = StringField(required=True, unique=True) description = StringField() url = URLField() leader = ReferenceField(User) members = ListField(ReferenceField(User)) create_time = DateTimeField(default=get_utc_time()) tags = ListField(StringField())
def save_authorization_code(self, client_id, code, request, *args, **kwargs): # Remember to associate it with request.scopes, request.redirect_uri # request.client, request.state and request.user (the last is passed in # post_authorization credentials, i.e. { 'user': request.user}. client = Client.objects(client_id=client_id).first() Code(client=client, user=request.user, state=request.state, code=code['code'], scopes=request.scopes, redirect_uri=request.redirect_uri, expires_at=get_utc_time(CODE_EXPIRE_TIME)).save()
def save_bearer_token(self, token, request, *args, **kwargs): # Remember to associate it with request.scopes, request.user and # request.client. The two former will be set when you validate # the authorization code. Don't forget to save both the # access_token and the refresh_token and set expiration for the # access_token to now + expires_in seconds. Token(client=request.client, user=request.user, scopes=request.scopes, access_token=token['access_token'], refresh_token=token['refresh_token'], expires_at=get_utc_time(token['expires_in'])).save() return request.client.default_redirect_uri
async def on_poll_react(self, payload): """ Listens for reactions to poll messages """ # Ignores if any bots reacts if payload.member.bot: return # Ignores react if the message doesn't correspond to a poll message_id = payload.message_id poll = Poll.where('message_id', message_id).first() if not poll: return channel = self.bot.get_channel(payload.channel_id) try: message = await channel.fetch_message(message_id) except discord.errors.NotFound: return user = payload.member emoji = payload.emoji if emoji.name == DELETE_POLL_EMOJI: deleted = await self.user_delete_poll(poll, message, user) if not deleted: await message.remove_reaction(emoji, user) return # New responses after the poll has ended are not accepted end_date = poll.end_date if ut.get_utc_time() >= end_date or poll.ended: try: await message.remove_reaction(emoji, user) except discord.errors.NotFound: pass return if emoji.name == ADD_CHOICE_EMOJI: await self.get_new_choice_from_user(poll, message, user) elif emoji.name == END_POLL_EMOJI: await self.user_end_poll(poll, message, user) else: choice = poll.choices().where('reaction', str(emoji)).first() await self.toggle_poll_response(choice, message, user) try: await message.remove_reaction(emoji, user) except discord.errors.NotFound: pass if emoji.name not in POLL_CONTROL_EMOJI: await self.update_response_counts(poll)
def validate_code(self, client_id, code, client, request, *args, **kwargs): # Validate the code belongs to the client. Add associated scopes, # state and user to request.scopes, request.state and request.user. client = Client.objects(client_id=client_id).first() client_code = Code.objects(client=client).first() valid = client_code.code == code if valid and client_code.expires_at > get_utc_time(): request.scopes = client_code.scopes request.user = client_code.user request.state = client_code.state return True return False
async def update_response_counts(self, poll): def key(choice): try: return emojis.index(choice.reaction) except ValueError: # If emoji isn't found, then return 0 return 0 channel = self.bot.get_channel(poll.channel_id) # If the message is deleted, then ignore and return try: message = await channel.fetch_message(poll.message_id) except discord.errors.NotFound: return # Eager-loads choice for poll poll.load('choices') choices = list(poll.choices().get()) # Choices are sorted in the order of appearance # of the emoji in the message - also the order in which they are added emojis = [str(reaction.emoji) for reaction in message.reactions] choices.sort(key=key) embed = message.embeds[0] embed.clear_fields() user_limit = 3 for choice in choices: count = choice.users().count() first_users = choice.users().limit(user_limit).get() users = ', '.join([f"<@{user.id}>" for user in first_users]) if count > user_limit: users += f" and {count - user_limit} more" field_value = choice.text + (f" - {users}" if users else "") embed.add_field(name=f"{choice.reaction} {count}", value=field_value, inline=False) embed.timestamp = ut.get_utc_time() embed.set_footer(text=f"Poll ID: {poll.id}") # Again, if the message is deleted try: await message.edit(embed=embed) except discord.errors.NotFound: return
async def user_end_poll(self, poll, message, user: discord.User): # Only the creator of the poll can end the poll if poll.creator_id != user.id and not ut.is_admin(user): return result, reason = await ut.get_confirmation( message.channel, user, self.bot, "Are you sure you want to end the poll now?") # Brings forward the end date for the poll to current time # # The poll will end the poll on its next iteration if result: poll.end_date = ut.get_utc_time() poll.save()
def post(self, *args, **kwargs): if 'user' not in kwargs or args: self.raise401() category = self.get_argument('category', None) description = self.get_argument('description', None) project_name = self.get_argument('project', None) status = self.get_argument('status', None) priority = self.get_argument('priority', None) assign_to = self.get_argument('assign_to', None) due = self.get_argument('due', None) # days or date tags = self.get_argument('tags', None) user = kwargs['user'] project = Project.objects(name=project_name).first() if not project or user not in project.members: self.raise401() try: due_day = int(due) except ValueError: due_day = 0 try: assign_to_list = [] if assign_to: for member in parse_listed_strs(assign_to): u = User.objects(username=member).first() if not u: continue assign_to_list.append(u) due_time = get_utc_time(due_day * 24 * 3600) tags_list = parse_listed_strs(tags) task = Task(category=category, description=description, project=project, status=status, priority=priority, assign_to=assign_to_list, due=due_time, tags=tags_list) task.save() task_data = document_to_json(task, filter_set=_FILTER) self.set_status(201) self.write(task_data) except Exception as e: reason = e.message self.raise400(reason=reason)
class Task(Document): from user import User from project import Project from comment import TaskComment description = StringField(required=True) category = StringField(required=True) project = ReferenceField(Project, required=True) status = StringField( default='new', choices=['new', 'in progress', 'testing', 'complete', 'closed']) priority = StringField(default='normal', choices=['low', 'normal', 'high', 'emergency']) assign_to = ListField(ReferenceField(User)) due = DateTimeField() create_time = DateTimeField(default=get_utc_time()) update_time = DateTimeField() tags = ListField(StringField()) comments = ListField(EmbeddedDocumentField(TaskComment))
class Client(Document): from ..user import User client_id = StringField(unique=True) client_secret = StringField() user = ReferenceField(User) grant_type = StringField(max_length=18, choices=[ 'authorization_code', 'implicit', 'client_credentials', 'password' ]) response_type = StringField(max_length=5, choices=['code', 'token']) scopes = ListField(StringField()) default_scopes = ListField(StringField()) redirect_uris = ListField(URLField()) default_redirect_uri = URLField() app_name = StringField() website = URLField() description = StringField() create_time = DateTimeField(default=get_utc_time())
def post(self, *args, **kwargs): if 'user' not in kwargs or args: self.raise401() category = self.get_argument('category', None) description = self.get_argument('description', None) project_name = self.get_argument('project', None) status = self.get_argument('status', None) priority = self.get_argument('priority', None) assign_to = self.get_argument('assign_to', None) due = self.get_argument('due', None) # days or date tags = self.get_argument('tags', None) user = kwargs['user'] project = Project.objects(name=project_name).first() if not project or user not in project.members: self.raise401() try: due_day = int(due) except ValueError: due_day = 0 try: assign_to_list = [] if assign_to: for member in parse_listed_strs(assign_to): u = User.objects(username=member).first() if not u: continue assign_to_list.append(u) due_time = get_utc_time(due_day * 24 * 3600) tags_list = parse_listed_strs(tags) task = Task( category=category, description=description, project=project, status=status, priority=priority, assign_to=assign_to_list, due=due_time, tags=tags_list) task.save() task_data = document_to_json(task, filter_set=_FILTER) self.set_status(201) self.write(task_data) except Exception as e: reason = e.message self.raise400(reason=reason)
class CodeReview(EmbeddedDocument): from user import User content = StringField(required=True) reviewer = ReferenceField(User) approved = BooleanField(default=False) create_time = DateTimeField(default=get_utc_time())
class CodeComment(EmbeddedDocument): from user import User lines = StringField(required=True) content = StringField(required=True) author = ReferenceField(User) create_time = DateTimeField(default=get_utc_time())
class ProjectComment(EmbeddedDocument): content = StringField(required=True) from user import User author = ReferenceField(User) reply_to = ReferenceField(User) create_time = DateTimeField(default=get_utc_time())