wowee i did a thing

pull/1/head
Matt C 3 years ago
parent 9f94be1e35
commit 2878bbf45e

@ -1,5 +1,2 @@
# caveman # caveman
Bang rock together make package tracker bot
Discord bot (pycord) for monitoring repos and stuff
Based on Matt's Gamerbot2 from https://git.tar.black/matt/Gamerbot2

179
bot.py

@ -1,164 +1,15 @@
# Standard python imports import discord,os
import os, string, unicodedata, sys, re, random, time, datetime, subprocess, json, traceback from discord.ext import commands
import urllib.parse
import importlib from task import Packages
from os import listdir bot = commands.Bot(";")
from os.path import isfile, join bot.add_cog(Packages(bot))
# Pycord
import discord if not os.path.exists(os.environ["HOME"] + "/.cavetoken"):
from discord.ext import commands print("No token found")
exit()
# Kind've discord related else:
from pretty_help import DefaultMenu, PrettyHelp token = open(os.environ["HOME"] + "/.cavetoken", "r").read()
bot.run(token)
# Other pip packages
import asyncio
import requests
# My own classes n such
from global_config import configboi
from util_functions import *
if os.path.sep == "\\":
print("This bot is only supported on UNIX-like systems. Aborting.")
sys.exit(1)
intents = discord.Intents.default()
intents.members = True
# Start event handling and bot creation
bot = commands.Bot(
command_prefix=commands.when_mentioned_or(";"),
description="Ooga booga hit rocks together",
intents=intents,
)
helpmenu = DefaultMenu("◀️", "▶️", "")
bot.help_command = PrettyHelp(
no_category="Commands", navigation=helpmenu, color=discord.Colour.blurple()
)
# Sane default?
my_homedir = os.getenv("HOME", "/home/caveman")
# No default b/c we're fucked long before this if PATH is none
old_path = os.getenv("PATH")
new_path = old_path + ":" + my_homedir + "/.local/bin/"
os.environ["PATH"] = new_path
print("Our PATH is: " + os.getenv("PATH"))
# Startup event
@bot.event
async def on_ready():
syslog.log("Main-Important", "Bot has restarted at " + getstamp())
syslog.log("Main", f"\n{bot.user} has connected to Discord!\n")
if check("restarted.txt"):
channel = get("restarted.txt")
chan = bot.get_channel(int(channel))
if chan is not None:
await chan.send(
embed=infmsg("System", "Finished restarting at: `" + getstamp() + "`")
)
os.remove("restarted.txt")
ownerman = await bot.fetch_user(OWNER)
notifyowner = confmgr.getasbool("OWNER_DM_RESTART")
cogs_dir = "cogs"
for extension in [
f.replace(".py", "") for f in listdir(cogs_dir) if isfile(join(cogs_dir, f))
]:
try:
bot.load_extension(cogs_dir + "." + extension)
syslog.log("Main", "Loaded " + extension)
# await ownerman.send(embed=infmsg("System","Loaded `" + extension + "`"))
except (Exception) as e:
await ownerman.send(
embed=errmsg(
"System", "Error from cog: " + extension + ": ```" + str(e) + "```"
)
)
syslog.log("Main", f"Failed to load extension {extension}.")
# traceback.print_exc()
if notifyowner:
await ownerman.send(
embed=infmsg("System", "Started/restarted at: `" + getstamp() + "`")
)
@bot.event
async def on_message(message):
if message.author != bot.user:
mc = message.content
if "bot" in mc:
# we're being talked to
if "bad" in mc or "sucks" in mc:
await message.channel.send(":(")
await bot.process_commands(message)
@bot.event
async def on_command_error(ctx, error):
syslog.log("Main", "Error in command: " + str(error))
await ctx.send(embed=errmsg("Error", "```" + str(error) + "```"))
@bot.command()
async def removecog(ctx, name):
"""Un-load a cog that was loaded by default."""
if ctx.message.author.id == OWNER:
await ctx.send(embed=infmsg("Gotcha", "Ok, I'll try to disable `" + name + "`"))
try:
bot.remove_cog(name)
syslog.log("Main", "Disabled cog: " + name)
await ctx.send(embed=warnmsg("Done", "Disabled: `" + name + "`."))
except Exception as e:
await ctx.send(
embed=errmsg("Broke", "Something went wrong: `" + str(e) + "`.")
)
else:
await ctx.send(embed=errmsg("Oops", wrongperms("removecog")))
@bot.command()
async def getsyslog(ctx):
"""Get a copy of the system log"""
if ctx.message.author.id == OWNER:
log = syslog.getlog()
if len(log) > 1994:
text = paste(log)
await ctx.send(embed=infmsg("Output", text))
else:
text = "```" + log + "```"
await ctx.send("Here you go:")
await ctx.send(text)
else:
await ctx.send(embed=errmsg("Oops", wrongperms("getsyslog")))
if UNLOAD_COGS is not None:
# Remove any cogs as per config
for item in UNLOAD_COGS:
if item != "" and item != " ":
syslog.log("Main", "Trying to remove '" + item + "'")
try:
bot.remove_cog(item)
syslog.log("Main", "Removed '" + item + "'")
except:
syslog.log("Main", "Failed to remove '" + item + "'")
if check(".cavetoken"):
token = open(".cavetoken").read().strip()
else:
fail("No token found in .cavetoken")
bot.run(token)

@ -1,68 +0,0 @@
import discord
from discord.ext import commands
from util_functions import *
# Hopefully we'll never need logging here
class About(commands.Cog):
"""Stuff that the developer couldn't find a better category for"""
def __init__(self, bot):
self.bot = bot
@commands.command()
async def source(self, ctx):
"""Bot source code link"""
await ctx.send(
embed=infmsg(
"Source",
"My source code lives here: https://git.getcryst.al/crystal/caveman",
)
)
@commands.command()
async def report(self, ctx):
"""Report bot issues"""
await ctx.send(
embed=infmsg(
"Issues",
"You can file issues here: https://git.getcryst.al/crystal/caveman/issues",
)
)
@commands.command()
async def suggest(self, ctx):
"""Suggest bot feature(s)"""
await ctx.send(
embed=infmsg(
"Issues",
"You can file issues here: https://git.getcryst.al/crystal/caveman/issues",
)
)
@commands.command()
async def version(self, ctx):
"""Bot version"""
commit_msg = await run_command_shell(
"git --no-pager log --decorate=short --pretty=oneline -n1"
)
msg = ""
msg += "Latest Git commit: \n"
msg += "```" + commit_msg + "```"
await ctx.send(embed=infmsg("Bot Stats", msg))
@commands.command()
async def invite(self, ctx):
"""Add me to another server"""
await ctx.send(
embed=infmsg(
"Invite me :)",
"https://discord.com/api/oauth2/authorize?client_id=900841588996063282&permissions=8&scope=bot%20applications.commands",
)
)
def setup(bot):
bot.add_cog(About(bot))

@ -1,130 +0,0 @@
import discord
from discord.ext import commands
from util_functions import *
from global_config import configboi
# Hopefully we'll never need logging here
class Debug(commands.Cog):
"""Stuff that the developer couldn't find a better category for"""
def __init__(self, bot):
self.bot = bot
self.confmgr = configboi("config.txt", False)
@commands.command()
async def checkcog(self, ctx, *, n):
"""check if cog is a thing"""
try:
if ctx.bot.get_cog(n) is not None:
await ctx.send(
embed=infmsg("Debug Tools", "Bot was able to find `" + n + "`")
)
else:
await ctx.send(
embed=errmsg("Debug Tools", "Bot was not able to find `" + n + "`")
)
except Exception as e:
await ctx.send(
embed=errmsg(
"Debug Tools - ERROR",
"Had error `" + str(e) + "` while checking cog `" + n + "`",
)
)
@commands.command()
async def restart(self, ctx):
"""Restart the bot (Mod. only)"""
if ctx.message.author.id == OWNER:
await ctx.send(embed=infmsg("Sad", "Ok, restarting"))
if ctx.voice_client is not None:
await ctx.voice_client.disconnect()
await ctx.bot.logout()
syslog.log(
"Admin-Important",
"Bot is restarting because "
+ ctx.message.author.display_name
+ " requested we do so.",
)
save("restarted.txt", str(ctx.message.channel.id))
await login(os.environ["bottoken"], bot=True)
else:
await ctx.send(embed=errmsg("Oops", wrongperms("restart")))
@commands.command()
async def update(self, ctx):
"""Update bot from Git, and restart (Mod. only)"""
if ctx.message.author.id == OWNER:
await ctx.send(embed=infmsg("Updater", "Updating..."))
syslog.log(
"Admin-Important",
"Bot is updating & restarting because "
+ ctx.message.author.display_name
+ " requested we do so.",
)
# are these being upset?
pull_out = await run_command_shell("git pull -v")
commit_msg = await run_command_shell(
"git --no-pager log --decorate=short --pretty=oneline -n1"
)
msg = (
"Changes:"
+ "\n```"
+ pull_out
+ "```\nCommit message:\n"
+ "```"
+ commit_msg
+ "```"
)
await ctx.send(embed=infmsg("Updater", msg))
await run_command_shell("pip3 install --upgrade -r requirements.txt")
await ctx.send(embed=infmsg("Updater", "Restarting"))
if ctx.voice_client is not None:
await ctx.voice_client.disconnect()
await ctx.bot.logout()
save("restarted.txt", str(ctx.message.channel.id))
await login(os.environ["bottoken"], bot=True)
else:
await ctx.send(embed=errmsg("Oops", wrongperms("update")))
@commands.command()
async def chbranch(self, ctx, *, branch):
"""Switch bot's upstream to a given branch (Mod. only)"""
if ctx.message.author.id == OWNER:
await ctx.send(embed=infmsg("Updater", "Switching branch..."))
syslog.log(
"Admin-Important",
"Bot is switching branch to "
+ branch
+ " because "
+ ctx.message.author.display_name
+ " requested we do so.",
)
await run_command_shell("git checkout " + branch)
await ctx.send(embed=infmsg("Updater", "Done!"))
else:
await ctx.send(embed=errmsg("Oops", wrongperms("chbranch")))
@commands.command()
async def gitstatus(self, ctx):
"""Show the output of git status"""
commit_msg = await run_command_shell(
"git --no-pager log --decorate=short --pretty=oneline -n1"
)
await ctx.send(embed=infmsg("Git Status", "```" + commit_msg + "```"))
@commands.command()
async def purgesyslog(self, ctx):
"""Delete all existing syslogs (USE WITH CARE) (Owner only)"""
if ctx.message.author.id == OWNER:
purged = await run_command_shell("rm system_log* -v")
await ctx.send(embed=infmsg("Syslog Purger", "We purged:\n```" + purged + "```"))
else:
await ctx.send(embed=errmsg("Oops", wrongperms("purgesyslog")))
def setup(bot):
bot.add_cog(Debug(bot))

@ -1,23 +0,0 @@
import discord
from discord.ext import commands
from util_functions import *
# Hopefully we'll never need logging here
class Random(commands.Cog):
"""Stuff that the developer couldn't find a better category for"""
def __init__(self, bot):
self.bot = bot
@commands.command()
async def ping(self, ctx):
"""pong."""
await ctx.send(
"pong. :upside_down: :gun:", file=discord.File("images/pong.jpg")
)
def setup(bot):
bot.add_cog(Random(bot))

@ -1,110 +0,0 @@
import sys, datetime, os
import discord
from discord.ext import commands, tasks
import feedparser,requests
from global_config import configboi
from util_functions import *
sc = configboi("config.txt", False)
REFRESH_TIME = sc.getasint("REFRESH_TIME")
class RSS(commands.Cog):
"""This cog handles RSS stuff"""
def __init__(self, bot):
self.bot = bot
self.confmgr = configboi("config.txt", False)
self.package_names = self.confmgr.getaslist("WATCHED_PACKAGES")
temp = self.confmgr.getaslist("FEED_URLS")
self.gitea_urls = self.confmgr.getaslist("GITEA_URLS")
self.package_channel = self.confmgr.getasint("PACKAGE_CHANNEL")
self.feed_urls = []
for feed in temp:
self.feed_urls.append("https://" + feed)
self.chan = self.bot.get_channel(self.package_channel)
if self.chan is None:
syslog.log("RSS", "Package task failed because we couldn't find the target channel.")
sys.exit(1)
self.root = "package-cache"
ensure(self.root)
self.package_task.start()
def cog_unload(self):
self.package_task.cancel()
@commands.Cog.listener()
async def on_ready(self):
syslog.log("RSS", "Running initial package check")
await self.check_packages()
@tasks.loop(seconds=REFRESH_TIME)
async def package_task(self):
await self.check_packages()
@package_task.before_loop
async def before_status_task(self):
syslog.log(
"RSS", "Waiting for bot to be ready before starting package task"
)
await self.bot.wait_until_ready()
syslog.log("RSS", "Bot is ready. Enabling package task")
async def sendwarn(self, msg):
await self.chan.send(embed=warnmsg("RSS",msg))
async def senderr(self, msg):
await self.chan.send(embed=errmsg("RSS",msg))
async def send(self, msg):
await self.chan.send(embed=infmsg("RSS",msg))
def dolog(self, msg):
syslog.log("RSS", msg)
async def check_packages(self):
try:
for feed in self.feed_urls:
self.dolog("Checking: " + feed)
previous = ""
if check(self.root + "/" + feed.replace("/","-")):
self.dolog("Found previous cached data")
previous = open(self.root + "/" + feed.replace("/","-")).read().strip()
else:
self.dolog("No previous data")
new = requests.get(feed).text
if new != previous:
self.dolog("New data is different")
if check(self.root + "/" + feed.replace("/","-")):
os.remove(self.root + "/" + feed.replace("/","-"))
with open(self.root + "/" + feed.replace("/","-"), "w") as f:
f.write(new)
self.dolog("Updated cache")
d = feedparser.parse(new)
for item in d.entries:
pkgn = str(item['title'])
if " " in pkgn:
pkgn = pkgn.split(" ")[0]
for tgt in self.package_names:
if tgt in pkgn:
await self.send("Package change: `" + str(item['title']) + "`")
break
except Exception as e:
syslog.log("RSS ERROR", str(e))
def setup(bot):
bot.add_cog(RSS(bot))

@ -1,91 +0,0 @@
import sys, datetime
import discord
from discord.ext import commands, tasks
from global_config import configboi
from util_functions import *
class Status(commands.Cog):
"""This cog keeps the bot status in sync"""
def __init__(self, bot):
self.bot = bot
self.confmgr = configboi("config.txt", False)
self.status_task.start()
self.uptime_logger.start()
self.upt = 0
def cog_unload(self):
self.status_task.cancel()
self.uptime_logger.cancel()
async def setDefaultStatus(self):
ac_type = None
if self.confmgr.get("DEFAULT_STATUS_TYPE") == "watching":
ac_type = discord.ActivityType.watching
elif self.confmgr.get("DEFAULT_STATUS_TYPE") == "listening":
ac_type = discord.ActivityType.listening
elif self.confmgr.get("DEFAULT_STATUS_TYPE") == "streaming":
ac_type = discord.ActivityType.streaming
total = 0
if "{number_users}" in self.confmgr.get("DEFAULT_STATUS_TEXT"):
guilds = self.bot.guilds
for guild in guilds:
total += guild.member_count
if ac_type is None:
ac_type = discord.ActivityType.playing
await self.bot.change_presence(
activity=discord.Activity(
type=ac_type,
name=self.confmgr.get("DEFAULT_STATUS_TEXT")
.replace("{guild_count}", str(len(list(self.bot.guilds))))
.replace("{number_users}", str(total)),
)
)
@commands.Cog.listener()
async def on_ready(self):
syslog.log("Bot Status", "Setting default status as per config")
await self.setDefaultStatus()
@tasks.loop(seconds=60.0)
async def status_task(self):
await self.setDefaultStatus()
@status_task.before_loop
async def before_status_task(self):
syslog.log(
"Bot Status", "Waiting for bot to be ready before starting updater task"
)
await self.bot.wait_until_ready()
syslog.log("Bot Status", "Bot is ready. Enabling update task")
@tasks.loop(seconds=1.0)
async def uptime_logger(self):
self.upt += 1
@uptime_logger.before_loop
async def before_logger_task(self):
await self.bot.wait_until_ready()
@commands.command(aliases=["uptime"])
async def getuptime(self, ctx):
await ctx.send(
embed=infmsg(
"Bot Stats",
"Uptime: `" + str(datetime.timedelta(seconds=self.upt)) + "`",
)
)
def setup(bot):
bot.add_cog(Status(bot))

@ -1,48 +0,0 @@
# This is a comment!
# Note: In the code, if the data type is not supported,
# you'll have to deal yourself (by editing global_config.py likely)
# Also, at the moment, these aren't type safe, so if you use this file in other cogs,
# make sure to use the correct getter function for the type you expect it to be. (and cast!)
# General bot stuff
# Types: watching, listening, playing
DEFAULT_STATUS_TYPE:watching
# These are currently the only substitutions
# - {number_users}
# - {guild_count}
DEFAULT_STATUS_TEXT:for ;
# Any default cogs you don't want to load:
# Example: UNLOAD_COGS:Internet,Speak
# Or maybe more likely: UNLOAD_COGS:Shells
# Blank is fine, too
UNLOAD_COGS:
# Who gets all log messages, and run extra-privileged commands
OWNER:117445905572954121
# Text for messages:
# Note {command} is the only substitution allowed here (we do auto-mention the user)
WRONG_PERMS:You're not a special snowflake, so you can't run `{command}`
# Should the owner get a DM when the bot restarts
OWNER_DM_RESTART:True
######################################################################################
# Package settings #
######################################################################################
# Package names to care about
WATCHED_PACKAGES:grub,arch-install-scripts,base,filesystem,lsb-release,neofetch,pfetch
# How often to re-query the feed(s) {in seconds}
REFRESH_TIME:3600
# Feed source(s)
FEED_URLS:archlinux.org/feeds/packages/
# Channel to send notifications
PACKAGE_CHANNEL:900844916974977125

@ -1,99 +0,0 @@
import os
# Nonstandard to avoid depend loop
from logger import BotLogger
syslog = BotLogger("system_log.txt")
def check(fn):
if os.path.exists(fn):
return True
else:
return False
class configboi:
def __init__(self, fn, logging=True):
self.config = {}
if not check(fn):
if logging:
syslog.log("Config", "No config found!")
else:
if logging:
syslog.log("Config", "----- Loading config values -----")
with open(fn) as f:
config_lines = f.read().split("\n")
for line in config_lines:
if line != "" and line != "\n":
if line[0] != "#":
bits = line.split(":")
key = bits[0]
val = bits[1]
if logging:
syslog.log("Config", "Added " + key + ": " + val)
self.config[key] = val
self.islogging = logging
def reloadconfig(self):
if not check(fn):
if self.logging:
syslog.log("Config", "No config found!")
else:
if self.logging:
syslog.log("Config", "----- Loading config values -----")
with open(fn) as f:
config_lines = f.read().split("\n")
for line in config_lines:
if line != "" and line != "\n":
if line[0] != "#":
bits = line.split(":")
key = bits[0]
val = bits[1]
if self.logging:
syslog.log("Config", "Added " + key + ": " + val)
self.config[key] = val
def get(self, key):
if key in self.config:
return self.config[key].replace("//", "://")
else:
return "Not found"
def getasint(self, key):
if key in self.config:
return int(self.config[key])
else:
return 0
def getasbool(self, key):
if key in self.config:
result = self.config[key]
if result == "true" or result == "True":
return True
else:
return False
else:
return False
def getaslist(self, key):
if key in self.config:
if "," in self.config[key]:
return self.config[key].split(",")
else:
return [self.config[key]]
else:
return None
def getasintlist(self, key):
if key in self.config:
if "," in self.config[key]:
data = self.config[key].split(",")
newdata = []
for item in data:
newdata.append(int(item))
return newdata
else:
return [int(self.config[key])]
else:
return [0]

@ -1,31 +0,0 @@
import os
def getstamp():
os.system("date >> stamp")
with open("stamp") as f:
s = f.read()
os.remove("stamp")
return s
class BotLogger:
def __init__(self, filename):
if os.path.exists(filename):
n = 0
while os.path.exists(filename + "." + str(n)):
n += 1
filename = filename + "." + str(n)
self.fn = filename
def log(self, caller, text):
info = getstamp().strip() + " --> " + caller + ": " + text
with open(self.fn, "a+") as f:
f.write("\n" + info + "\n")
print(info)
def getlog(self):
with open(self.fn) as f:
return f.read()

@ -1,6 +1,2 @@
py-cord[voice] feedparser
discord-pretty-help py-cord
requests
asyncio
requests
feedparser

@ -0,0 +1,69 @@
from discord.ext import tasks, commands
import feedparser,os
CHAN = 825480016045408329
ROLE = 825474723948265474
WATCHED = "grub,arch-install-scripts,base,filesystem,lsb-release,neofetch,pfetch"
class Package:
def __init__(self,name,ver,arch):
self.name = name
self.ver = ver
self.arch = arch
def __str__(self):
return self.name + ' ' + self.ver + ' ' + self.arch
def __repr__(self):
return self.__str__()
class Packages(commands.Cog):
def __init__(self, bot):
self.bot = bot
self.check.start()
if not os.path.exists("packages"):
os.makedirs("packages")
def cog_unload(self):
self.check.cancel()
@tasks.loop(seconds=300)
async def check(self):
watched = WATCHED.split(",")
new = []
feed_data = feedparser.parse('https://archlinux.org/feeds/packages/')
for entry in feed_data.entries:
info = entry.title
name,version,arch = info.split(" ")
if name in watched:
p = Package(name,version,arch)
new.append(p)
for p in new:
if os.path.exists("packages/" + p.name):
ver = open("packages/" + p.name, "r").read()
if ver != p.ver:
os.remove("packages/" + p.name)
with open("packages/" + p.name, "w") as f:
f.write(p.ver)
else:
new.pop(p)
else:
with open("packages/" + p.name, "w") as f:
f.write(p.ver)
if new != []:
await self.bot.get_channel(CHAN).send("<@&" + str(ROLE) + ">, there are package changes.")
for p in new:
print(str(p))
print("-"*10)
msg = "`" + p.name + "` is now `" + p.ver + "`"
await self.bot.get_channel(CHAN).send(msg)
#else:
# await self.bot.get_channel(CHAN).send("No new packages")
@check.before_loop
async def before_check(self):
print('waiting for bot to be ready...')
await self.bot.wait_until_ready()

@ -1,141 +0,0 @@
# System
import os, sys, random, string
# Pip
import asyncio, requests, discord
# Me
from global_config import configboi
from logger import BotLogger
# lol
confmgr = configboi("config.txt", False)
syslog = BotLogger("system_log.txt")
# <-------------- Don't touch pls --------------->
# If you're adding your own stuff, you need to look at
# global_config.py to see the supported data types, and add your
# own if needed.
# .get is string
VER = confmgr.get("VER")
HELP_LOC = confmgr.get("HELP_LOC")
WRONG_PERMS = confmgr.get("WRONG_PERMS")
NEW_MEMBER = confmgr.get("NEW_MEMBER")
INTRO_CHANNEL = confmgr.get("INTRO_CHANNEL")
DEFAULT_STATUS_TYPE = confmgr.get("DEFAULT_STATUS_TYPE")
DEFAULT_STATUS_TEXT = confmgr.get("DEFAULT_STATUS_TEXT")
UNLOAD_COGS = confmgr.getaslist("UNLOAD_COGS")
OWNER = confmgr.getasint("OWNER")
# <-------------- End --------------------->
# <--------------Colors Start-------------->
# For embed msgs (you can override these if you want)
# But changing the commands which use embed would be better
purple_dark = 0x6A006A
purple_medium = 0xA958A5
purple_light = 0xC481FB
orange = 0xFFA500
gold = 0xDAA520
red_dark = 8e2430
red_light = 0xF94343
blue_dark = 0x3B5998
cyan = 0x5780CD
blue_light = 0xACE9E7
aqua = 0x33A1EE
pink = 0xFF9DBB
green_dark = 0x2AC075
green_light = 0xA1EE33
white = 0xF9F9F6
cream = 0xFFDAB9
# <--------------Colors End-------------->
def strip_dangerous(text):
remove = [";", "&&", "&", '"']
for thing in remove:
text = text.replace(thing, "")
if "\n" in text:
text = text.split("\n")[0]
return text
def fancymsg(title, text, color, footnote=None):
e = discord.Embed(colour=color)
e.add_field(name=title, value=text, inline=False)
if footnote is not None:
e.set_footer(text=footnote)
return e
def errmsg(title, text, footnote=None):
return fancymsg(title, text, discord.Colour.red(), footnote)
def warnmsg(title, text, footnote=None):
return fancymsg(title, text, discord.Colour.gold(), footnote)
def infmsg(title, text, footnote=None):
return fancymsg(title, text, discord.Colour.blurple(), footnote)
def imgbed(title, type, dat):
# see https://discordpy.readthedocs.io/en/stable/faq.html?highlight=embed#how-do-i-use-a-local-image-file-for-an-embed-image
e = discord.Embed(color=discord.Colour.blurple())
e.add_field(name="foo", value=title, inline=False)
if type == "rem":
e.set_image(url=dat)
else:
e.set_image(url="attachment://" + dat)
return e
# Simple file wrappers
def check(fn):
if os.path.exists(fn):
return True
else:
return False
def save(fn, text):
with open(fn, "a+") as f:
f.write(text + "\n")
def get(fn):
if check(fn):
with open(fn) as f:
return f.read()
def ensure(fn):
if not check(fn):
os.makedirs(fn, exist_ok=True)
def getstamp():
if sys.platform != "win32":
os.system("date >> stamp")
with open("stamp") as f:
s = f.read()
os.remove("stamp")
return s
else:
return ""
def wrongperms(command):
syslog.log("System", "Someone just failed to run: '" + command + "'")
return WRONG_PERMS.replace("{command}", command)
def fail(msg):
syslog.log("System ERROR", msg)
sys.exit(1)
Loading…
Cancel
Save