def __init__(self, **kwargs): if ('hash' not in kwargs) or ('lines' not in kwargs) or ('chars' not in kwargs) or ('files' not in kwargs) or ('size' not in kwargs): libfiles = [] lines = 0 chars = 0 fs = 0 size = 0 for subdir, dirs, files in os.walk(conf.rootDir): for file in files: fs += 1 size += os.path.getsize(os.path.join(subdir, file)) if file.endswith(".py"): libfiles.append(os.path.join(subdir, file)) with open(os.path.join(subdir, file), "r") as f: for line in f: lines += 1 chars += len(line) hash = hashlib.sha512(open(libfiles[0], 'rb').read()) for file in libfiles[1:]: hash.update(open(file, 'rb').read()) hash = hash.hexdigest() self.hash = kwargs['hash'] if 'hash' in kwargs else hash self.lines = kwargs['lines'] if 'lines' in kwargs else lines self.chars = kwargs['chars'] if 'chars' in kwargs else chars self.files = kwargs['files'] if 'files' in kwargs else fs self.size = kwargs['size'] if 'size' in kwargs else size self.number = kwargs['number'] if 'number' in kwargs else Revisioning.obtain().current.number + 1 self.major_version = kwargs['major_version'] if 'major_version' in kwargs else conf.VERSION self.version_tag = kwargs['version_tag'] if 'version_tag' in kwargs else conf.VERSIONTAG self.timestamp = kwargs['timestamp'] if 'timestamp' in kwargs else localnow()
async def christmas(self, ctx): """ Syntax: `{pre}{command_name}` **Aliases:** `{aliases}` **Node:** `{node}` **Grant Level:** `{grant_level}` __**Description**__ Enqueue a special shuffled playlist of holiday music. This command will only succeed in December, so use it while you can! __**Arguments**__ This command takes no arguments. __**Example Usage**__ `{pre}{command_name}` """ if localnow().strftime("%m") != "12": return await ctx.send("It's not even december.") player = self.get_player(ctx) if not player.is_connected: channel = await player.connect(ctx) if not channel: return member = Member.obtain(ctx.author.id) await player.set_volume(member.last_volume) admin = Member.obtain(conf.ownerID) plentries = admin.playlists["Christmas"] random.shuffle(plentries) await player.add_enqueue_job(ctx, self.wavelink, "Christmas Music", plentries)
def open(self, title, description="No description provided."): issue = Issue(id=self.last.id + 1, title=title, date=localnow(), description=description) self.issues[str(issue.id)] = issue self.save() return issue
async def queue(self, ctx, number=10): """ Syntax: `{pre}{command_name} [number]` **Aliases:** `{aliases}` **Node:** `{node}` **Grant Level:** `{grant_level}` __**Description**__ Displays the queue, with the specified number of entries. If not specified, it shows the next 10 entries. __**Arguments**__ `[number]` - The number of entries to show. __**Example Usage**__ `{pre}{command_name}` `{pre}{command_name} 15` """ player = self.get_player(ctx) try: status = player.queue.current_track status = "good" except QueueIsEmpty: status = "empty" except EndOfQueue: status = "end" if status == "empty": return await ctx.send("The queue is empty.") if status == "end": return await ctx.send("The queue has reached the end.") embed = discord.Embed( title="Queue", description=f"Showing up to next {number} tracks", colour=ctx.author.colour, timestamp=localnow()) embed.set_author(name="Query Results") embed.set_footer(text=f"Requested by {ctx.author.display_name}", icon_url=ctx.author.avatar_url) embed.add_field(name="Currently playing", value=getattr(player.queue.current_track, "title", "No tracks currently playing."), inline=False) upcoming = player.queue.next_tracks if upcoming: embed.add_field(name="Next up", value="\n".join(t.title for t in upcoming[:number]), inline=False) await ctx.send(embed=embed)
async def uptime(self, ctx): """ Syntax: `{pre}{command_name}` **Aliases:** `{aliases}` **Node:** `{node}` **Grant Level:** `{grant_level}` __**Description**__ Display {bot}'s current uptime statistics. __**Arguments**__ This command takes no arguments. __**Example Usage**__ `{pre}{command_name}` """ uptimes = UptimeRecords.obtain() ut = uptimes.total_uptime dt = uptimes.total_downtime utpercent = uptimes.percentage_up dtpercent = uptimes.percentage_down embed = discord.Embed(title=f"__**{conf.name} Uptime Statistics**__", color=discord.Colour(0xd9e0cf), description="As of " + localnow().strftime("%-m/%-d/%Y %H:%M:%S %Z")) embed.add_field(name="Total Uptime", value=strfdelta(ut, "{%d} days {%H}:{%M}:{%S}\n") + " (" + str(round(utpercent, 2)) + "%)") embed.add_field(name="Total Downtime", value=strfdelta(dt, "{%d} days {%H}:{%M}:{%S}\n") + " (" + str(round(dtpercent, 2)) + "%)") embed.add_field( name="Current Session", value=strfdelta( localnow() - uptimes.current_uptime.start_timestamp, "{%d} days {%H}:{%M}:{%S}")) embed.add_field(name="Initialization Instances", value="{:,}".format(len(uptimes.all) + 1)) await ctx.send(embed=embed)
def update(self): self.end_timestamp = localnow() self.save()
def __init__(self, **kwargs): self.start_timestamp = kwargs[ 'start_timestamp'] if 'start_timestamp' in kwargs else localnow() self.end_timestamp = kwargs[ 'end_timestamp'] if 'end_timestamp' in kwargs else self.start_timestamp
async def choose_track(self, ctx, tracks): """ Allow for track selection. The vast majority of this function only fires when the command executor has promptOnSearch turned on. If it's off, this function simply returns the first result from a ytsearch, and stops cold. Otherwise, this handles the message asking which result should be played and the message response to that. """ def r_check(r, u): return (r.emoji in OPTSR.keys() and u == ctx.author and r.message.id == msg.id) def m_check(m): return (m.content in OPTSM.keys() or m.content.startswith(f"{conf.prefix}play") ) and m.author == ctx.author embed = discord.Embed( title="Choose a song", description=("\n".join( f"**{i+1}.** {t.title} ({t.length//60000}:{str(t.length%60).zfill(2)})" for i, t in enumerate(tracks[:5]))), colour=ctx.author.colour, timestamp=localnow()) embed.set_author(name="Query Results") embed.set_footer(text=f"Invoked by {ctx.author.display_name}", icon_url=ctx.author.avatar_url) msg = await ctx.send(embed=embed) for emoji in list(OPTSR.keys())[:min(len(tracks), len(OPTSR))]: await msg.add_reaction(emoji) try: tasks = [ self.bot.wait_for("reaction_add", timeout=60.0, check=r_check), self.bot.wait_for("message", timeout=60.0, check=m_check) ] done, pending = await asyncio.wait( tasks, return_when=asyncio.FIRST_COMPLETED) is_reaction = True try: for task in done: reaction, _ = task.result() except TypeError: for task in done: message = task.result() is_reaction = False for task in pending: task.cancel() except asyncio.TimeoutError: await msg.delete() await ctx.message.delete() else: await msg.delete() if is_reaction: return tracks[OPTSR[reaction.emoji]] else: try: await message.delete() await ctx.message.delete() except discord.errors.NotFound: pass if message.content.startswith(f"{conf.prefix}play"): return None return tracks[OPTSM[message.content]]
async def handleOAuth(request, scope=""): """ Handle OAuth2. This function takes the request and attempts to perform OAuth2, but only does so when it's necessary. It behaves differently under a few circumstances: - If the correct OAuth2 data is present, and the token has not yet expired, it simply returns the session object. - If the token has expired, it uses the refresh token to get a new one, and returns the new session data. - If the session data is not present, it checks to see if a code is attached to the request. If one is, it uses the code to retrieve a token, then returns the session data. - If one is not attached, it redirects the user to the OAuth2 URL, and obtains the code so that it can be used to retrieve a token. """ session = await get_session(request) try: session['token'] refresh_token = session['refresh_token'] session['token_type'] expiry = session['token_expiry'] scope = session['scope'] if localnow() > datetime.datetime.strptime(expiry, "%x %X %z"): data = { 'client_id': request.app.bot.user.id, 'client_secret': request.app.bot.user.id, 'grant_type': 'refresh_token', 'refresh_token': refresh_token, 'redirect_uri': str(request.url).replace("http://", "https://"), 'scope': scope } headers = {'Content-Type': 'application/x-www-form-urlencoded'} async with aiohttp.ClientSession() as session: async with session.post( "https://discord.com/api/v6/oauth2/token", data=data, headers=headers) as r: json = await r.json() session['token'] = json['access_token'] session['refresh_token'] = json['refresh_token'] session['token_type'] = json['token_type'] expiry = localnow() + datetime.timedelta( seconds=json['expires_in']) session['token_expiry'] = expiry.strftime("%x %X %z") session['scope'] = json['scope'] return session except KeyError: try: code = request.rel_url.query['code'] except KeyError: query_data = { 'client_id': request.app.bot.user.id, 'redirect_uri': str(request.url).replace("http://", "https://"), 'response_type': 'code', 'scope': scope } query = urllib.parse.urlencode(query_data) raise web.HTTPFound("https://discord.com/api/oauth2/authorize?" + query) data = { 'client_id': request.app.bot.user.id, 'client_secret': conf.secret, 'grant_type': 'authorization_code', 'code': code, 'redirect_uri': str(request.url).split("?")[0].replace("http://", "https://"), 'scope': scope } headers = {'Content-Type': 'application/x-www-form-urlencoded'} async with aiohttp.ClientSession() as sesh: async with sesh.post("https://discord.com/api/v6/oauth2/token", data=data, headers=headers) as r: json = await r.json() session['token'] = json['access_token'] session['refresh_token'] = json['refresh_token'] session['token_type'] = json['token_type'] expiry = localnow() + datetime.timedelta(seconds=json['expires_in']) session['token_expiry'] = expiry.strftime("%x %X %z") session['scope'] = json['scope'] return session
async def issuelist(self, ctx, tag_or_id="open"): """ Syntax: `{pre}{command_name} [tag_or_id]` **Aliases:** `{aliases}` **Node:** `{node}` **Grant Level:** `{grant_level}` __**Description**__ Lists issues. A `#tag` may be specified for all issues matching that tag, or an issue number can be specified to list the details about a specific issue. If neither are specified it defaults to all open issues. __**Arguments**__ `[tag_or_id]` - The tag or ID number. All matching tags will be shown whereas only the single matching issue will be shown when a number is specified. If not given, all open issues are displayed. __**Example Usage**__ `{pre}{command_name}` `{pre}{command_name} #critical` `{pre}{command_name} 69` """ if tag_or_id.isdigit(): id = int(tag_or_id) try: issue = IssuesMaster.obtain(id=id) except KeyError: return await ctx.send( "No issue with ID #{id} exists.".formaT(id=id)) embed = discord.Embed(title="__Issue #{id}__".format(id=id), description=issue.title, color=0xc6c6c6) embed.add_field( name="__Tags__", value="`{tags}`".format(tags="`, `".join(issue.status_tags)), inline=True) embed.add_field( name="__Date Created__", value=issue.date.strftime("%-m/%-d/%Y %-I:%M:%S %p %Z"), inline=True) embed.add_field(name="__Description__", value=issue.description, inline=True) responses = list( [response.render(ctx.guild) for response in issue.responses]) resp_title = "Responses in chronological order:" if responses else "No responses yet." embed.add_field(name="__Responses__", value=resp_title, inline=True) await paginate_embed(ctx, embed, responses, threshold=900) else: tag = tag_or_id.lower() if tag.replace("#", "") == "all": title = "__All Issues__" matches = list([ match for id, match in IssuesMaster.obtain().issues.items() ]) else: if tag.replace("#", "") not in conf.issues.validTags: return await ctx.send( "Invalid tag specified: `{tag}`. Valid tags are `{tags}`." .format(tag=tag, tags="`, `".join(conf.issues.validTags))) matches = list([ match for id, match in IssuesMaster.obtain(tag=tag).items() ]) if len(matches) == 0: return await ctx.send( "No issues with tags matching `#{tag}` were found.".format( tag=tag.replace("#", ""))) title = "__Issues with tag {tag}__".format( tag=tag) if tag.startswith( "#") else "__Issues with tag #{tag}__".format(tag=tag) description = "{matches} as of {time}".format( matches="{:,}".format(len(matches)), time=localnow().strftime("%-m/%-d/%Y %-I:%M:%S %p")) embed = discord.Embed(title=title, description=description, color=0xc6c6c6) pack = list([[ "#{id} - {tags}".format(id=issue.id, tags=issue.rendered_tags), issue.title ] for issue in matches]) await paginate_embed(ctx, embed, pack, threshold=900)
def add_response(self, author=None, response=None): self.responses.append( IssueResponse(timestamp=localnow(), responder=author, response=response))
def last(self): try: return self.issues[len(self.issues)] except KeyError: date = localnow() return Issue(id=0, date=date, title="none")