Пример #1
0
 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
Пример #2
0
 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))
Пример #3
0
 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))
Пример #4
0
    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!")
Пример #5
0
    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!")
Пример #6
0
    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!")
Пример #7
0
    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!")
Пример #8
0
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
Пример #9
0
    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)))
Пример #10
0
    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)))