def predicate(ctx): if not ctx.guild: return True if utils.is_template_adder(ctx) or utils.is_template_admin(ctx) or utils.is_admin(ctx): return True else: raise NoUserPermissionError
async def template_remove(self, ctx, name): t = sql.template_get_by_name(ctx.guild.id, name) if not t: raise TemplateNotFoundError log.info("(T:{})".format(t.name, t.gid)) if t.owner_id != ctx.author.id and not utils.is_template_admin( ctx) and not utils.is_admin(ctx): await ctx.send(ctx.s("template.err.not_owner")) return sql.template_delete(t.gid, t.name) await ctx.send(ctx.s("template.remove").format(name))
async def template_remove(self, ctx, name): t = ctx.session.query(TemplateDb).filter_by(guild_id=ctx.guild.id, name=name).first() if not t: raise TemplateNotFoundError(ctx, ctx.guild.id, name) if t.owner != ctx.author.id and not utils.is_template_admin( ctx) and not utils.is_admin(ctx): await ctx.send(ctx.s("template.err.not_owner")) return ctx.session.delete(t) await ctx.send(ctx.s("template.remove").format(name))
async def snapshot_remove(self, ctx, base_template, snapshot_template): if not utils.is_template_admin(ctx) and not utils.is_admin(ctx): return await ctx.send(ctx.s("template.err.not_owner")) snap = ctx.session.query(Snapshot).filter( Snapshot.base_template.has(name=base_template), Snapshot.target_template.has(name=snapshot_template)).first() if not snap: return await ctx.send("That snapshot does not exist.") ctx.session.delete(snap) await ctx.send("Snapshot removed!")
async def template_snapshot_remove(self, ctx, base_template, snapshot_template): if not utils.is_template_admin(ctx) and not utils.is_admin(ctx): await ctx.send(ctx.s("template.err.not_owner")) return s = sql.snapshot_get_by_names(ctx.guild.id, base_template, snapshot_template) if s is None: await ctx.send("That snapshot does not exist.") return sql.snapshot_delete(ctx.guild.id, base_template, snapshot_template) await ctx.send("Snapshot removed!")
async def snapshot_add(self, ctx, base_template, snapshot_template): if not utils.is_template_admin(ctx) and not utils.is_admin(ctx): await ctx.send(ctx.s("template.err.not_owner")) return base = ctx.session.query(TemplateDb).filter_by( guild_id=ctx.guild.id, name=base_template).first() target = ctx.session.query(TemplateDb).filter_by( guild_id=ctx.guild.id, name=snapshot_template).first() if base is None: return await ctx.send("The base template does not exist.") if target is None: return await ctx.send("The snapshot template does not exist.") snap = Snapshot(base_template=base, target_template=target) ctx.session.add(snap) await ctx.send("Snapshot added!")
async def template_snapshot_add(self, ctx, base_template, snapshot_template): if not utils.is_template_admin(ctx) and not utils.is_admin(ctx): await ctx.send(ctx.s("template.err.not_owner")) return base = sql.template_get_by_name(ctx.guild.id, base_template) target = sql.template_get_by_name(ctx.guild.id, snapshot_template) if base == None: await ctx.send("The base template does not exist.") return if target == None: await ctx.send("The snapshot template does not exist.") return sql.snapshot_add(ctx.guild.id, base_template, snapshot_template) await ctx.send("Snapshot added!")
async def check_for_duplicate_by_name(ctx, name): """Checks for duplicates by name, returns a that template if one exists and the user has permission to overwrite, False if they do not. None is returned if no other templates share this name. Arguments: ctx - commands.Context. name - Template name. Returns: A template object, or None. """ dup = ctx.session.query(TemplateDb).filter_by( guild_id=ctx.guild.id, name=name).first() if dup: if dup.owner != ctx.author.id: if not utils.is_admin and not utils.is_template_admin(ctx): await ctx.send(ctx.s("template.err.name_exists")) raise commands.BadArgument return dup
async def snapshot(self, ctx, *filter): if not utils.is_template_admin(ctx) and not utils.is_admin(ctx): return await ctx.send(ctx.s("template.err.not_owner")) if filter: template_ids = ctx.session.query(TemplateDb.id).filter( TemplateDb.guild_id == ctx.guild.id, TemplateDb.name.in_(filter)).subquery() else: template_ids = ctx.session.query(TemplateDb.id).filter( TemplateDb.guild_id == ctx.guild.id).subquery() snapshots = ctx.session.query(Snapshot).filter( Snapshot.base_template_id.in_(template_ids)).all() if not snapshots: return await ctx.send( f"No snapshots found, add some using `{ctx.prefix}snapshot add`" ) for i, snap in enumerate(snapshots): snap.result = None snap_msg = await ctx.send( f"Checking {snap.target_template.name} for errors...") data = await http.get_template(snap.target_template.url, snap.target_template.name) fetch = self.bot.fetchers[snap.target_template.canvas] img = await fetch(self.bot, snap.target_template.x, snap.target_template.y, snap.target_template.width, snap.target_template.height) func = partial(render.diff, snap.target_template.x, snap.target_template.y, data, 1, img, colors.by_name[snap.target_template.canvas]) diff_img, tot, err, bad, _err, _bad = await self.bot.loop.run_in_executor( None, func) if not err: query = await utils.yes_no( ctx, "There are no errors on the snapshot, do you want to update it?", cancel=True) if query is False: snap.result = "skip" await snap_msg.delete(delay=1) continue elif query is None: for snap in snapshots[i:]: snap.result = "cancel" await snap_msg.delete(delay=1) break else: done = tot - err perc = done / tot if perc < 0.00005 and done > 0: perc = ">0.00%" elif perc >= 0.99995 and err > 0: perc = "<100.00%" else: perc = "{:.2f}%".format(perc * 100) out = ctx.s("canvas.diff") if bad == 0 else ctx.s( "canvas.diff_bad_color") out = out.format(done, tot, err, perc, bad=bad) with io.BytesIO() as bio: diff_img.save(bio, format="PNG") bio.seek(0) f = discord.File(bio, "diff.png") diff_msg = await ctx.send(content=out, file=f) query = await utils.yes_no( ctx, "There are errors on the snapshot, do you want to update it? You will loose track of progress if you do this.", cancel=True) if query is False: snap.result = "err" await snap_msg.delete(delay=1) await diff_msg.delete(delay=1) continue elif query is None: for snap in snapshots[i:]: snap.result = "cancel" await snap_msg.delete(delay=1) await diff_msg.delete(delay=1) break await snap_msg.edit( content=f"Generating snapshot from {snap.base_template.name}..." ) data = await http.get_template(snap.base_template.url, snap.base_template.name) fetch = self.bot.fetchers[snap.base_template.canvas] img = await fetch(self.bot, snap.base_template.x, snap.base_template.y, snap.base_template.width, snap.base_template.height) func = partial(render.diff, snap.base_template.x, snap.base_template.y, data, 1, img, colors.by_name[snap.base_template.canvas], create_snapshot=True) diff_img, tot, err, bad, _err, _bad = await self.bot.loop.run_in_executor( None, func) if not bad: with io.BytesIO() as bio: diff_img.save(bio, format="PNG") bio.seek(0) f = discord.File(bio, f"{snap.target_template.name}.png") await snap_msg.delete(delay=1) msg = await ctx.send(file=f) url = msg.attachments[0].url # The coordinates need to be casted to strings, or the regex in add_template will break shit result = await add_template(ctx, snap.base_template.canvas, snap.target_template.name, str(snap.base_template.x), str(snap.base_template.y), url) if result is None: snap.result = "gen" else: snap.result = "bad" not_updated = [snap for snap in snapshots if snap.result is not None] if not_updated: out = [] for snap in not_updated: reasons = { "err": f"`{snap.base_template.name}`: errors on the current snapshot.", "bad": f"`{snap.base_template.name}`: unquantised pixels detected.", "cancel": f"`{snap.base_template.name}`: the command was cancelled.", "skip": f"`{snap.base_template.name}`: the template was skipped.", "gen": f"`{snap.base_template.name}`: template generation was halted." } text = reasons.get(snap.result) if text: out.append(text) await ctx.send(embed=discord.Embed( description="Unupdated Snapshots").add_field( name="name | reason", value="\n".join(out)))
async def template_snapshot(self, ctx, *filter): if not utils.is_template_admin(ctx) and not utils.is_admin(ctx): await ctx.send(ctx.s("template.err.not_owner")) return snapshots = sql.snapshots_get_all_by_guild(ctx.guild.id) if snapshots == []: await ctx.send( f"No snapshots found, add some using `{ctx.gprefix}template snapshot add`" ) return if filter != (): for i, s in enumerate(snapshots): if s[0].name not in filter: snapshots[i] = None snapshots = [s for s in snapshots if s is not None] not_updated = [] for base, target in snapshots: await ctx.send(f"Checking {target.name} for errors...") data = await http.get_template(target.url, target.name) fetchers = { 'pixelcanvas': render.fetch_pixelcanvas, 'pixelzone': render.fetch_pixelzone, 'pxlsspace': render.fetch_pxlsspace } diff_img, tot, err, bad, err_list \ = await render.diff(target.x, target.y, data, 1, fetchers[target.canvas], colors.by_name[target.canvas], False) if err == 0: if not await utils.yes_no( ctx, "There are no errors on the snapshot, do you want to update it?" ): not_updated.append([base, "skip"]) continue else: done = tot - err perc = done / tot if perc < 0.00005 and done > 0: perc = ">0.00%" elif perc >= 0.99995 and err > 0: perc = "<100.00%" else: perc = "{:.2f}%".format(perc * 100) out = ctx.s("canvas.diff") if bad == 0 else ctx.s( "canvas.diff_bad_color") out = out.format(done, tot, err, perc, bad=bad) with io.BytesIO() as bio: diff_img.save(bio, format="PNG") bio.seek(0) f = discord.File(bio, "diff.png") msg = await ctx.send(content=out, file=f) if not await utils.yes_no( ctx, "There are errors on the snapshot, do you want to update it? You will loose track of progress if you do this." ): not_updated.append([base, "err"]) continue await ctx.send(f"Generating snapshot from {base.name}...") data = await http.get_template(base.url, base.name) fetchers = { 'pixelcanvas': render.fetch_pixelcanvas, 'pixelzone': render.fetch_pixelzone, 'pxlsspace': render.fetch_pxlsspace } diff_img, tot, err, bad, err_list \ = await render.diff(base.x, base.y, data, 1, fetchers[base.canvas], colors.by_name[base.canvas], True) if bad == 0: with io.BytesIO() as bio: diff_img.save(bio, format="PNG") bio.seek(0) f = discord.File(bio, "diff.png") msg = await ctx.send(file=f) url = msg.attachments[0].url await Template.add_template(ctx, base.canvas, target.name, str(base.x), str(base.y), url) else: not_updated.append(base, "bad") continue if not_updated != []: out = [] for t, reason in not_updated: if reason == "err": out.append( f"The snapshot of {t.name} was not updated, as there were errors on the current snapshot." ) if reason == "bad": out.append( f"The snapshot of {t.name} was not updated, as there were unquantised pixels detected." ) await ctx.send("```{}```".format("\n".join(out)))