├── .flake8
├── .gitattributes
├── .github
└── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
├── .gitignore
├── Bot
├── LICENSE
├── adapters
│ ├── README.md
│ ├── args.py
│ └── tag.py
├── core
│ ├── _
│ │ ├── README.md
│ │ ├── extract_.py
│ │ ├── image
│ │ │ ├── _.py
│ │ │ └── effects.py
│ │ └── tasks
│ │ │ └── reddit
│ │ │ └── memes.py
│ ├── __init__.py
│ ├── abc.py
│ ├── bot.py
│ ├── logging.py
│ ├── meta.py
│ └── version.py
├── main.py
├── src
│ ├── configure
│ │ └── management.py
│ ├── core.py
│ ├── dev
│ │ ├── README.md
│ │ ├── eval.py
│ │ └── owner.py
│ ├── funhouse
│ │ ├── fun.py
│ │ ├── games.py
│ │ ├── image.py
│ │ ├── misc.py
│ │ ├── music.py
│ │ └── reddit.py
│ ├── help.py
│ ├── moderation
│ │ └── moderation.py
│ ├── passive
│ │ ├── _join.py
│ │ ├── dashboard.py
│ │ ├── handler.py
│ │ ├── logging.py
│ │ └── starboard.py
│ ├── support
│ │ ├── join_events.py
│ │ ├── loadup.py
│ │ └── reaction-roles.py
│ ├── tools
│ │ ├── _cache.py
│ │ ├── checks.py
│ │ ├── emoji.py
│ │ ├── giveaways.py
│ │ ├── suggestions.py
│ │ ├── tags.py
│ │ ├── tickets.py
│ │ └── todo.py
│ └── unclassified
│ │ └── motivation.py
├── storage
│ ├── README.md
│ ├── images
│ │ └── README.md
│ ├── logs
│ │ └── README.md
│ ├── soundboard
│ │ └── README.md
│ ├── speeches
│ │ └── README.md
│ └── storage
│ │ └── README.md
└── utility
│ ├── __init__.py
│ ├── _resp.py
│ ├── cache.py
│ ├── checks.py
│ ├── color_finder.py
│ ├── colours.py
│ ├── embeds.py
│ ├── emojis.py
│ ├── env.py
│ ├── errors.py
│ ├── facts.py
│ ├── genders.py
│ ├── handler.py
│ ├── hangman.py
│ ├── jokes.py
│ ├── metrics.py
│ ├── min.py
│ ├── prefix.py
│ ├── quotes.py
│ └── words.py
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── CREDITS
├── Documentation
├── README.md
├── _static
│ ├── css
│ │ └── darkmode.css
│ ├── icons
│ │ └── dashboard.png
│ └── karen.png
├── _templates
│ └── home-navbar.html
├── commands
│ ├── cache
│ │ └── index.rst
│ ├── fun
│ │ ├── images
│ │ │ └── slot.png
│ │ └── slot.rst
│ ├── games
│ │ ├── coin.rst
│ │ ├── decipher.rst
│ │ ├── fight.rst
│ │ ├── hangman.rst
│ │ ├── images
│ │ │ ├── coin.png
│ │ │ ├── decipher-1.png
│ │ │ ├── decipher-2.png
│ │ │ ├── decipher.png
│ │ │ ├── fight-1.png
│ │ │ ├── fight-2.png
│ │ │ ├── fight-3.png
│ │ │ ├── fight-4.png
│ │ │ ├── hangman-1.png
│ │ │ ├── hangman-2.png
│ │ │ ├── minesweeper-1.png
│ │ │ ├── minesweeper-2.png
│ │ │ ├── roll.png
│ │ │ ├── rps-1.png
│ │ │ └── rps-2.png
│ │ ├── index.rst
│ │ ├── minesweeper.rst
│ │ ├── roll.rst
│ │ └── rps.rst
│ ├── image
│ │ ├── commands
│ │ │ ├── 8bit.rst
│ │ │ ├── achievement.rst
│ │ │ ├── autumn.rst
│ │ │ ├── beard.rst
│ │ │ ├── bird.rst
│ │ │ ├── blur.rst
│ │ │ ├── boot.rst
│ │ │ ├── breakingbad.rst
│ │ │ ├── cartoon.rst
│ │ │ ├── cmm.rst
│ │ │ ├── delete.rst
│ │ │ ├── distracted.rst
│ │ │ ├── drip.rst
│ │ │ ├── equalize.rst
│ │ │ ├── evilpatrick.rst
│ │ │ ├── expand.rst
│ │ │ ├── flip.rst
│ │ │ ├── gamma.rst
│ │ │ ├── glitch.rst
│ │ │ ├── grayscale.rst
│ │ │ ├── heaven.rst
│ │ │ ├── image.rst
│ │ │ ├── images
│ │ │ │ ├── 8bit.png
│ │ │ │ ├── achievement.png
│ │ │ │ ├── autumn.png
│ │ │ │ ├── beard.png
│ │ │ │ ├── bird.png
│ │ │ │ ├── blur.png
│ │ │ │ ├── boot.png
│ │ │ │ ├── breakingbad.png
│ │ │ │ ├── cartoon.png
│ │ │ │ ├── change-my-mind.png
│ │ │ │ ├── delete.png
│ │ │ │ ├── distracted.png
│ │ │ │ ├── drip.png
│ │ │ │ ├── equalize.png
│ │ │ │ ├── evilpatrick.png
│ │ │ │ ├── expand.png
│ │ │ │ ├── flip.png
│ │ │ │ ├── gamma.png
│ │ │ │ ├── glitch.png
│ │ │ │ ├── grayscale.png
│ │ │ │ ├── heaven.png
│ │ │ │ ├── image.png
│ │ │ │ ├── inferno.png
│ │ │ │ ├── invert.png
│ │ │ │ ├── meme.png
│ │ │ │ ├── mirror.png
│ │ │ │ ├── obese.png
│ │ │ │ ├── posterize.png
│ │ │ │ ├── rainbow.png
│ │ │ │ ├── reddit.png
│ │ │ │ ├── salt.png
│ │ │ │ ├── sketch-colour.png
│ │ │ │ ├── sketch.png
│ │ │ │ ├── slap.png
│ │ │ │ ├── solarize.png
│ │ │ │ ├── spank.png
│ │ │ │ ├── spin.png
│ │ │ │ ├── swirl.png
│ │ │ │ ├── table_flip.png
│ │ │ │ ├── transpose.png
│ │ │ │ ├── trash.png
│ │ │ │ ├── twilight.png
│ │ │ │ ├── warp.png
│ │ │ │ ├── wasted.png
│ │ │ │ └── watercolour.png
│ │ │ ├── inferno.rst
│ │ │ ├── invert.rst
│ │ │ ├── meme.rst
│ │ │ ├── mirror.rst
│ │ │ ├── obese.rst
│ │ │ ├── posterize.rst
│ │ │ ├── rainbow.rst
│ │ │ ├── reddit.rst
│ │ │ ├── salt.rst
│ │ │ ├── sketch.rst
│ │ │ ├── slap.rst
│ │ │ ├── solarize.rst
│ │ │ ├── spank.rst
│ │ │ ├── spin.rst
│ │ │ ├── swirl.rst
│ │ │ ├── table_flip.rst
│ │ │ ├── transpose.rst
│ │ │ ├── trash.rst
│ │ │ ├── twilight.rst
│ │ │ ├── warp.rst
│ │ │ ├── wasted.rst
│ │ │ └── watercolour.rst
│ │ ├── index.rst
│ │ └── tutorials
│ │ │ ├── accepted.rst
│ │ │ ├── images
│ │ │ ├── attachment.png
│ │ │ ├── from_cache.png
│ │ │ ├── from_cache_difslot.png
│ │ │ └── saving.png
│ │ │ ├── index.rst
│ │ │ ├── reply.rst
│ │ │ └── temp.rst
│ ├── index.rst
│ └── moderation
│ │ ├── archive.rst
│ │ ├── asciify.rst
│ │ ├── ban.rst
│ │ ├── clear.rst
│ │ ├── images
│ │ ├── Lock
│ │ │ ├── lock1.png
│ │ │ └── lock2.png
│ │ ├── Nuke
│ │ │ ├── nuke1.png
│ │ │ └── nuke2.png
│ │ ├── Purge
│ │ │ ├── classic.png
│ │ │ ├── member.png
│ │ │ ├── regex.png
│ │ │ └── role.png
│ │ ├── archive1.png
│ │ ├── archive2.png
│ │ ├── asciify.png
│ │ ├── ban.png
│ │ ├── kick.png
│ │ ├── lock.png
│ │ ├── mute1.png
│ │ ├── mute2.png
│ │ ├── nickname.png
│ │ ├── slowmode.png
│ │ ├── unban.png
│ │ ├── unmute1.png
│ │ └── unmute2.png
│ │ ├── index.rst
│ │ ├── kick.rst
│ │ ├── lock.rst
│ │ ├── mute.rst
│ │ ├── muterole
│ │ ├── images
│ │ │ ├── raw.png
│ │ │ ├── remove.png
│ │ │ └── set.png
│ │ ├── index.rst
│ │ ├── remove.rst
│ │ └── set.rst
│ │ ├── nickname.rst
│ │ ├── nuke.rst
│ │ ├── slowmode.rst
│ │ ├── unban.rst
│ │ ├── unmute.rst
│ │ └── warn
│ │ ├── clearwarns.rst
│ │ ├── delwarn.rst
│ │ ├── images
│ │ ├── clearwarn.png
│ │ ├── delwarn.png
│ │ ├── warn.png
│ │ └── warns.png
│ │ ├── index.rst
│ │ ├── warn.rst
│ │ └── warns.rst
├── conf.py
├── dashboard
│ └── index.rst
└── index.rst
├── LICENSE
├── README.md
├── Website
└── README
├── app.json
├── pipfile
├── pipfile.lock
└── requirements.txt
/.flake8:
--------------------------------------------------------------------------------
1 | [flake8]
2 | count = True
3 | statistics = True
4 | max-complexity = 32
5 | max-line-length = 240
6 | exclude =
7 | .git,
8 | __pycache__,
9 | build,
10 | dist,
11 | env,
12 | venv,
13 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | * text=auto
2 | *.txt text
3 | *.vcproj text eol=crlf
4 | *.sh text eol=lf
5 | *.jpg -text
6 | *.ps1 text working-tree-encoding=UTF-16LE eol=CRLF
7 |
8 | [filter "indent"]
9 | clean = indent
10 | smudge = cat
11 |
12 | [filter "p4"]
13 | clean = git-p4-filter --clean %f
14 | smudge = git-p4-filter --smudge %f
15 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots**
24 | If applicable, add screenshots to help explain your problem.
25 |
26 | **Additional context**
27 | Add any other context about the problem here.
28 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *__pycache__
2 | *.manifest
3 | *.spec
4 | *.log
5 | *.env
6 | *venv
7 | *.build
8 | *.template
9 |
10 | # I like fish. 🐟
11 |
--------------------------------------------------------------------------------
/Bot/adapters/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Mecha Karen
5 | Fun, Powerful and Unique
6 |
7 | Tagscript Adapters
8 |
9 | Usage and Purpose
10 |
11 | This folder will hold all adapters for the tagscript module, This makes our tags more flexible and powerful as we have more built-in models!
12 |
13 |
14 |
17 |
--------------------------------------------------------------------------------
/Bot/adapters/args.py:
--------------------------------------------------------------------------------
1 | from TagScriptEngine import Adapter, Verb, escape_content
2 | from ast import literal_eval
3 |
4 |
5 | class ArgumentAdapter(Adapter):
6 | r""" A class which will parse `*args` into your tag """
7 |
8 | def __init__(self, *args):
9 | self.args = args
10 | self._methods = {}
11 |
12 | self.object = self.__repr__()
13 | super().__init__()
14 |
15 | def __repr__(self):
16 | return "< TagArguments [{!r}] >".format(len(self.args))
17 |
18 | def get_value(self, ctx: Verb):
19 | should_escape = False
20 |
21 | if not ctx.parameter:
22 | return self.object
23 |
24 | parameter = ctx.parameter
25 |
26 | if ':' in parameter:
27 | slices = parameter.split(':')[:3]
28 | _ = []
29 | for _slice in slices:
30 | if not _slice.isdigit() or _slice:
31 | ## Means that the slice given was something useless
32 | return str()
33 | if _slice:
34 | _.append(int(_slice))
35 | else:
36 | _.append(None)
37 | _slice = slice(*_)
38 |
39 | return self.args[_slice]
40 |
41 | try:
42 | value = self.args[int(ctx.parameter)]
43 | except (IndexError, ValueError):
44 | if method := self._methods.get(ctx.parameter):
45 | value = method()
46 | else:
47 | return str()
48 |
49 | if isinstance(value, tuple):
50 | value, should_escape = value
51 |
52 | if not value:
53 | return_value = str()
54 | else:
55 | return_value = str(value)
56 |
57 | if should_escape:
58 | return escape_content(return_value)
59 | return return_value
60 |
--------------------------------------------------------------------------------
/Bot/adapters/tag.py:
--------------------------------------------------------------------------------
1 | from TagScriptEngine import Adapter, Verb, escape_content
2 |
3 |
4 | class TagAdapter(Adapter):
5 | r"""
6 | Adapter for a TAG object
7 |
8 | Attributes
9 | ----------
10 |
11 | content:str:The raw data of the tag
12 | name:str:The name of the tag
13 | guild:int:The ID of your server
14 | author:int:The user who created the tag (ID)
15 | uses:int:A number showing how many times this tag has been used
16 | nsfw:bool:A boolean showing if the tag should be used in a NSFW channel
17 | mod:bool:A boolean showing if users require `manage_messages` permissions
18 | created_at:datetime.datetime:A datetime object which represents the creation date of the tag
19 | updated_at:datetime.datetime:A datetime object representing when your tag was last updated
20 | """
21 |
22 | def __init__(self, tag):
23 | self._attributes = {
24 | 'content': tag.content,
25 | 'name': tag.name,
26 | 'guild': tag.guild,
27 | 'author': tag.author,
28 | 'uses': tag.uses,
29 | 'nsfw': tag.nsfw,
30 | 'mod': tag.mod
31 | }
32 | self._methods = dict()
33 |
34 | super().__init__()
35 |
36 | def repr(self):
37 | return f'[Tag Object !name={self._attributes["name"]}]'
38 |
39 | def get_value(self, ctx: Verb) -> str:
40 | should_escape = False
41 |
42 | if not ctx.parameter:
43 | return repr(self)
44 |
45 | try:
46 | value = self._attributes[ctx.parameter]
47 | except KeyError:
48 | if method := self._methods.get(ctx.parameter):
49 | value = method()
50 | else:
51 | return str()
52 |
53 | if isinstance(value, tuple):
54 | value, should_escape = value
55 |
56 | if not value:
57 | return_value = str()
58 | else:
59 | return_value = str(value)
60 |
61 | if should_escape:
62 | return escape_content(return_value)
63 | return return_value
64 |
--------------------------------------------------------------------------------
/Bot/core/_/README.md:
--------------------------------------------------------------------------------
1 | This section is too large and contains a lot of sensitive info so I will not be releasing files in this area YET!
2 | I will slowly push out releases for this section, this will start with more rougher areas.
3 |
4 | This may affect the `IMAGE` cog so there may be some issues. I wouldn't worry about it.\
5 | For a quick and easy fix comment out all the areas which use this folder.
6 |
--------------------------------------------------------------------------------
/Bot/core/_/image/_.py:
--------------------------------------------------------------------------------
1 | # !/usr/bin/python
2 |
3 | """
4 | Copyright ©️: 2020 Seniatical / _-*™#7519
5 | License: Apache 2.0
6 | A permissive license whose main conditions require preservation of copyright and license notices.
7 | Contributors provide an express grant of patent rights.
8 | Licensed works, modifications, and larger works may be distributed under different terms and without source code.
9 | FULL LICENSE CAN BE FOUND AT:
10 | https://www.apache.org/licenses/LICENSE-2.0.html
11 | Any violation to the license, will result in moderate action
12 | You are legally required to mention (original author, license, source and any changes made)
13 | """
14 |
15 | import typing
16 | from PIL import Image
17 | import discord
18 | import io
19 |
20 | def save_image(image: typing.Union[list, Image.Image], filename: str, **kwargs) -> discord.File:
21 | if type(image) == list:
22 | with io.BytesIO() as buffer:
23 | duration = kwargs.get('duration')
24 | loop = kwargs.get('loop')
25 |
26 | if duration:
27 | image[0].save(
28 | buffer, 'GIF',
29 | duration=duration,
30 | loop=0, save_all=True,
31 | append_images=image[1:]
32 | )
33 | else:
34 | image[0].save(
35 | buffer, 'GIF',
36 | loop=loop, save_all=True,
37 | append_images=image[1:]
38 | )
39 | buffer.seek(0)
40 |
41 | return discord.File(fp=buffer, filename=filename)
42 |
43 | with io.BytesIO() as buffer:
44 | image.save(buffer, kwargs.get('type') or 'PNG')
45 | buffer.seek(0)
46 |
47 | return discord.File(fp=buffer, filename=filename)
48 |
49 | def sort_size(*size) -> tuple:
50 | if size:
51 | if len(size) > 1:
52 | x, y = tuple(map(int, size[:2]))
53 | else:
54 | x, y = size[0], 300
55 | else:
56 | x, y = (300, 300)
57 | try:
58 | size = tuple(map(int, (x, y)))
59 | except ValueError:
60 | size = (300, 300)
61 |
62 | if any(i for i in size if i > 900):
63 | size = (300, 300)
64 |
65 | return size
66 |
--------------------------------------------------------------------------------
/Bot/core/_/tasks/reddit/memes.py:
--------------------------------------------------------------------------------
1 | # !/usr/bin/python
2 |
3 | """
4 | Copyright ©️: 2020 Seniatical / _-*™#7519
5 | License: Apache 2.0
6 | A permissive license whose main conditions require preservation of copyright and license notices.
7 | Contributors provide an express grant of patent rights.
8 | Licensed works, modifications, and larger works may be distributed under different terms and without source code.
9 | FULL LICENSE CAN BE FOUND AT:
10 | https://www.apache.org/licenses/LICENSE-2.0.html
11 | Any violation to the license, will result in moderate action
12 | You are legally required to mention (original author, license, source and any changes made)
13 | """
14 |
15 | from utility import emojis as emoji
16 | from utility import abbrev_denary as convert_size
17 | import random
18 | import discord
19 | global stack
20 | from requests.utils import requote_uri
21 | import asyncio
22 |
23 | stack = []
24 |
25 | def add_global(new_stack: list) -> None:
26 | global stack
27 | stack = new_stack
28 |
29 | async def task(bot, reddit):
30 | while True:
31 | bot.cache.cache['memes'].clear()
32 | sub = await reddit.subreddit('memes')
33 | async for _submission in sub.top(limit=500):
34 | if not _submission:
35 | continue
36 |
37 | name = _submission.title
38 | url = _submission.url
39 | comments = _submission.num_comments
40 | up = _submission.score
41 | sub = await _submission.subreddit()
42 | name_ = await _submission.author()
43 |
44 | embed = discord.Embed(
45 | title=name,
46 | color=random.randint(0x000000, 0xFFFFFF),
47 | url=await bot.loop.run_in_executor(
48 | None, requote_uri,
49 | f'https://www.reddit.com/r/dankmemes/comments/{_submission.id}/{_submission.title}/'
50 | )
51 | )
52 | try:
53 | embed.set_author(name='Posted by {} from r/{}'.format(name_, sub), icon_url=name_.icon_img,
54 | url=f'https://www.reddit.com/user/{name_}/')
55 | except Exception:
56 | embed.set_author(name='Posted by {} from r/{}'.format(name_, sub),
57 | url=f'https://www.reddit.com/user/{name_}/')
58 | embed.set_image(url=url)
59 | embed.set_footer(
60 | text='{} {} | {} {}'.format(emoji.UNICODE['up'], convert_size(up), emoji.UNICODE['text'],
61 | convert_size(comments)))
62 | bot.cache.cache['memes'].append(embed)
63 | await asyncio.sleep(3600)
64 |
--------------------------------------------------------------------------------
/Bot/core/__init__.py:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/Bot/core/abc.py:
--------------------------------------------------------------------------------
1 | # !/usr/bin/python
2 |
3 | """
4 | Copyright ©️: 2020 Seniatical / _-*™#7519
5 | License: Apache 2.0
6 | A permissive license whose main conditions require preservation of copyright and license notices.
7 | Contributors provide an express grant of patent rights.
8 | Licensed works, modifications, and larger works may be distributed under different terms and without source code.
9 | FULL LICENSE CAN BE FOUND AT:
10 | https://www.apache.org/licenses/LICENSE-2.0.html
11 | Any violation to the license, will result in moderate action
12 | You are legally required to mention (original author, license, source and any changes made)
13 | """
14 |
15 | from .bot import MechaKaren
16 | from discord.ext.commands import Cog
17 | from abc import ABC
18 | from pydantic import BaseModel
19 |
20 |
21 | class Bot(BaseModel):
22 | default_prefix: str = ""
23 | intents: tuple = ('guilds', 'members', 'bans', 'emojis', 'voice_states',
24 | 'presences', 'messages', 'guild_messages', 'reactions',
25 | 'integrations'
26 | )
27 | # FALSE - Disabled
28 | logging: bool = True
29 | guild_logging: bool = True
30 | error_logging: bool = True
31 | running: bool = None
32 |
33 |
34 | class KarenMixin(ABC):
35 | r"""
36 | Base Class for cogs - Holds some key functions and other stuff which wont need constant re-defining
37 | In in each cog
38 | """
39 | Bot.running = True
40 |
41 | defaults: Bot
42 | bot: MechaKaren
43 |
44 | def __init__(self, *args, **kwargs):
45 | self.args = args
46 | self.kwargs = kwargs
47 |
48 | self.attrs = []
49 | self.methods = []
50 |
51 | super().__init__()
52 | self._sort()
53 |
54 | def cog_unload(self):
55 | super().cog_unload()
56 |
57 | def _sort(self):
58 | values = dir(super())
59 | attrs, methods = ([], [])
60 | for value in values:
61 | if not callable(getattr(super(), value)):
62 | ## If it the attr is callable we dont class it as an attribute
63 | attrs.append(value)
64 | else:
65 | methods.append(value)
66 |
67 | self.attrs = attrs
68 | self.methods = methods
69 |
70 | return True
71 |
72 |
73 | class KarenMetaClass(type(Cog), type(ABC)):
74 | pass
75 |
--------------------------------------------------------------------------------
/Bot/core/version.py:
--------------------------------------------------------------------------------
1 | __version__ = "1.9.2a"
--------------------------------------------------------------------------------
/Bot/main.py:
--------------------------------------------------------------------------------
1 | # !/usr/bin/python
2 |
3 | """
4 | Copyright ©️: 2020 Seniatical / _-*™#7519
5 | License: Apache 2.0
6 | A permissive license whose main conditions require preservation of copyright and license notices.
7 | Contributors provide an express grant of patent rights.
8 | Licensed works, modifications, and larger works may be distributed under different terms and without source code.
9 | FULL LICENSE CAN BE FOUND AT:
10 | https://www.apache.org/licenses/LICENSE-2.0.html
11 | Any violation to the license, will result in moderate action
12 | You are legally required to mention (original author, license, source and any changes made)
13 | """
14 |
15 | from core import bot, meta
16 | import os
17 | import tracemalloc
18 | import argparse
19 |
20 | parse = argparse.ArgumentParser(description='Optional CLI for running Mecha Karen')
21 | parse.add_argument('--meta', type=None, help='Run the meta version of Mecha Karen')
22 | parse.add_argument('--main', type=None, help='[Default] Run the main bot!')
23 |
24 | if __name__ == '__main__':
25 | args = vars(parse.parse_args())
26 |
27 | tracemalloc.start()
28 |
29 | os.chdir(os.path.dirname(os.path.realpath(__file__)))
30 |
31 | if 'meta' in args:
32 | karen = meta.MechaKaren()
33 | elif 'main' in args:
34 | ## Well theres only 1 command other then help
35 | karen = bot.MechaKaren()
36 | else:
37 | exit()
38 | ipc = karen.ipc
39 |
40 | print('Websocket running on: ', (ipc.host, ipc.port, ipc.multicast_port))
41 |
42 | karen.run()
43 |
44 | else:
45 | raise RuntimeError('Make sure your running `main.py`!')
46 |
47 | tracemalloc.stop()
48 |
--------------------------------------------------------------------------------
/Bot/src/core.py:
--------------------------------------------------------------------------------
1 | # !/usr/bin/python
2 |
3 | """
4 | Copyright ©️: 2020 Seniatical / _-*™#7519
5 | License: Apache 2.0
6 | A permissive license whose main conditions require preservation of copyright and license notices.
7 | Contributors provide an express grant of patent rights.
8 | Licensed works, modifications, and larger works may be distributed under different terms and without source code.
9 | FULL LICENSE CAN BE FOUND AT:
10 | https://www.apache.org/licenses/LICENSE-2.0.html
11 | Any violation to the license, will result in moderate action
12 | You are legally required to mention (original author, license, source and any changes made)
13 | """
14 |
15 | import os
16 | import traceback
17 |
18 | path = './src/'
19 | dirs = []
20 | cogs = []
21 |
22 | """ PATH FINDING """
23 | ## Searches through dirs
24 |
25 | for file in os.listdir(path):
26 | path_ = path + file
27 | if os.path.isdir(path_) and file != '__pycache__':
28 | dirs.append(path_)
29 | ## NOT ADDING COGS OUT OF FOLDERS!
30 |
31 | for _dir in dirs:
32 | for file in os.listdir(_dir):
33 | path_ = _dir + '/' + file
34 | if not os.path.isdir(path_) and file != '__pycache__':
35 | cogs.append(path_)
36 |
37 | def load_cogs(bot):
38 | for cog in cogs:
39 | try:
40 | ## COG IS THE RELATIVE PATH
41 | ## NEED TO CHANGE IT TO AN IMPORT
42 | ## CONVERTS ./path/to/cog.py - path.to.cog
43 |
44 | bot.load_extension(cog[2:].replace('/', '.')[:-3])
45 | except Exception as error:
46 | traceback.print_exception(type(error), error, error.__traceback__)
47 | bot.load_extension('src.help')
48 |
49 | return True
50 |
--------------------------------------------------------------------------------
/Bot/src/dev/README.md:
--------------------------------------------------------------------------------
1 | This Section holds all the `OWNER-ONLY` commands
2 |
--------------------------------------------------------------------------------
/Bot/src/support/join_events.py:
--------------------------------------------------------------------------------
1 | # !/usr/bin/python
2 |
3 | """
4 | Copyright ©️: 2020 Seniatical / _-*™#7519
5 | License: Apache 2.0
6 | A permissive license whose main conditions require preservation of copyright and license notices.
7 | Contributors provide an express grant of patent rights.
8 | Licensed works, modifications, and larger works may be distributed under different terms and without source code.
9 | FULL LICENSE CAN BE FOUND AT:
10 | https://www.apache.org/licenses/LICENSE-2.0.html
11 | Any violation to the license, will result in moderate action
12 | You are legally required to mention (original author, license, source and any changes made)
13 | """
14 |
15 | import discord
16 | from discord.ext import commands
17 | import os
18 | import json
19 | import io
20 | from PIL import Image, ImageDraw
21 | import asyncio
22 | import datetime
23 | import aiohttp
24 | import time
25 |
26 |
27 | async def ending(count: int = 0):
28 | if count == 0:
29 | return 'The first member!'
30 | x = str(count)
31 | if '1' in x[-1]:
32 | ending = 'ˢᵗ'
33 | elif '2' in x[-1]:
34 | ending = 'ⁿᵈ'
35 | elif '3' in x[-1]:
36 | ending = 'ʳᵈ'
37 | else:
38 | ending = 'ᵗʰ'
39 | return '%s' % ending
40 |
41 | def simplify(days):
42 | year = days // 365
43 | days %= 365
44 | months = days // 30
45 | days %= 30
46 | return '%s Year(s), %s Month(s) and %s day(s) ago.' % (year, months, days)
47 |
48 | class Events(commands.Cog):
49 | def __init__(self, bot):
50 | self.bot = bot
51 | #self.channel =
52 |
53 | @commands.Cog.listener()
54 | async def on_ready(self):
55 | async def myloop():
56 | while True:
57 | primary = self.bot.get_channel(789874799379742811)
58 | await primary.edit(name='MK Members | {}'.format(len(self.bot.users)))
59 | secondary = self.bot.get_channel(789952098938126336)
60 | await secondary.edit(name='MK Servers | {}'.format(len(self.bot.guilds)))
61 | secondary = self.bot.get_channel(789952098938126336)
62 | await asyncio.sleep(30)
63 | await secondary.edit(name='Members | {}'.format(len(self.bot.get_guild(740523643980873789).members)))
64 |
65 | self.bot.loop.create_task(myloop())
66 |
67 | @commands.Cog.listener()
68 | async def on_member_join(self, member):
69 | if member.guild.id == 839184636948774963:
70 | await member.add_roles(member.guild.get_role(839202886796968017))
71 |
72 | if member.guild.id != 740523643980873789:
73 | return
74 | channel = self.bot.get_channel(776198796357926922)
75 |
76 | await channel.send(embed=discord.Embed(
77 | title='Welcome!',
78 | description='Welcome {} to {}. You are our {}{} member!'.format(member.mention, member.guild.name, member.guild.member_count, await ending(len(member.guild.members))),
79 | colour=discord.Colour.red()
80 | ), content='{}, To access the server, React with ✅ in <#741292472784912425> to <@!740514706858442792> Message!'.format(member.mention))
81 |
82 | @commands.Cog.listener()
83 | async def on_member_remove(self, member):
84 | channel = self.bot.get_channel(776198796357926922)
85 | if channel not in member.guild.channels:
86 | return
87 | await channel.send(f'**{member}** ({member.id}) has left us. Hope you come back soon!')
88 |
89 | def setup(bot):
90 | bot.add_cog(Events(bot))
91 |
--------------------------------------------------------------------------------
/Bot/src/support/loadup.py:
--------------------------------------------------------------------------------
1 | # !/usr/bin/python
2 |
3 | """
4 | Copyright ©️: 2020 Seniatical / _-*™#7519
5 | License: Apache 2.0
6 | A permissive license whose main conditions require preservation of copyright and license notices.
7 | Contributors provide an express grant of patent rights.
8 | Licensed works, modifications, and larger works may be distributed under different terms and without source code.
9 | FULL LICENSE CAN BE FOUND AT:
10 | https://www.apache.org/licenses/LICENSE-2.0.html
11 | Any violation to the license, will result in moderate action
12 | You are legally required to mention (original author, license, source and any changes made)
13 | """
14 |
15 | import discord
16 | from asyncio import sleep
17 | from os import system, name
18 | from discord.ext import commands
19 | from colorama import Fore, init
20 | import platform
21 | import sys
22 | from core._.handle_clear
23 |
24 | os = platform.system()
25 |
26 | def clear():
27 | if name == 'nt':
28 | _ = system('cls')
29 | else:
30 | _ = system('clear')
31 | ## Cleans up stdout
32 | handle_clear() ## This function cleans up the hidden area
33 |
34 | class Boot(commands.Cog):
35 | def __init__(self, bot):
36 | self.bot = bot
37 | self.cache = bot.cache
38 | self.text = """\
39 | ███▄ ▄███▓▓█████ ▄████▄ ██░ ██ ▄▄▄ ██ ▄█▀▄▄▄ ██▀███ ▓█████ ███▄ █
40 | ▓██▒▀█▀ ██▒▓█ ▀ ▒██▀ ▀█ ▓██░ ██▒▒████▄ ██▄█▒▒████▄ ▓██ ▒ ██▒▓█ ▀ ██ ▀█ █
41 | ▓██ ▓██░▒███ ▒▓█ ▄ ▒██▀▀██░▒██ ▀█▄ ▓███▄░▒██ ▀█▄ ▓██ ░▄█ ▒▒███ ▓██ ▀█ ██▒
42 | ▒██ ▒██ ▒▓█ ▄ ▒▓▓▄ ▄██▒░▓█ ░██ ░██▄▄▄▄██ ▓██ █▄░██▄▄▄▄██ ▒██▀▀█▄ ▒▓█ ▄ ▓██▒ ▐▌██▒
43 | ▒██▒ ░██▒░▒████▒▒ ▓███▀ ░░▓█▒░██▓ ▓█ ▓██▒ ▒██▒ █▄▓█ ▓██▒░██▓ ▒██▒░▒████▒▒██░ ▓██░
44 | ░ ▒░ ░ ░░░ ▒░ ░░ ░▒ ▒ ░ ▒ ░░▒░▒ ▒▒ ▓▒█░ ▒ ▒▒ ▓▒▒▒ ▓▒█░░ ▒▓ ░▒▓░░░ ▒░ ░░ ▒░ ▒ ▒
45 | ░ ░ ░ ░ ░ ░ ░ ▒ ▒ ░▒░ ░ ▒ ▒▒ ░ ░ ░▒ ▒░ ▒ ▒▒ ░ ░▒ ░ ▒░ ░ ░ ░░ ░░ ░ ▒░
46 | ░ ░ ░ ░ ░ ░░ ░ ░ ▒ ░ ░░ ░ ░ ▒ ░░ ░ ░ ░ ░ ░
47 | ░ ░ ░░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░
48 | ░
49 | """
50 |
51 | @commands.Cog.listener()
52 | async def on_ready(self):
53 | async def status():
54 | for user in self.bot.users:
55 | res = await self.cache.base_template(user.id)
56 | if res == False:
57 | print('Failed to add %s to the cache.' % str(user))
58 |
59 | while True:
60 | shard_count = self.bot.shard_count
61 | shards = self.bot.shards
62 | await self.bot.wait_until_ready()
63 | for i in range(shard_count):
64 | shard = self.bot.get_shard(shards[i])
65 | await self.bot.change_presence(status=discord.Status.do_not_disturb,
66 | activity=discord.Activity(type=discord.ActivityType.watching,
67 | name='-Help | {}/{} https://mechakaren.xyz/'.format(1, shard_count)))
68 | await sleep(20)
69 | print(Fore.BLUE + 'All Cogs loaded!\n' + Fore.RESET)
70 | print(Fore.GREEN + f'{sys.version}\n\n' + Fore.RESET)
71 | print(Fore.LIGHTRED_EX + self.text + Fore.RESET)
72 | self.bot.loop.create_task(status())
73 |
74 | @commands.command()
75 | @commands.is_owner()
76 | async def reset(self, ctx):
77 | clear()
78 | print(Fore.BLUE + 'All Cogs loaded!\n' + Fore.RESET)
79 | print(Fore.GREEN + f'{sys.version}\n\n' + Fore.RESET)
80 | print(Fore.LIGHTRED_EX + self.text + Fore.RESET)
81 | return await ctx.send('Cleared the following:```\nInternal Cache\nLogging Cache\nSTDOUT && STDIN && STDERR\nGateway Storage\nAll Containers```')
82 |
83 | def setup(bot):
84 | bot.add_cog(Boot(bot))
85 |
--------------------------------------------------------------------------------
/Bot/src/tools/giveaways.py:
--------------------------------------------------------------------------------
1 | # !/usr/bin/python
2 |
3 | """
4 | Copyright ©️: 2020 Seniatical / _-*™#7519
5 | License: Apache 2.0
6 | A permissive license whose main conditions require preservation of copyright and license notices.
7 | Contributors provide an express grant of patent rights.
8 | Licensed works, modifications, and larger works may be distributed under different terms and without source code.
9 | FULL LICENSE CAN BE FOUND AT:
10 | https://www.apache.org/licenses/LICENSE-2.0.html
11 | Any violation to the license, will result in moderate action
12 | You are legally required to mention (original author, license, source and any changes made)
13 | """
14 |
15 | import discord
16 | from discord.ext import commands
17 | import datetime
18 | import datetime
19 | import os
20 | from binascii import hexlify
21 |
22 | class Giveaway(commands.Cog):
23 | def __init__(self, bot):
24 | self.bot = bot
25 | self.client = bot.client
26 |
27 | self.table = self.client['Giveaways']
28 | self.codes = self.table['codes']
29 |
30 | self.giveaways = {}
31 | self.questions = (
32 | 'Which channel would you like to set this giveaway up in?',
33 | 'How many winners would you like for this giveaway',
34 | 'How long will this giveaway last for? Please use the format of `