Example #1
0
async def modMention(message, client, typ):
    split = message.content.split()
    correctUsageString = getUseString(typ + "role", client)

    if await checkMinArgs(message, 2, correctUsageString): return

    sid = await checkInt(message, split[1], correctUsageString)
    if sid is False: return

    rid = await checkInt(message, split[2], correctUsageString)
    if rid is False: return

    role = message.guild.get_role(int(rid))
    if not role:
        return await sendError(message, f"{split[2]} is not a valid role id.",
                               correctUsageString)

    mentions = utils.loadJson(globals.MENTION_FILE)

    sData = utils.loadJson(globals.SERIES_FILE)
    sName = str(sid)
    if str(sid) in sData: sName = f"{sData[str(sid)]['title']} ({sName})"

    if typ == "add":
        if str(sid) not in mentions: mentions[str(sid)] = []
        if str(rid) in mentions[str(sid)]:
            return await message.channel.send(
                f"Error. `{role.name} ({rid})` is already a mentioned role for series `{sName}`."
            )
        mentions[str(sid)].append(str(rid))
    elif typ == "remove":
        if str(rid) not in mentions[str(sid)]:
            return await message.channel.send(
                f"Error. `{role.name} ({rid})` is not a mentioned role for series `{sName}`."
            )
        mentions[str(sid)] = [
            x for x in mentions[str(sid)] if str(x) != str(rid)
        ]

    lst = []
    for x in mentions[str(sid)]:
        role = message.guild.get_role(int(rid))
        if role: name = role.name
        else:
            continue
            name = "unknown"

        lst.append(f"`{name} ({x})`")
    await message.channel.send(f"Pinged roles for **`{sName}`**: " +
                               ", ".join(lst))

    utils.dumpJson(mentions, globals.MENTION_FILE)
Example #2
0
async def scanMessages(client, last=False):
    channel = client.get_channel(int(CONFIG['SUBMISSION_CHANNEL']))

    log = None
    if last: log = utils.loadJson(globals.MSG_FILE)
    if not log: log = {"log": [], "members": {}, "last_parsed": ""}

    try:
        if last and log["last_parsed"]:
            last = await channel.fetch_message(log['last_parsed'])
        else:
            last = None
    except:
        last = None
        print("resetting log")
        log = {"log": [], "members": {}, "last_parsed": ""}

    async for msg in channel.history(limit=None, oldest_first=True,
                                     after=last):
        print("Scanning", msg.content)
        log['log'].append(sheetUtils.msgToDict(msg))
        log['members'][msg.author.id] = msg.author.name
        log['last_parsed'] = msg.id

    with open("data/msg_log.json", "w+") as file:
        json.dump(log, file, indent=2)

    parse.parse()

    return len(log['log'])
Example #3
0
async def modUser(message, client, typ):
    split = message.content.split()
    correctUsageString = getUseString(typ + "user", client)

    if await checkMinArgs(message, 1, correctUsageString): return
    val = await checkInt(message, split[1], correctUsageString)
    if val is False: return
    user = client.get_user(val)
    if not user:
        return await sendError(message, f"{split[1]} is not a valid user id.",
                               correctUsageString)

    config = utils.loadJson(globals.CONFIG_FILE)

    if typ == "add":
        if str(val) in config["ADMINS"]:
            return await message.channel.send(
                f"Error. {user.name} ({val}) is already a bot admin.")
        config["ADMINS"].append(str(val))
    elif typ == "remove":
        if str(val) not in config["ADMINS"]:
            return await message.channel.send(
                f"Error. {user.name} ({val}) is not a bot admin.")
        config["ADMINS"] = [x for x in config['ADMINS'] if x != str(val)]

    lst = []
    for x in config['ADMINS']:
        user = client.get_user(int(x))
        if user: name = user.name
        else: name = "unknown"

        lst.append(f"`{name} ({x})`")
    await message.channel.send("Current admins: " + ", ".join(lst))

    utils.dumpJson(config, globals.CONFIG_FILE)
Example #4
0
async def modChannel(message, client, typ):
    split = message.content.split()
    correctUsageString = getUseString(typ + "channel", client)

    if await checkMinArgs(message, 1, correctUsageString): return

    val = await checkInt(message, split[1], correctUsageString)
    if val is False: return

    ch = client.get_channel(val)
    if not ch:
        return await sendError(message,
                               f"{split[1]} is not a valid channel id.",
                               correctUsageString)

    config = utils.loadJson(globals.CONFIG_FILE)

    if typ == "add":
        if str(val) in config["UPDATE_CHANNELS"]:
            return await message.channel.send(
                f"Error. <#{val}> is already an update channel.")
        config["UPDATE_CHANNELS"].append(str(val))
    elif typ == "remove":
        if str(val) not in config["UPDATE_CHANNELS"]:
            return await message.channel.send(
                f"Error. <#{val}> is not an update channel.")
        config["UPDATE_CHANNELS"] = [
            x for x in config['UPDATE_CHANNELS'] if x != str(val)
        ]

    lst = [f"<#{x}>" for x in config['UPDATE_CHANNELS']]
    await message.channel.send("Current update channels:" + ", ".join(lst))

    utils.dumpJson(config, globals.CONFIG_FILE)
Example #5
0
def parse():
    data = utils.loadJson(globals.MSG_FILE)

    i, warningCount = 0, 0
    matches = []
    warningLog = []
    parsedData = []
    for msg in data['log']:
        text = msg['content'].split("\n")

        m, failures = scanMessage(msg)
        if not m:
            # print('here',m, failures)
            continue
        if failures:
            cpy = copy.deepcopy(msg)
            cpy['failed'] = failures
            warningLog.append(cpy)

        dct = listToDict(m[0])
        msg['parsed'] = dct
        matches.append(dct)
        parsedData.append(msg)

    matches = cleanMatches(matches)

    # debugPrint(matches, warningLog)

    with open(globals.PARSED_FILE, "w+") as file:
        d = {
            "parsed": parsedData,
            "warnings": warningLog,
            "members": data['members']
        }
        json.dump(d, file, indent=2)
Example #6
0
async def listSeries(message, client):
    sData = utils.loadJson(globals.SERIES_FILE)
    lst = []

    for sid in sData:
        lst += [f"[{utils.zeroPad(sid)}] {sData[sid]['title']}"]

    join = '\n'.join(lst)
    text = f"```css\n{join}\n```"
    await message.channel.send(text)
Example #7
0
def updateSeriesData(update):
    sid = update['sId']
    data = utils.loadJson(globals.SERIES_FILE)

    if sid not in data or True:
        data[sid] = {}
        data[sid]['title'] = update['sName']
        data[sid]['link'] = update['sLink']
        data[sid]['cover'] = update['cover']

        html = requests.get(update['sLink']).text
        soup = bs(html, 'html.parser')
        desc = soup.find(
            "div", class_="col-lg-9 col-md-8 col-xs-12 text-muted").findAll(
                text=True, recursive=False)
        desc = ''.join(desc).strip()
        data[sid]['description'] = desc

    utils.dumpJson(data, globals.SERIES_FILE)
Example #8
0
    async def on_message(self, message):
        if message.author.id == self.user.id: return

        m = message.content.lower().replace(self.prefix, "", 1)
        args = [message, self]

        isAdmin = str(message.author.id) in utils.loadJson(
            globals.CONFIG_FILE)['ADMINS']
        if isAdmin:
            print(message.author.name, message.content)
            if m.startswith("help"):
                await help(*args)
            elif m.startswith("sett"):
                await settings(*args)
            elif m.startswith("setde"):
                await setDelay(*args)
            elif m.startswith("setdis"):
                await setDiscordDelay(*args)
            elif m.startswith("addc"):
                await modChannel(*args, typ="add")
            elif m.startswith("removec"):
                await modChannel(*args, typ="remove")
            elif m.startswith("addu"):
                await modUser(*args, typ="add")
            elif m.startswith("removeu"):
                await modUser(*args, typ="remove")
            elif m.startswith("addr"):
                await modMention(*args, typ="add")
            elif m.startswith("remover"):
                await modMention(*args, typ="remove")
            elif m.startswith("ser"):
                await listSeries(*args)
            elif m.startswith("listr"):
                await listRoles(*args)

        # todo: hardcode
        if isAdmin or message.guild.id == 425423910759170049:
            if m.startswith("stat"):
                print(message.author.name, message.content)
                await scanMessages(self, last=True)
                await stats(*args)
            elif m.startswith("update"):
                await updateSheet(self, message)
Example #9
0
async def setDiscordDelay(message, client):
    split = message.content.split()
    correctUsageString = getUseString("setdelay", client)

    if await checkMinArgs(message, 1, correctUsageString): return

    val = await checkInt(message, split[1], correctUsageString)
    if val is False: return
    if val < 0:
        return await sendError(message, "Delay interval must be positive",
                               correctUsageString)

    config = utils.loadJson(globals.CONFIG_FILE)
    oldDelay = config["DISCORD_DELAY"]
    config["DISCORD_DELAY"] = val
    utils.dumpJson(config, globals.CONFIG_FILE)

    await message.channel.send(
        f"Updates are delayed `{val}` seconds (from `{oldDelay}`).")
Example #10
0
def getSeriesData(sid):
    data = utils.loadJson(globals.SERIES_FILE)
    return data[str(sid)]
Example #11
0
from utilss import utils, globals
import requests, re, asyncio, json, copy, time
from bs4 import BeautifulSoup as bs

CONFIG = utils.loadJson(globals.CONFIG_FILE)


def parseUpdateDiv(dv):
    ret = {
        "chLink": "N/A",
        "chNum": "-1",
        "chId": "-1",
        "sLink": "N/A",
        "sName": "N/A",
        "sId": "-1"
    }

    linkDiv = dv.find("div", class_="media media-comic-card")
    infoDiv = dv.find("div", class_="list-body")

    ret['chLink'] = linkDiv.find("a")['href'].strip()
    ret['chNum'] = linkDiv.find(
        "span",
        class_="badge badge-md text-uppercase bg-darker-overlay").text.strip()
    ret['chId'] = re.search(r"/(\d+)/(\d+)[/|$]*", ret['chLink']).group(2)
    ret['cover'] = "https://zeroscans.com/" + re.search(
        r"(/storage/.+)\);",
        linkDiv.find("a")['style']).group(1)

    ret['sLink'] = infoDiv.find("a")['href'].strip()
    ret['sName'] = infoDiv.find("a").text.strip()
Example #12
0
def reload():
    global CONFIG, CACHE, MENTIONS
    CONFIG = utils.loadJson(globals.CONFIG_FILE)
    CACHE = utils.loadJson(globals.CACHE_FILE, default=globals.CACHE_DEFAULT)
    MENTIONS = utils.loadJson(globals.MENTION_FILE)
Example #13
0
async def stats(message, client):
    split = [x.lower() for x in message.content.split(maxsplit=1)]

    data = utils.loadJson(globals.PARSED_FILE)
    tallies = statUtils.getTallies(data)

    if len(split) == 1:
        gStats = statUtils.getGlobalStats(tallies, data, num=3)

        h1 = ['Type', '30 Days', 'All-time']
        h2 = ['Type', 'Users (30 days)', 'Users (all)']
        p1 = utils.pprint(gStats['all'], headers=h1)
        p2 = utils.pprint(gStats['users'], headers=h2)

        p1 = "\n".join(p1.split("\n")[:-1]) + "\n" + "".join(
            ["-"] * len(p1.split("\n")[0])) + "\n" + p1.split("\n")[-1]

        title = "@ All Users"
        s = f"""```py\n\n{title}\n\n{p1}\n\n{p2}\n```"""
        s = utils.breakMessage(s, codeblock=True, lang="py")

        for m in s:
            await message.channel.send(m)
        return
    else:
        spl = [x.lower() for x in split[1].split()]

        catMatch = [
            x for x in tallies['all']
            if x.lower() == spl[0] and spl[0] != 'all'
        ]
        if catMatch:
            catMatch = catMatch[0]

            flag = False
            if 'all' in spl: flag = True

            header = [f'User', '30 Days', 'All-time']
            catStats = statUtils.getSingleCatStats(catMatch,
                                                   tallies,
                                                   data,
                                                   allSort=flag)

            s = f'```py\n\n@ {catMatch.upper()} Stats\n\n{utils.pprint(catStats, headers=header)}\n```'
            if not flag:
                s += "\n(Include `all` at the end to sort by all-time counts.)"

            s = utils.breakMessage(s, codeblock=True, lang="py")

            for msg in s:
                await message.channel.send(msg)
            return

        else:
            catStats = statUtils.getCatStats(tallies)

            username = None
            try:
                username = int(split[1].replace("<@!", "").replace(">", ""))
                username = client.get_user(username).name
            except ValueError:
                for x in data['members']:
                    if all(
                        [y.lower() in data['members'][x].lower()
                         for y in spl]):
                        username = data['members'][x]
                        break

            if not username:
                return await message.channel.send(
                    f"Error. `{split[1]}` is not a known user.")

            uStats = statUtils.getUserStats(username, data, tallies)
            for x in uStats['stats']:
                cat = x[0].lower()
                rankRecent = 1 + catStats[cat]['recent'].index(int(x[1]))
                rankAll = 1 + catStats[cat]['all'].index(int(x[2]))
                x[1] = f"{x[1].ljust(3)}" + f"(rank-{rankRecent})".rjust(10)
                x[2] = f"{x[2].ljust(3)}" + f"(rank-{rankAll})".rjust(10)

            h1 = ['Type'.ljust(7), '30 Days', 'All-time']
            h2 = ['Type'.ljust(7), 'Days Ago', 'Chap', 'Series']

            p1 = utils.pprint(uStats['stats'], headers=h1)
            p1 = "\n".join(p1.split("\n")[:-1]) + "\n" + "".join(
                ["-"] * len(p1.split("\n")[0])) + "\n" + p1.split("\n")[-1]

            if uStats['recent']:
                p2 = "\n\n" + utils.pprint(uStats['recent'], headers=h2)
            else:
                p2 = ""

            title = f"@ {username}"
            s = f"""```py\n{title}\n\n{p1}{p2}\n```"""
            s = utils.breakMessage(s, codeblock=True, lang="py")

            for msg in s:
                await message.channel.send(msg)
            return
Example #14
0
async def settings(message, client):
    config = utils.loadJson(globals.CONFIG_FILE)
    config['mentions'] = utils.loadJson(globals.MENTION_FILE)
    del config["DISCORD_KEY"]

    # Make channels readable
    cpy = []
    for chid in config['UPDATE_CHANNELS']:
        uCh = client.get_channel(int(chid))
        if int(uCh.guild.id) != int(message.guild.id): cpy.append(uCh.id)
        else: cpy.append(f"{uCh.name} ({uCh.id})")
    config['UPDATE_CHANNELS'] = cpy

    # Make roles readable
    sData = utils.loadJson(path=globals.SERIES_FILE)
    cpy = copy.deepcopy(config['mentions'])
    for sid in cpy:
        for mid in cpy[sid]:
            mid = int(mid)
            role = message.guild.get_role(mid)
            if role: name = role.name
            else:
                if sid in config['mentions']:
                    config['mentions'][sid].remove(str(mid))
                    if sid in config[
                            'mentions'] and not config['mentions'][sid]:
                        del config['mentions'][sid]
                continue
                name = "unknown"

            if str(sid) not in sData and str(sid) != "-1":
                stitle = "unknown"
                print("WARNING:", sid, "is an unknown series.")
            elif str(sid) != "-1":
                stitle = sData[str(sid)]['title']

            if sid != "-1": key = f"{stitle} ({sid})"
            else: key = "ALL (-1)"
            val = f"{name} ({mid})"

            if key not in config['mentions']:
                config['mentions'][key] = []
                del config['mentions'][sid]
            config['mentions'][key].append(val)

    # Make admins readable
    users = []
    for uid in config["ADMINS"]:
        user = client.get_user(int(uid))

        if user: name = user.name
        else: name = "unknown"

        val = f"{name} ({uid})"
        users.append(val)
    config['ADMINS'] = users

    text = utils.breakMessage(json.dumps(config, indent=2), codeblock=True)

    for t in text:
        await message.channel.send(t)