1
0
Fork 0

Integrate backup & restore extensions

This commit is contained in:
Ethanell 2020-07-30 11:56:31 +02:00
parent c59a89e5ac
commit 80c012438e
4 changed files with 154 additions and 125 deletions

View file

@ -8,3 +8,5 @@ bot.load_extension("extensions.reminder")
bot.load_extension("extensions.greetings") bot.load_extension("extensions.greetings")
bot.load_extension("extensions.presentation") bot.load_extension("extensions.presentation")
bot.load_extension("extensions.rorec") bot.load_extension("extensions.rorec")
bot.load_extension("extensions.backup")
bot.load_extension("extensions.restore")

View file

@ -1,84 +1,96 @@
from discord.ext import commands
from backup_bot.logger import logger
from os.path import isdir
from os import mkdir
import shelve import shelve
from datetime import datetime
from discord import File, Embed
from collections import OrderedDict from collections import OrderedDict
from datetime import datetime
from os import mkdir
from os.path import isdir
from discord import File, Embed
from discord.ext import commands
from administrator.logger import logger
extension_name = "backup" extension_name = "backup"
logger = logger.getChild(extension_name) logger = logger.getChild(extension_name)
@commands.command("backup") class Backup(commands.Cog):
async def backup_cmd(ctx: commands.Context): def __init__(self, bot: commands.Bot):
embed = Embed(title="Backup", description="In progress... \N{hourglass}") self.bot = bot
msg = await ctx.send(embed=embed)
file_name = f"backup/{datetime.now().strftime('%d-%m-%Y %H:%M')}" def description(self):
with shelve.open(file_name, writeback=True) as file: return "Backup all message on the guild"
file["channels"] = OrderedDict()
file["users"] = OrderedDict() @commands.group("backup", pass_context=True)
file["categories"] = OrderedDict() @commands.guild_only()
for c in ctx.guild.text_channels: @commands.has_permissions(manage_messages=True)
embed_field_name = c.name async def backup(self, ctx: commands.Context):
if c.category: embed = Embed(title="Backup", description="In progress... \N{hourglass}")
embed_field_name = f"{c.category} > {embed_field_name}" msg = await ctx.send(embed=embed)
if c.category_id not in file["categories"]: file_name = f"backup/{datetime.now().strftime('%d-%m-%Y %H:%M')}"
file["categories"][c.category_id] = {"name": c.category.name, with shelve.open(file_name, writeback=True) as file:
"position": c.category.position, file["channels"] = OrderedDict()
"nsfw": c.category.is_nsfw()} file["users"] = OrderedDict()
embed = msg.embeds[0] file["categories"] = OrderedDict()
if len(embed.fields) != 0: for c in ctx.guild.text_channels:
embed.set_field_at(-1, name=embed.fields[-1].name, value="\N{check mark}", inline=False) embed_field_name = c.name
embed.add_field(name=embed_field_name, value="\N{hourglass}", inline=False) if c.category:
await msg.edit(embed=embed) embed_field_name = f"{c.category} > {embed_field_name}"
file["channels"][c.id] = {"name": c.name, if c.category_id not in file["categories"]:
"id": c.id, file["categories"][c.category_id] = {"name": c.category.name,
"category_id": c.category_id, "position": c.category.position,
"topic": c.topic, "nsfw": c.category.is_nsfw()}
"position": c.position, embed = msg.embeds[0]
"slowmode_delay": c.slowmode_delay, if len(embed.fields) != 0:
"nsfw": c.is_nsfw(), embed.set_field_at(-1, name=embed.fields[-1].name, value="\N{check mark}", inline=False)
"messages": []} embed.add_field(name=embed_field_name, value="\N{hourglass}", inline=False)
async for m in c.history(limit=None): await msg.edit(embed=embed)
if m.author.id not in file["users"]: file["channels"][c.id] = {"name": c.name,
file["users"][m.author.id] = {"name": m.author.name, "id": c.id,
"discriminator": m.author.discriminator, "category_id": c.category_id,
"display_name": m.author.display_name, "topic": c.topic,
"avatar": m.author.avatar} "position": c.position,
file["channels"][c.id]["messages"].append({"author_id": m.author.id, "slowmode_delay": c.slowmode_delay,
"content": m.content, "nsfw": c.is_nsfw(),
"embeds": m.embeds, "messages": []}
# "attachments": m.attachments, async for m in c.history(limit=None):
"pinned": m.pinned, if m.author.id not in file["users"]:
"reactions": m.reactions, file["users"][m.author.id] = {"name": m.author.name,
"created_at": m.created_at, "discriminator": m.author.discriminator,
"edited_at": m.edited_at}) "display_name": m.author.display_name,
embed = msg.embeds[0] "avatar": m.author.avatar}
embed.set_field_at(-1, name=embed.fields[-1].name, value="\N{check mark}", inline=False) file["channels"][c.id]["messages"].append({"author_id": m.author.id,
embed.description = "Finish ! \N{check mark}" "content": m.content,
await msg.edit(embed=embed) "embeds": m.embeds,
await ctx.send(file=File(file_name + ".db", "backup.db")) # "attachments": m.attachments,
"pinned": m.pinned,
"reactions": m.reactions,
"created_at": m.created_at,
"edited_at": m.edited_at})
embed = msg.embeds[0]
embed.set_field_at(-1, name=embed.fields[-1].name, value="\N{check mark}", inline=False)
embed.description = "Finish ! \N{check mark}"
await msg.edit(embed=embed)
await ctx.send(file=File(file_name + ".db", "backup.db"))
def setup(bot: commands.Bot): def setup(bot):
logger.info(f"Loading...") logger.info(f"Loading...")
if not isdir("backup"): if not isdir("backup"):
logger.info(f"Create backup folder") logger.info(f"Create backup folder")
mkdir("backup") mkdir("backup")
try: try:
bot.add_command(backup_cmd) bot.add_cog(Backup(bot))
except Exception as e: except Exception as e:
logger.error(f"Error loading: {e}") logger.error(f"Error loading: {e}")
else: else:
logger.info(f"Load successful") logger.info(f"Load successful")
def teardown(bot: commands.Bot): def teardown(bot):
logger.info(f"Unloading...") logger.info(f"Unloading...")
try: try:
bot.remove_command("backup") bot.remove_cog("Backup")
except Exception as e: except Exception as e:
logger.error(f"Error unloading: {e}") logger.error(f"Error unloading: {e}")
else: else:

View file

@ -1,95 +1,107 @@
from discord.ext import commands
from backup_bot.logger import logger
from os.path import isdir
from os import mkdir, remove
import shelve import shelve
from requests import get from os import mkdir, remove
from os.path import isdir
from discord import Embed from discord import Embed
from discord.ext import commands
from requests import get
from administrator.logger import logger
extension_name = "restore" extension_name = "restore"
logger = logger.getChild(extension_name) logger = logger.getChild(extension_name)
@commands.command("restore") class Restore(commands.Cog):
async def restore_cmd(ctx: commands.Context): def __init__(self, bot: commands.Bot):
if len(ctx.message.attachments) != 1: self.bot = bot
await ctx.send("No backup file given ! \N{cross mark}")
else:
embed = Embed(title="Restore", description="In progress... \N{hourglass}")
msg = await ctx.send(embed=embed)
file = get(ctx.message.attachments[0].url, stream=True) def description(self):
file_name = f"backup/{ctx.message.author.id}" return "Restore a backup of guild's messages"
with open(file_name + ".db", "w+b") as f:
for i in file.iter_content():
f.write(i)
with shelve.open(file_name) as file:
categories = {}
for c in file["categories"]:
categories[c] = await ctx.guild.create_category(name=file["categories"][c]["name"],
reason=f"Backup restore by {ctx.message.author}")
for c in file["channels"]:
embed_field_name = file["channels"][c]["name"]
category = None
if file["channels"][c]["category_id"]:
category = categories[file["channels"][c]["category_id"]]
embed_field_name = f"{category.name} > {embed_field_name}"
embed = msg.embeds[0] @commands.group("restore", pass_context=True)
if len(embed.fields) != 0: @commands.guild_only()
embed.set_field_at(-1, name=embed.fields[-1].name, value="\N{check mark}", inline=False) @commands.has_permissions(manage_messages=True)
embed.add_field(name=embed_field_name, value="\N{hourglass}", inline=False) async def restore(self, ctx: commands.Context):
await msg.edit(embed=embed) if len(ctx.message.attachments) != 1:
await ctx.send("No backup file given ! \N{cross mark}")
else:
embed = Embed(title="Restore", description="In progress... \N{hourglass}")
msg = await ctx.send(embed=embed)
chan = await ctx.guild.create_text_channel(name=file["channels"][c]["name"], file = get(ctx.message.attachments[0].url, stream=True)
category=category, file_name = f"backup/{ctx.message.author.id}"
topic=file["channels"][c]["topic"], with open(file_name + ".db", "w+b") as f:
slowmode_delay=file["channels"][c]["slowmode_delay"], for i in file.iter_content():
nsfw=file["channels"][c]["nsfw"], f.write(i)
reason=f"Backup restore by {ctx.message.author}") with shelve.open(file_name) as file:
hook = await chan.create_webhook(name="BackupBot", categories = {}
avatar=None, for c in file["categories"]:
reason=f"Backup restore by {ctx.message.author}") categories[c] = await ctx.guild.create_category(name=file["categories"][c]["name"],
for m in file["channels"][c]["messages"][::-1]: reason=f"Backup restore by {ctx.message.author}")
user = file["users"][m["author_id"]] for c in file["channels"]:
edit = "" embed_field_name = file["channels"][c]["name"]
if m["edited_at"]: category = None
edit = f", edited at: {m['edited_at']}" if file["channels"][c]["category_id"]:
content = f"`created: {m['created_at']}{edit}`" + "\n" + m["content"] category = categories[file["channels"][c]["category_id"]]
avatar = None embed_field_name = f"{category.name} > {embed_field_name}"
if user["avatar"]:
avatar = f"https://cdn.discordapp.com/avatars/{m['author_id']}/{user['avatar']}.webp"
await hook.send(content=content,
username=f"{user['display_name']} ({user['name']}#{user['discriminator']})",
avatar_url=avatar,
files=None,
embeds=m["embeds"])
await hook.delete()
remove(file_name + ".db") embed = msg.embeds[0]
embed = msg.embeds[0] if len(embed.fields) != 0:
embed.set_field_at(-1, name=embed.fields[-1].name, value="\N{check mark}", inline=False) embed.set_field_at(-1, name=embed.fields[-1].name, value="\N{check mark}", inline=False)
embed.description = "Finish ! \N{check mark}" embed.add_field(name=embed_field_name, value="\N{hourglass}", inline=False)
await msg.edit(embed=embed) await msg.edit(embed=embed)
chan = await ctx.guild.create_text_channel(name=file["channels"][c]["name"],
category=category,
topic=file["channels"][c]["topic"],
slowmode_delay=file["channels"][c]["slowmode_delay"],
nsfw=file["channels"][c]["nsfw"],
reason=f"Backup restore by {ctx.message.author}")
hook = await chan.create_webhook(name="BackupBot",
avatar=None,
reason=f"Backup restore by {ctx.message.author}")
for m in file["channels"][c]["messages"][::-1]:
user = file["users"][m["author_id"]]
edit = ""
if m["edited_at"]:
edit = f", edited at: {m['edited_at']}"
content = f"`created: {m['created_at']}{edit}`" + "\n" + m["content"]
avatar = None
if user["avatar"]:
avatar = f"https://cdn.discordapp.com/avatars/{m['author_id']}/{user['avatar']}.webp"
await hook.send(content=content,
username=f"{user['display_name']} ({user['name']}#{user['discriminator']})",
avatar_url=avatar,
files=None,
embeds=m["embeds"])
await hook.delete()
remove(file_name + ".db")
embed = msg.embeds[0]
embed.set_field_at(-1, name=embed.fields[-1].name, value="\N{check mark}", inline=False)
embed.description = "Finish ! \N{check mark}"
await msg.edit(embed=embed)
def setup(bot: commands.Bot): def setup(bot):
logger.info(f"Loading...") logger.info(f"Loading...")
if not isdir("backup"): if not isdir("backup"):
logger.info(f"Create backup folder") logger.info(f"Create backup folder")
mkdir("backup") mkdir("backup")
try: try:
bot.add_command(restore_cmd) bot.add_cog(Restore(bot))
except Exception as e: except Exception as e:
logger.error(f"Error loading: {e}") logger.error(f"Error loading: {e}")
else: else:
logger.info(f"Load successful") logger.info(f"Load successful")
def teardown(bot: commands.Bot): def teardown(bot):
logger.info(f"Unloading...") logger.info(f"Unloading...")
try: try:
bot.remove_command("restore") bot.remove_cog("Restore")
except Exception as e: except Exception as e:
logger.error(f"Error unloading: {e}") logger.error(f"Error unloading: {e}")
else: else:

View file

@ -1,11 +1,14 @@
aiohttp==3.6.2 aiohttp==3.6.2
async-timeout==3.0.1 async-timeout==3.0.1
attrs==19.3.0 attrs==19.3.0
certifi==2020.6.20
chardet==3.0.4 chardet==3.0.4
discord==1.0.1 discord==1.0.1
discord.py==1.3.4 discord.py==1.3.4
idna==2.10 idna==2.10
multidict==4.7.6 multidict==4.7.6
requests==2.24.0
SQLAlchemy==1.3.18 SQLAlchemy==1.3.18
urllib3==1.25.10
websockets==8.1 websockets==8.1
yarl==1.4.2 yarl==1.4.2