push functional python code
This commit is contained in:
commit
15b4b787b6
3
REAMDE.md
Normal file
3
REAMDE.md
Normal file
@ -0,0 +1,3 @@
|
||||
# Disclaimer.
|
||||
|
||||
I have no relation with `fxtwitter`, nor `vxtwitter`, or anything else being used there.
|
46
bot/Classes.py
Normal file
46
bot/Classes.py
Normal file
@ -0,0 +1,46 @@
|
||||
from dataclasses import dataclass, asdict
|
||||
from datetime import datetime, timedelta
|
||||
from os import getenv
|
||||
|
||||
|
||||
@dataclass
|
||||
class _CONFIG:
|
||||
"""
|
||||
Skell for other Services Configurations
|
||||
"""
|
||||
|
||||
def __hash__(self) -> dict:
|
||||
return asdict(self)
|
||||
|
||||
def load_envs(self) -> object:
|
||||
"""
|
||||
Loads variables from environment.
|
||||
:return:
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def __post_init__(self):
|
||||
self = self.load_envs()
|
||||
|
||||
|
||||
@dataclass
|
||||
class DiscordConf(_CONFIG):
|
||||
"""
|
||||
Stores the configuration for the Discord Bot
|
||||
|
||||
token: str
|
||||
mc_url: str : Url to post on the discord embeds / messages
|
||||
prefix: str : Prefix for the commands
|
||||
description: str : Bot description to have
|
||||
"""
|
||||
token: str = None
|
||||
# mc_url: str = None
|
||||
prefix: str = "!"
|
||||
description: str = "Don't u dare make me fix ur twitter links."
|
||||
|
||||
def load_envs(self):
|
||||
self.token = getenv("DISCORD_TOKEN") or self.token
|
||||
# self.mc_url = getenv("DISCORD_MC_URL") or self.mc_url
|
||||
self.prefix = getenv("DISCORD_PREFIX") or self.prefix
|
||||
self.description = getenv("DISCORD_DESCRIPTION") or self.description
|
||||
return self
|
77
bot/DiscordBot.py
Normal file
77
bot/DiscordBot.py
Normal file
@ -0,0 +1,77 @@
|
||||
import discord.ext.commands
|
||||
from discord.ext import commands
|
||||
from discord import Embed, Intents
|
||||
from Classes import DiscordConf
|
||||
from TwitterFixer import TwLink
|
||||
from validators import url as is_url
|
||||
|
||||
|
||||
# Set some validator of vx, fx pages to flag as working or not working.
|
||||
|
||||
class Bot(commands.Bot):
|
||||
conf: DiscordConf = None
|
||||
|
||||
def __init__(self, conf: DiscordConf = None, *args, **kwargs):
|
||||
intents = Intents(messages=True, guilds=True, message_content=True)
|
||||
super(commands.Bot, self).__init__(command_prefix=conf.prefix, description=conf.description, intents=intents,
|
||||
self_bot=False)
|
||||
self.config = conf
|
||||
self.add_commands()
|
||||
|
||||
def run(self, *args, **kwargs):
|
||||
super(commands.Bot, self).run(self.config.token, *args, **kwargs)
|
||||
|
||||
async def on_ready(self):
|
||||
print('------')
|
||||
print('Logged as')
|
||||
print(self.user.name)
|
||||
print(self.user.id)
|
||||
print(
|
||||
f'invite me with: {self.invite_url}')
|
||||
print('------')
|
||||
|
||||
@property
|
||||
def invite_url(self) -> str:
|
||||
return f"https://discord.com/oauth2/authorize?client_id={self.user.id}&permissions=84032&scope=bot"
|
||||
|
||||
def scan_message(self, ctx: discord.Message):
|
||||
"""
|
||||
Scans the message for twitter links that aren't fxtweeted.
|
||||
"""
|
||||
|
||||
def is_command(self, ctx: discord.Message) -> bool:
|
||||
__is_command: bool = ctx.content.startswith(self.command_prefix)
|
||||
print(f'>> `{ctx.author.name}` message is a command? {__is_command}')
|
||||
return __is_command
|
||||
|
||||
async def on_message(self, ctx: discord.Message, /):
|
||||
|
||||
__is_bot = ctx.author.bot
|
||||
|
||||
print(f'>> `{ctx.author.name}` posted a new message, is it a bot? {__is_bot}')
|
||||
if __is_bot:
|
||||
print(f"*** ``{ctx.author.name}`` is a bot, skipping ...")
|
||||
elif self.is_command(ctx):
|
||||
await self.process_commands(ctx)
|
||||
else:
|
||||
|
||||
"""
|
||||
Splits message by spaces.
|
||||
|
||||
Iterates and validates each one of the words split
|
||||
|
||||
If the "word" is flagged as valid URL, it will proceed with the URL fixing process, which in case of being a valid URL, will post a message.
|
||||
"""
|
||||
text_split = ctx.content.split(" ")
|
||||
for word in text_split:
|
||||
if is_url(word):
|
||||
url = word
|
||||
tw = TwLink(url=url)
|
||||
if tw.__bool__():
|
||||
print(f"fixed URL from `{url}` to `{tw}`")
|
||||
await ctx.reply(mention_author=False, content=f"Fixed Twitter Link! {tw}")
|
||||
|
||||
def add_commands(self):
|
||||
@self.command()
|
||||
async def invite(ctx):
|
||||
await ctx.reply(f"You can invite me to your server with: {self.invite_url}")
|
85
bot/TwitterFixer.py
Normal file
85
bot/TwitterFixer.py
Normal file
@ -0,0 +1,85 @@
|
||||
from urllib.parse import urlparse
|
||||
|
||||
|
||||
class TwLink:
|
||||
"""
|
||||
Disclaimer.
|
||||
|
||||
I have no relation with fxtwitter, nor vxtwitter, or anything else being used there.
|
||||
"""
|
||||
_user: str
|
||||
_post_id: str
|
||||
_url: str
|
||||
_prefix: [str] # List of valid fxshit
|
||||
_valid_url = False
|
||||
|
||||
def __init__(self, url: str):
|
||||
self._url = url
|
||||
self.__review_url()
|
||||
self._prefix = [
|
||||
"https://fxtwitter.com",
|
||||
"https://vxtwitter.com"
|
||||
]
|
||||
|
||||
pass
|
||||
|
||||
def __review_url(self) -> None:
|
||||
"""
|
||||
Checks if twitter URL is a valid post.
|
||||
|
||||
It requires:
|
||||
- Twitter domain.
|
||||
- /status/
|
||||
- Username
|
||||
- Post ID
|
||||
|
||||
:return: STR, returns "fixed" URL if given URL is valid.
|
||||
Returns nothing if isn't valid.
|
||||
"""
|
||||
|
||||
valid_twitter_hosts = ["twitter.com"]
|
||||
parsed_url = urlparse(url=self._url)
|
||||
host = parsed_url.netloc
|
||||
path: str | [str] = parsed_url.path
|
||||
if path.startswith("/"):
|
||||
# Remove initial /
|
||||
path = path[1:]
|
||||
path = path.split("/")
|
||||
|
||||
if host not in valid_twitter_hosts \
|
||||
or len(path) > 3 \
|
||||
or path[1].lower() != "status":
|
||||
print(f"URL '{self._url}' is NOT valid!")
|
||||
else:
|
||||
print(f"URL '{self._url}' is valid")
|
||||
self._valid_url = True
|
||||
self._user = path[0]
|
||||
self._post_id = path[2]
|
||||
|
||||
@property
|
||||
def __return_url(self) -> str:
|
||||
"""
|
||||
Returns the URL if the class been flagged as valid URL.
|
||||
|
||||
Retrusn an empty string if it's not flagged as valid URL.
|
||||
:return:
|
||||
"""
|
||||
|
||||
if self._valid_url:
|
||||
return f"{self._prefix[0]}/{self._user}/status/{self._post_id}"
|
||||
else:
|
||||
return ""
|
||||
|
||||
def __str__(self) -> str:
|
||||
return self.__return_url
|
||||
|
||||
def __bool__(self) -> bool:
|
||||
if self.__return_url is not None:
|
||||
return True
|
||||
|
||||
def __call__(self, *args, **kwargs) -> str:
|
||||
return self.__str__()
|
||||
|
||||
def __int__(self):
|
||||
return len(self.__str__())
|
||||
|
BIN
bot/__pycache__/Classes.cpython-311.pyc
Normal file
BIN
bot/__pycache__/Classes.cpython-311.pyc
Normal file
Binary file not shown.
BIN
bot/__pycache__/DiscordBot.cpython-311.pyc
Normal file
BIN
bot/__pycache__/DiscordBot.cpython-311.pyc
Normal file
Binary file not shown.
BIN
bot/__pycache__/TwitterFixer.cpython-311.pyc
Normal file
BIN
bot/__pycache__/TwitterFixer.cpython-311.pyc
Normal file
Binary file not shown.
9
bot/main.py
Normal file
9
bot/main.py
Normal file
@ -0,0 +1,9 @@
|
||||
#!/bin/python3
|
||||
|
||||
from DiscordBot import Bot, DiscordConf
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
disconf = DiscordConf()
|
||||
client = Bot(conf=disconf)
|
||||
client.run()
|
Loading…
x
Reference in New Issue
Block a user