# Path: embedmaker/serialize.py
# def deserialize_embed(conf: dict) -> discord.Embed:
# 
#     unpack = {k: v for k, v in conf["initable"].items() if v}
# 
#     if "timestamp" in unpack:
#         unpack["timestamp"] = dt.utcfromtimestamp(unpack["timestamp"])
# 
#     e = discord.Embed(**unpack)
# 
#     for k, v in conf["settable"].items():
#         if v is not None:
#             to_set = {_k: _v for _k, _v in v.items() if _v}
#             getattr(e, "set_" + k)(**to_set)
# 
#     for f in conf["fields"]:
#         e.add_field(**f)
# 
#     return e
# 
# def serialize_embed(embed: discord.Embed) -> dict:
# 
#     ret: dict = {"initable": {}, "settable": {}}
# 
#     for k in template["initable"].keys():
#         v = getattr(embed, k, None) or None
#         if v is None:
#             continue
#         if k == "timestamp" and v:
#             v = v.timestamp()
#         if k == "color" and v:
#             v = v.value
#         ret["initable"][k] = v
# 
#     for k, v in template["settable"].items():
#         proxy = getattr(embed, k, None) or None
#         if proxy is None:
#             continue
#         ret["settable"][k] = {}
#         for attr in v.keys():
#             to_set = getattr(proxy, attr, None)
#             if to_set or to_set is False:  # specifically not None or embed.Empty
#                 ret["settable"][k][attr] = to_set
# 
#     ret["fields"] = []
#     for field in embed.fields:
#         data = {}
#         for attr in ["name", "value", "inline"]:
#             to_set = getattr(field, attr, None)
#             if to_set or to_set is False:  # specifically not None or embed.Empty
#                 data[attr] = to_set
#         if data:
#             ret["fields"].append(data)
# 
#     return ret
# 
# Path: embedmaker/yaml_parse.py
# async def embed_from_userstr(ctx: commands.Context, string: str) -> discord.Embed:
#     ret: dict = {"initable": {}, "settable": {}, "fields": []}
#     string = string_preprocessor(string)
# 
#     parsed = yaml.safe_load(string)
#     ret["fields"] = [
#         field_data for _index, field_data in sorted(parsed.get("fields", {}).items())
#     ]
# 
#     for outer_key in ["initable", "settable"]:
#         for inner_key in template[outer_key].keys():
#             to_set = parsed.get(inner_key, {})
#             if to_set:
#                 if inner_key == "timestamp":
#                     to_set = handle_timestamp(to_set)
#                 elif inner_key in ("color", "colour"):
#                     to_set = await handle_color(ctx, to_set)
# 
#                 ret[outer_key][inner_key] = to_set
# 
#     return deserialize_embed(ret)


import io
import logging
import random
import discord
from typing import Generator, Literal, Optional, cast
from redbot.core import Config, checks, commands
from redbot.core.utils import AsyncIter
from redbot.core.utils.chat_formatting import pagify
from .serialize import deserialize_embed, serialize_embed
from .time_utils import parse_time
from .yaml_parse import embed_from_userstr
        else:
            return await ctx.send("No embed by that name here")

        try:
            assert isinstance(message.channel, discord.TextChannel)  # nosec
            if message.channel.permissions_for(ctx.me).manage_messages:
                await message.edit(embed=embed, suppress=False)
            else:
                await message.edit(embed=embed)
        except discord.HTTPException as exc:
            log.error("Message edit failed", exc_info=exc)
            await ctx.send("A message edit failed unexpectedly")
            return
        await ctx.tick()

    @commands.bot_has_permissions(embed_links=True)
    @_embed.command(name="advmake")
    async def make_adv(self, ctx: commands.GuildContext, name: str, *, data: str):
        """
        makes an embed from valid yaml

        Note: Fields should be provided as nested key: value pairs,
        keys indicating position.
        """
        name = name.lower()
        group = self.config.custom("EMBED", ctx.guild.id, name)
        if await group.owner() not in (ctx.author.id, None):
            return await ctx.maybe_send_embed("An embed with that name already exists!")

        try:

# Path: embedmaker/serialize.py
# def deserialize_embed(conf: dict) -> discord.Embed:
# 
#     unpack = {k: v for k, v in conf["initable"].items() if v}
# 
#     if "timestamp" in unpack:
#         unpack["timestamp"] = dt.utcfromtimestamp(unpack["timestamp"])
# 
#     e = discord.Embed(**unpack)
# 
#     for k, v in conf["settable"].items():
#         if v is not None:
#             to_set = {_k: _v for _k, _v in v.items() if _v}
#             getattr(e, "set_" + k)(**to_set)
# 
#     for f in conf["fields"]:
#         e.add_field(**f)
# 
#     return e
# 
# def serialize_embed(embed: discord.Embed) -> dict:
# 
#     ret: dict = {"initable": {}, "settable": {}}
# 
#     for k in template["initable"].keys():
#         v = getattr(embed, k, None) or None
#         if v is None:
#             continue
#         if k == "timestamp" and v:
#             v = v.timestamp()
#         if k == "color" and v:
#             v = v.value
#         ret["initable"][k] = v
# 
#     for k, v in template["settable"].items():
#         proxy = getattr(embed, k, None) or None
#         if proxy is None:
#             continue
#         ret["settable"][k] = {}
#         for attr in v.keys():
#             to_set = getattr(proxy, attr, None)
#             if to_set or to_set is False:  # specifically not None or embed.Empty
#                 ret["settable"][k][attr] = to_set
# 
#     ret["fields"] = []
#     for field in embed.fields:
#         data = {}
#         for attr in ["name", "value", "inline"]:
#             to_set = getattr(field, attr, None)
#             if to_set or to_set is False:  # specifically not None or embed.Empty
#                 data[attr] = to_set
#         if data:
#             ret["fields"].append(data)
# 
#     return ret
# 
# Path: embedmaker/yaml_parse.py
# async def embed_from_userstr(ctx: commands.Context, string: str) -> discord.Embed:
#     ret: dict = {"initable": {}, "settable": {}, "fields": []}
#     string = string_preprocessor(string)
# 
#     parsed = yaml.safe_load(string)
#     ret["fields"] = [
#         field_data for _index, field_data in sorted(parsed.get("fields", {}).items())
#     ]
# 
#     for outer_key in ["initable", "settable"]:
#         for inner_key in template[outer_key].keys():
#             to_set = parsed.get(inner_key, {})
#             if to_set:
#                 if inner_key == "timestamp":
#                     to_set = handle_timestamp(to_set)
#                 elif inner_key in ("color", "colour"):
#                     to_set = await handle_color(ctx, to_set)
# 
#                 ret[outer_key][inner_key] = to_set
# 
#     return deserialize_embed(ret)


# Path: embedmaker/embedmaker.py
import io
import logging
import random
import discord
from typing import Generator, Literal, Optional, cast
from redbot.core import Config, checks, commands
from redbot.core.utils import AsyncIter
from redbot.core.utils.chat_formatting import pagify
from .serialize import deserialize_embed, serialize_embed
from .time_utils import parse_time
from .yaml_parse import embed_from_userstr

        else:
            return await ctx.send("No embed by that name here")

        try:
            assert isinstance(message.channel, discord.TextChannel)  # nosec
            if message.channel.permissions_for(ctx.me).manage_messages:
                await message.edit(embed=embed, suppress=False)
            else:
                await message.edit(embed=embed)
        except discord.HTTPException as exc:
            log.error("Message edit failed", exc_info=exc)
            await ctx.send("A message edit failed unexpectedly")
            return
        await ctx.tick()

    @commands.bot_has_permissions(embed_links=True)
    @_embed.command(name="advmake")
    async def make_adv(self, ctx: commands.GuildContext, name: str, *, data: str):
        """
        makes an embed from valid yaml

        Note: Fields should be provided as nested key: value pairs,
        keys indicating position.
        """
        name = name.lower()
        group = self.config.custom("EMBED", ctx.guild.id, name)
        if await group.owner() not in (ctx.author.id, None):
            return await ctx.maybe_send_embed("An embed with that name already exists!")

        try:

            e = await embed_from_userstr(ctx, data)