Merge branch 'beanie' into 'main'

Beanie

See merge request stark-industries/jarvis/jarvis-core!1
This commit is contained in:
Zeva Rose 2023-09-14 02:38:20 +00:00
commit d598ec8b49
17 changed files with 1094 additions and 1020 deletions

22
.flake8
View file

@ -3,18 +3,16 @@ exclude =
tests/*
extend-ignore =
Q0, E501, C812, E203, W503, # These default to arguing with Black. We might configure some of them eventually
ANN1, # Ignore self and cls annotations
ANN204, ANN206, # return annotations for special methods and class methods
D105, D107, # Missing Docstrings in magic method and __init__
S311, # Standard pseudo-random generators are not suitable for security/cryptographic purposes.
D401, # First line should be in imperative mood; try rephrasing
D400, # First line should end with a period
D101, # Missing docstring in public class
D106, # Missing docstring in public nested class
# Plugins we don't currently include: flake8-return
R503, # missing explicit return at the end of function ableto return non-None value.
Q0, E501, C812, E203, W503,
ANN1, ANN003,
ANN204, ANN206,
D105, D107,
S311,
D401,
D400,
D101, D102,
D106,
R503,
max-line-length=100

View file

@ -1,6 +1,6 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.1.0
rev: v4.4.0
hooks:
- id: check-toml
- id: check-yaml
@ -9,21 +9,19 @@ repos:
- id: requirements-txt-fixer
- id: end-of-file-fixer
- id: debug-statements
language_version: python3.10
- id: trailing-whitespace
args: [--markdown-linebreak-ext=md]
- repo: https://github.com/pre-commit/pygrep-hooks
rev: v1.9.0
rev: v1.10.0
hooks:
- id: python-check-blanket-noqa
- repo: https://github.com/psf/black
rev: 22.3.0
rev: 23.7.0
hooks:
- id: black
args: [--line-length=100, --target-version=py310]
language_version: python3.10
args: [--line-length=100]
- repo: https://github.com/pre-commit/mirrors-isort
rev: v5.10.1
@ -32,7 +30,7 @@ repos:
args: ["--profile", "black"]
- repo: https://github.com/pycqa/flake8
rev: 4.0.1
rev: 6.1.0
hooks:
- id: flake8
additional_dependencies:
@ -46,4 +44,3 @@ repos:
- flake8-deprecated
- flake8-print
- flake8-return
language_version: python3.10

View file

@ -1,13 +1,12 @@
"""Load global config."""
import os
from lib2to3.pgen2 import token
from pathlib import Path
from typing import Union
from dotenv import load_dotenv
from yaml import load
from jarvis_core.util import Singleton, find_all
from jarvis_core.util import Singleton
try:
from yaml import CLoader as Loader
@ -65,7 +64,6 @@ class Config(Singleton):
def load(cls) -> "Config":
if DEFAULT_ENV_PATH.exists():
return cls.from_env()
else:
return cls.from_yaml()
@classmethod

View file

@ -1,101 +1,30 @@
"""JARVIS database models and utilities."""
from bson import ObjectId
from motor.motor_asyncio import AsyncIOMotorClient
from pytz import utc
from umongo.frameworks import MotorAsyncIOInstance
from beanie import init_beanie
from jarvis_core.util import find
CLIENT = None
JARVISDB = None
CTC2DB = None
JARVIS_INST = MotorAsyncIOInstance()
CTC2_INST = MotorAsyncIOInstance()
from jarvis_core.db.models import all_models
def connect(
async def connect(
host: list[str] | str,
username: str,
password: str,
port: int = 27017,
testing: bool = False,
host: str = None,
hosts: list[str] = None,
replicaset: str = None,
extra_models: list = [],
) -> None:
"""
Connect to MongoDB.
Args:
host: Hostname/IP
host: Hostname/IP, or list of hosts for replica sets
username: Username
password: Password
port: Port
testing: Whether or not to use jarvis_dev
extra_models: Extra beanie models to register
"""
global CLIENT, JARVISDB, CTC2DB, JARVIS_INST, CTC2_INST
if not replicaset:
CLIENT = AsyncIOMotorClient(
host=host, username=username, password=password, port=port, tz_aware=True, tzinfo=utc
)
else:
CLIENT = AsyncIOMotorClient(
hosts, username=username, password=password, tz_aware=True, tzinfo=utc, replicaset=replicaset
)
JARVISDB = CLIENT.narvis if testing else CLIENT.jarvis
CTC2DB = CLIENT.ctc2
JARVIS_INST.set_db(JARVISDB)
CTC2_INST.set_db(CTC2DB)
QUERY_OPS = ["ne", "lt", "lte", "gt", "gte", "not", "in", "nin", "mod", "all", "size"]
STRING_OPS = [
"exact",
"iexact",
"contains",
"icontains",
"startswith",
"istartswith",
"endswith",
"iendswith",
"wholeword",
"iwholeword",
"regex",
"iregex" "match",
]
GEO_OPS = [
"get_within",
"geo_within_box",
"geo_within_polygon",
"geo_within_center",
"geo_within_sphere",
"geo_intersects",
"near",
"within_distance",
"within_spherical_distance",
"near_sphere",
"within_box",
"within_polygon",
"max_distance",
"min_distance",
]
ALL_OPS = QUERY_OPS + STRING_OPS + GEO_OPS
def q(**kwargs: dict) -> dict:
"""uMongo query wrapper.""" # noqa: D403
query = {}
for key, value in kwargs.items():
if key == "_id":
value = ObjectId(value)
elif "__" in key:
args = key.split("__")
if not any(x in ALL_OPS for x in args):
key = ".".join(args)
else:
idx = args.index(find(lambda x: x in ALL_OPS, args))
key = ".".join(args[:idx])
value = {f"${args[idx]}": value}
query[key] = value
return query
client = AsyncIOMotorClient(host, username=username, password=password, port=port, tz_aware=True, tzinfo=utc)
db = client.jarvis_dev if testing else client.jarvis
await init_beanie(database=db, document_models=all_models + extra_models)

View file

@ -1,257 +1,277 @@
"""JARVIS database models."""
import re
from datetime import datetime
from typing import Any, List
from typing import Optional
import marshmallow as ma
from umongo import Document, EmbeddedDocument, fields
from beanie import Document, Link
from pydantic import BaseModel, Field
from jarvis_core.db import CTC2_INST, JARVIS_INST
from jarvis_core.db.fields import RawField
from jarvis_core.db.models.actions import *
from jarvis_core.db.models.backups import *
from jarvis_core.db.models.mastodon import *
from jarvis_core.db.models.modlog import *
from jarvis_core.db.models.reddit import *
from jarvis_core.db.models.twitter import *
from jarvis_core.db.utils import get_now
from jarvis_core.db.models.actions import Ban, Kick, Mute, Unban, Warning
from jarvis_core.db.models.modlog import Action, Modlog, Note
from jarvis_core.db.models.reddit import Subreddit, SubredditFollow
from jarvis_core.db.models.twitter import TwitterAccount, TwitterFollow
from jarvis_core.db.utils import NowField
__all__ = [
"Action",
"Autopurge",
"Autoreact",
"Ban",
"Config",
"Filter",
"Guess",
"Kick",
"Lock",
"Lockdown",
"Modlog",
"Mute",
"Note",
"Pin",
"Pinboard",
"Phishlist",
"Purge",
"Reminder",
"Rolegiver",
"Bypass",
"Roleping",
"Setting",
"Subreddit",
"SubredditFollow",
"Tag",
"Temprole",
"TwitterAccount",
"TwitterFollow",
"Unban",
"UserSetting",
"Warning",
"all_models",
]
@JARVIS_INST.register
class Autopurge(Document):
guild: int = fields.IntegerField(required=True)
channel: int = fields.IntegerField(required=True)
delay: int = fields.IntegerField(default=30)
admin: int = fields.IntegerField(required=True)
created_at: datetime = fields.AwareDateTimeField(default=get_now)
guild: int
channel: int
delay: int = 30
admin: int
created_at: datetime = NowField()
@JARVIS_INST.register
class Autoreact(Document):
guild: int = fields.IntegerField(required=True)
channel: int = fields.IntegerField(required=True)
reactions: List[str] = fields.ListField(fields.StringField())
admin: int = fields.IntegerField(required=True)
thread: bool = fields.BooleanField(default=True)
created_at: datetime = fields.AwareDateTimeField(default=get_now)
guild: int
channel: int
reactions: list[str] = Field(default_factory=list)
admin: int
thread: bool
created_at: datetime = NowField()
@JARVIS_INST.register
class Config(Document):
"""Config database object."""
key: str = fields.StringField(required=True)
value: Any = RawField(required=True)
key: str
value: str | int | bool
@JARVIS_INST.register
class Filter(Document):
"""Regex Filter database object."""
"""Filter database object."""
def _validate_filters(value):
for v in value:
try:
re.compile(v)
except re.error:
raise ValueError(f"Invalid regex: {v}")
guild: int = fields.IntegerField(required=True)
name: str = fields.StringField(required=True)
filters: List[str] = fields.ListField(fields.StringField(), validate=[_validate_filters])
guild: int
name: str
filters: list[str] = Field(default_factory=list)
@CTC2_INST.register
class Guess(Document):
"""Guess database object."""
correct: bool = fields.BooleanField(default=False)
guess: str = fields.StringField(required=True)
user: int = fields.IntegerField(required=True)
correct: bool
guess: str
user: int
@JARVIS_INST.register
class Permission(EmbeddedDocument):
class Permission(BaseModel):
"""Embedded Permissions document."""
id: int = fields.IntegerField(required=True)
allow: int = fields.IntegerField(default=0)
deny: int = fields.IntegerField(default=0)
id: int
allow: int = 0
deny: int = 0
@JARVIS_INST.register
class Lock(Document):
"""Lock database object."""
active: bool = fields.BooleanField(default=True)
admin: int = fields.IntegerField(required=True)
channel: int = fields.IntegerField(required=True)
duration: int = fields.IntegerField(default=10)
guild: int = fields.IntegerField(required=True)
reason: str = fields.StringField(required=True)
original_perms: Permission = fields.EmbeddedField(Permission, required=False)
created_at: datetime = fields.AwareDateTimeField(default=get_now)
active: bool = True
admin: int
channel: int
duration: int = 10
reason: str
original_perms: Permission
created_at: datetime = NowField()
@JARVIS_INST.register
class Lockdown(Document):
"""Lockdown database object."""
active: bool = fields.BooleanField(default=True)
admin: int = fields.IntegerField(required=True)
duration: int = fields.IntegerField(default=10)
guild: int = fields.IntegerField(required=True)
reason: str = fields.StringField(required=True)
original_perms: int = fields.IntegerField(required=True)
created_at: datetime = fields.AwareDateTimeField(default=get_now)
active: bool = True
admin: int
duration: int = 10
guild: int
reason: str
original_perms: int
created_at: datetime = NowField()
@JARVIS_INST.register
class Event(Document):
"""Event Meetup Object."""
user: int = fields.IntegerField(required=True)
going: bool = fields.BooleanField(required=True)
travel_method: str = fields.StringField()
before_flight: str = fields.StringField()
before_arrival_time: datetime = fields.AwareDateTimeField()
before_departure_time: datetime = fields.AwareDateTimeField()
after_flight: str = fields.StringField()
after_arrival_time: datetime = fields.AwareDateTimeField()
after_departure_time: datetime = fields.AwareDateTimeField()
hotel: str = fields.StringField()
event_name: str = fields.StringField()
@JARVIS_INST.register
class Phishlist(Document):
"""Phishing safelist."""
url: str = fields.StringField(required=True)
confirmed: bool = fields.BooleanField(default=False)
valid: bool = fields.BooleanField(default=True)
created_at: datetime = fields.AwareDateTimeField(default=get_now)
@JARVIS_INST.register
class Purge(Document):
"""Purge database object."""
admin: int = fields.IntegerField(required=True)
channel: int = fields.IntegerField(required=True)
guild: int = fields.IntegerField(required=True)
count: int = fields.IntegerField(default=10)
created_at: datetime = fields.AwareDateTimeField(default=get_now)
admin: int
channel: int
guild: int
count_: int = Field(10, alias="count")
created_at: datetime = NowField()
@JARVIS_INST.register
class Reminder(Document):
"""Reminder database object."""
active: bool = fields.BooleanField(default=True)
user: int = fields.IntegerField(required=True)
guild: int = fields.IntegerField(required=True)
channel: int = fields.IntegerField(required=True)
message: str = fields.StringField(required=True)
remind_at: datetime = fields.AwareDateTimeField(required=True)
created_at: datetime = fields.AwareDateTimeField(default=get_now)
private: bool = fields.BooleanField(default=False)
active: bool = True
user: int
guild: int
channel: int
message: str
remind_at: datetime
created_at: datetime = NowField()
repeat: Optional[str] = None
timezone: str = "UTC"
total_reminders: int = 0
parent: Optional[str] = None
private: bool = False
@JARVIS_INST.register
class Rolegiver(Document):
"""Rolegiver database object."""
guild: int = fields.IntegerField(required=True)
roles: List[int] = fields.ListField(fields.IntegerField())
guild: int
roles: list[int]
group: Optional[str] = None
@JARVIS_INST.register
class Bypass(EmbeddedDocument):
class Bypass(BaseModel):
"""Roleping bypass embedded object."""
users: List[int] = fields.ListField(fields.IntegerField())
roles: List[int] = fields.ListField(fields.IntegerField())
users: list[int]
roles: list[int]
@JARVIS_INST.register
class Roleping(Document):
"""Roleping database object."""
active: bool = fields.BooleanField(default=True)
role: int = fields.IntegerField(required=True)
guild: int = fields.IntegerField(required=True)
admin: int = fields.IntegerField(required=True)
bypass: Bypass = fields.EmbeddedField(Bypass)
created_at: datetime = fields.AwareDateTimeField(default=get_now)
active: bool = True
role: int
guild: int
admin: int
bypass: Bypass
created_at: datetime = NowField()
@JARVIS_INST.register
class Setting(Document):
"""Setting database object."""
guild: int = fields.IntegerField(required=True)
setting: str = fields.StringField(required=True)
value: Any = RawField()
guild: int
setting: str
value: str | int | bool | list[int | str]
@JARVIS_INST.register
class Star(Document):
"""Star database object."""
class Phishlist(Document):
"""Phishlist database object."""
active: bool = fields.BooleanField(default=True)
index: int = fields.IntegerField(required=True)
message: int = fields.IntegerField(required=True)
channel: int = fields.IntegerField(required=True)
starboard: int = fields.IntegerField(required=True)
guild: int = fields.IntegerField(required=True)
admin: int = fields.IntegerField(required=True)
star: int = fields.IntegerField(required=True)
created_at: datetime = fields.AwareDateTimeField(default=get_now)
url: str
confirmed: bool = False
valid: bool = True
created_at: datetime = NowField()
@JARVIS_INST.register
class Starboard(Document):
"""Starboard database object."""
class Pinboard(Document):
"""Pinboard database object."""
channel: int = fields.IntegerField(required=True)
guild: int = fields.IntegerField(required=True)
admin: int = fields.IntegerField(required=True)
created_at: datetime = fields.AwareDateTimeField(default=get_now)
channel: int
guild: int
admin: int
created_at: datetime = NowField()
class Pin(Document):
"""Pin database object."""
active: bool = True
index: int
message: int
channel: int
pinboard: Link[Pinboard]
guild: int
admin: int
pin: int
created_at: datetime = NowField()
@JARVIS_INST.register
class Tag(Document):
"""Tag database object."""
creator: int = fields.IntegerField(required=True)
created_at: datetime = fields.AwareDateTimeField(default=get_now)
editor: int = fields.IntegerField()
edited_at: datetime = fields.AwareDateTimeField()
name: str = fields.StringField(required=True)
content: str = fields.StringField(required=True)
guild: int = fields.IntegerField(required=True)
creator: int
name: str
content: str
guild: int
created_at: datetime = NowField()
edited_at: Optional[datetime] = None
editor: Optional[int] = None
@JARVIS_INST.register
class Temprole(Document):
"""Temporary role object."""
guild: int = fields.IntegerField(required=True)
user: int = fields.IntegerField(required=True)
role: int = fields.IntegerField(required=True)
admin: int = fields.IntegerField(required=True)
expires_at: datetime = fields.AwareDateTimeField(required=True)
created_at: datetime = fields.AwareDateTimeField(default=get_now)
guild: int
user: int
role: int
admin: int
expires_at: datetime
reapply_on_rejoin: bool = True
created_at: datetime = NowField()
@JARVIS_INST.register
class UserSetting(Document):
"""User Setting object."""
user: int = fields.IntegerField(required=True)
type: str = fields.StringField(required=True)
setting: str = fields.StringField(required=True)
value: Any = RawField()
user: int
type: str
setting: str
value: str | int | bool
class Meta:
collection_name = "usersetting"
all_models = [
Autopurge,
Autoreact,
Ban,
Config,
Filter,
Guess,
Kick,
Lock,
Lockdown,
Modlog,
Mute,
Pin,
Pinboard,
Phishlist,
Purge,
Reminder,
Rolegiver,
Roleping,
Setting,
Subreddit,
SubredditFollow,
Tag,
Temprole,
TwitterAccount,
TwitterFollow,
Unban,
UserSetting,
Warning,
]

View file

@ -1,72 +1,66 @@
"""User action models."""
from datetime import datetime, timezone
from datetime import datetime
from typing import Optional
from umongo import Document, fields
from beanie import Document
from jarvis_core.db import JARVIS_INST
from jarvis_core.db.utils import get_now
from jarvis_core.db.utils import NowField
@JARVIS_INST.register
class Ban(Document):
active: bool = fields.BooleanField(default=True)
admin: int = fields.IntegerField(required=True)
user: int = fields.IntegerField(required=True)
username: str = fields.StringField(required=True)
discrim: int = fields.IntegerField(required=True)
duration: int = fields.IntegerField(required=False, default=None)
guild: int = fields.IntegerField(required=True)
type: str = fields.StringField(default="perm")
reason: str = fields.StringField(required=True)
created_at: datetime = fields.AwareDateTimeField(default=get_now)
active: bool = True
admin: int
user: int
username: str
discrim: Optional[int]
duration: Optional[int]
guild: int
type: str = "perm"
reason: str
created_at: datetime = NowField()
@JARVIS_INST.register
class Kick(Document):
"""Kick database object."""
admin: int = fields.IntegerField(required=True)
guild: int = fields.IntegerField(required=True)
reason: str = fields.StringField(required=True)
user: int = fields.IntegerField(required=True)
created_at: datetime = fields.AwareDateTimeField(default=get_now)
admin: int
guild: int
reason: str
user: int
created_at: datetime = NowField()
@JARVIS_INST.register
class Mute(Document):
"""Mute database object."""
active: bool = fields.BooleanField(default=True)
user: int = fields.IntegerField(required=True)
admin: int = fields.IntegerField(required=True)
duration: int = fields.IntegerField(default=10)
guild: int = fields.IntegerField(required=True)
reason: str = fields.StringField(required=True)
created_at: datetime = fields.AwareDateTimeField(default=get_now)
active: bool = True
user: int
admin: int
duration: int = 10
guild: int
reason: str
created_at: datetime = NowField()
@JARVIS_INST.register
class Unban(Document):
"""Unban database object."""
user: int = fields.IntegerField(required=True)
username: str = fields.StringField(required=True)
discrim: int = fields.IntegerField(required=True)
guild: int = fields.IntegerField(required=True)
admin: int = fields.IntegerField(required=True)
reason: str = fields.StringField(required=True)
created_at: datetime = fields.AwareDateTimeField(default=get_now)
user: int
username: str
discrim: Optional[str]
guild: int
reason: str
created_at: datetime = NowField()
@JARVIS_INST.register
class Warning(Document):
"""Warning database object."""
active: bool = fields.BooleanField(default=True)
admin: int = fields.IntegerField(required=True)
user: int = fields.IntegerField(required=True)
guild: int = fields.IntegerField(required=True)
duration: int = fields.IntegerField(default=24)
reason: str = fields.StringField(required=True)
expires_at: datetime = fields.AwareDateTimeField(required=True)
created_at: datetime = fields.AwareDateTimeField(default=get_now)
active: bool = True
admin: int
user: int
guild: int
duration: int = 24
reason: str
expires_at: datetime
created_at: datetime = NowField()

View file

@ -1,122 +1,104 @@
from datetime import datetime
from typing import List, Optional
from typing import Optional
from umongo import Document, EmbeddedDocument, fields
from beanie import Document, Indexed, Link
from pydantic import BaseModel, Field
from jarvis_core import __version__
from jarvis_core.db import JARVIS_INST
from jarvis_core.db.fields import BinaryField
from jarvis_core.db.utils import get_id, get_now
from jarvis_core.db.utils import NanoField, NowField
@JARVIS_INST.register
class Image(Document):
discord_id: int = fields.IntegerField(unique=True)
image_data: List[bytes] = BinaryField()
image_ext: str = fields.StringField()
created_at: datetime = fields.AwareDateTimeField(default=get_now)
discord_id: int = Indexed(int, unique=True)
image_data: list[bytes]
image_ext: str
created_at: datetime = NowField()
@JARVIS_INST.register
class PermissionOverwriteBackup(EmbeddedDocument):
id: int = fields.IntegerField()
type: int = fields.IntegerField()
allow: int = fields.IntegerField()
deny: int = fields.IntegerField()
class PermissionOverwriteBackup(BaseModel):
id: int
type: int
allow: int
deny: int
@JARVIS_INST.register
class WebhookBackup(EmbeddedDocument):
id: int = fields.IntegerField()
channel_id: int = fields.IntegerField()
type: int = fields.IntegerField()
avatar: Image = fields.ReferenceField(Image)
name: str = fields.StringField()
class WebhookBackup(BaseModel):
id: int
channel_id: int
type: int
avatar: Link[Image]
name: str
@JARVIS_INST.register
class ChannelBackup(EmbeddedDocument):
id: int = fields.IntegerField()
name: str = fields.StringField()
type: int = fields.IntegerField()
position: int = fields.IntegerField()
topic: Optional[str] = fields.StringField(default=None)
nsfw: bool = fields.BooleanField(default=False)
rate_limit_per_user: int = fields.IntegerField(default=None)
bitrate: Optional[int] = fields.IntegerField(default=None)
user_limit: Optional[int] = fields.IntegerField(default=None)
permission_overwrites: List[PermissionOverwriteBackup] = fields.ListField(
fields.EmbeddedField(PermissionOverwriteBackup), factory=list
)
parent_id: Optional[int] = fields.IntegerField(default=None)
rtc_region: Optional[str] = fields.StringField(default=None)
video_quality_mode: Optional[int] = fields.IntegerField(default=None)
default_auto_archive_duration: Optional[int] = fields.IntegerField(default=None)
webhooks: List[WebhookBackup] = fields.ListField(
fields.EmbeddedField(WebhookBackup), factory=list
)
class ChannelBackup(BaseModel):
id: int
name: str
type: int
position: int
topic: Optional[str] = None
nsfw: bool = False
rate_limit_per_user: Optional[int] = None
bitrate: Optional[int] = None
user_limit: Optional[int] = None
permission_overwrites: list[PermissionOverwriteBackup] = Field(default_factory=list)
parent_id: Optional[int] = None
rtc_region: Optional[str] = None
video_quality_mode: Optional[int] = None
default_auto_archive_duration: Optional[int] = None
webhooks: list[WebhookBackup] = Field(default_factory=list)
@JARVIS_INST.register
class RoleBackup(EmbeddedDocument):
id: int = fields.IntegerField()
name: str = fields.StringField()
permissions: int = fields.IntegerField()
color: str = fields.StringField()
hoist: bool = fields.BooleanField()
mentionable: bool = fields.BooleanField()
class RoleBackup(BaseModel):
id: int
name: str
permissions: int
color: str
hoist: bool
mentionable: bool
@JARVIS_INST.register
class EmojiBackup(EmbeddedDocument):
id: int = fields.IntegerField()
name: str = fields.StringField()
image: Image = fields.ReferenceField(Image)
class EmojiBackup(BaseModel):
id: int
name: str
image: Link[Image]
@JARVIS_INST.register
class StickerBackup(EmbeddedDocument):
id: int = fields.IntegerField()
name: str = fields.StringField()
format_type: int = fields.IntegerField()
tags: str = fields.StringField()
type: int = fields.IntegerField()
image: Image = fields.ReferenceField(Image)
class StickerBackup(BaseModel):
id: int
name: str
format_type: int
tags: str
type: int
image: Link[Image]
@JARVIS_INST.register
class GuildBackup(EmbeddedDocument):
name: str = fields.StringField(required=True)
description: str = fields.StringField(default=None)
default_message_notifications: Optional[int] = fields.IntegerField(default=None)
explicit_content_filter: Optional[int] = fields.IntegerField(default=None)
afk_channel: Optional[int] = fields.IntegerField(default=None)
afk_timeout: Optional[int] = fields.IntegerField(default=None)
icon: Optional[Image] = fields.ReferenceField(Image, default=None)
owner: int = fields.IntegerField(required=True)
splash: Optional[Image] = fields.ReferenceField(Image, default=None)
discovery_splash: Optional[Image] = fields.ReferenceField(Image, default=None)
banner: Optional[Image] = fields.ReferenceField(Image, default=None)
system_channel: Optional[int] = fields.IntegerField(default=None)
system_channel_flags: Optional[int] = fields.IntegerField(default=None)
rules_channel: Optional[int] = fields.IntegerField(default=None)
public_updates_channel: Optional[int] = fields.IntegerField(default=None)
preferred_locale: Optional[str] = fields.StringField(default=None)
features: List[str] = fields.ListField(fields.StringField, factory=list)
channels: List[ChannelBackup] = fields.ListField(
fields.EmbeddedField(ChannelBackup), factory=list
)
roles: List[RoleBackup] = fields.ListField(fields.EmbeddedField(RoleBackup), factory=list)
emojis: List[EmojiBackup] = fields.ListField(fields.EmbeddedField(EmojiBackup), factory=list)
stickers: List[StickerBackup] = fields.ListField(
fields.EmbeddedField(StickerBackup), factory=list
)
class GuildBackup(BaseModel):
name: str
description: Optional[str] = None
default_message_notifications: Optional[int] = None
explicit_content_filter: Optional[int] = None
afk_channel: Optional[int] = None
afk_timeout: Optional[int] = None
icon: Optional[Link[Image]] = None
owner: int
splash: Optional[Link[Image]] = None
discovery_splash: Optional[Link[Image]] = None
banner: Optional[Link[Image]] = None
system_channel: Optional[int] = None
system_channel_flags: Optional[int] = None
rules_channel: Optional[int] = None
public_updates_channel: Optional[int] = None
preferred_locale: Optional[str] = None
features: list[str] = Field(default_factory=list)
channels: list[ChannelBackup] = Field(default_factory=list)
roles: list[RoleBackup] = Field(default_factory=list)
emojis: list[EmojiBackup] = Field(default_factory=list)
stickers: list[StickerBackup] = Field(default_factory=list)
@JARVIS_INST.register
class Backup(Document):
created_at: datetime = fields.AwareDateTimeField(default=get_now)
guild_id: int = fields.IntegerField()
bkid: str = fields.StringField(default=get_id)
guild: GuildBackup = fields.EmbeddedField(GuildBackup, required=True)
version: str = fields.StringField(default=__version__)
created_at: datetime = NowField()
guild_id: int
bkid: str = NanoField()
guild: GuildBackup
version: str = Field(default=__version__)

View file

@ -0,0 +1,12 @@
from datetime import datetime
from beanie import Document
from pydantic import Field
from jarvis_core.db.utils import get_now
class Captcha(Document):
user: int
guild: int
correct: str
created_at: datetime = Field(default_factory=get_now)

View file

@ -1,36 +1,30 @@
"""Mastodon databaes models."""
from datetime import datetime, timezone
from umongo import Document, fields
from beanie import Document
from jarvis_core.db import JARVIS_INST
from jarvis_core.db.utils import get_now
from jarvis_core.db.utils import NowField
@JARVIS_INST.register
class MastodonUser(Document):
"""User object."""
user_id: int = fields.IntegerField(required=True)
acct: str = fields.StringField(required=True)
username: str = fields.StringField(required=True)
last_sync: datetime = fields.AwareDateTimeField(default=get_now)
class Meta:
collection_name = "mastodonuser"
user_id: int
acct: str
username: str
last_sync: datetime = NowField()
@JARVIS_INST.register
class MastodonFollow(Document):
"""User Follow object."""
active: bool = fields.BooleanField(default=True)
user_id: int = fields.IntegerField(required=True)
channel: int = fields.IntegerField(required=True)
guild: int = fields.IntegerField(required=True)
reblogged: bool = fields.BooleanField(default=True)
admin: int = fields.IntegerField(required=True)
created_at: datetime = fields.AwareDateTimeField(default=get_now)
class Meta:
collection_name = "mastodonfollow"
active: bool = True
user_id: int
channel: int
guild: int
reblogged: bool = True
admin: int
created_at: datetime = NowField()

View file

@ -1,41 +1,36 @@
"""Modlog database models."""
from datetime import datetime, timezone
from typing import List
from datetime import datetime
from bson import ObjectId
from umongo import Document, EmbeddedDocument, fields
from beanie import Document, PydanticObjectId
from pydantic import BaseModel, Field
from jarvis_core.db import JARVIS_INST
from jarvis_core.db.utils import get_id, get_now
from jarvis_core.db.utils import NowField, NanoField
@JARVIS_INST.register
class Action(EmbeddedDocument):
class Action(BaseModel):
"""Modlog embedded action document."""
action_type: str = fields.StringField(required=True)
parent: ObjectId = fields.ObjectIdField(required=True)
orphaned: bool = fields.BoolField(default=False)
action_type: str
parent: PydanticObjectId
orphaned: bool = False
@JARVIS_INST.register
class Note(EmbeddedDocument):
class Note(BaseModel):
"""Modlog embedded note document."""
admin: int = fields.IntegerField(required=True)
content: str = fields.StrField(required=True)
created_at: datetime = fields.AwareDateTimeField(default=get_now)
admin: int
content: str
created_at: datetime = NowField()
@JARVIS_INST.register
class Modlog(Document):
"""Modlog database object."""
user: int = fields.IntegerField(required=True)
nanoid: str = fields.StringField(default=get_id)
guild: int = fields.IntegerField(required=True)
admin: int = fields.IntegerField(required=True)
actions: List[Action] = fields.ListField(fields.EmbeddedField(Action), factory=list)
open: bool = fields.BoolField(default=True)
created_at: datetime = fields.AwareDateTimeField(default=get_now)
notes: List[Note] = fields.ListField(fields.EmbeddedField(Note), factory=list)
user: int
nanoid: str = NanoField()
guild: int
admin: int
actions: list[Action] = Field(default_factory=list)
notes: list[Note] = Field(default_factory=list)
open: bool = True
created_at: datetime = NowField

View file

@ -1,52 +1,27 @@
"""Reddit databaes models."""
from datetime import datetime, timezone
from datetime import datetime
from umongo import Document, fields
from beanie import Document
from jarvis_core.db import JARVIS_INST
from jarvis_core.db.utils import get_now
from jarvis_core.db.utils import NowField
@JARVIS_INST.register
class Subreddit(Document):
"""Subreddit object."""
display_name: str = fields.StringField(required=True)
over18: bool = fields.BooleanField(default=False)
display_name: str
over18: bool = False
@JARVIS_INST.register
class SubredditFollow(Document):
"""Subreddit Follow object."""
active: bool = fields.BooleanField(default=True)
display_name: str = fields.StringField(required=True)
channel: int = fields.IntegerField(required=True)
guild: int = fields.IntegerField(required=True)
admin: int = fields.IntegerField(required=True)
created_at: datetime = fields.AwareDateTimeField(default=get_now)
active: bool = True
display_name: str
channel: int
guild: int
admin: int
created_at: datetime = NowField()
class Meta:
collection_name = "subredditfollow"
@JARVIS_INST.register
class Redditor(Document):
"""Reddit User object."""
name: str = fields.StringField(required=True)
@JARVIS_INST.register
class RedditorFollow(Document):
"""Reditor Follow object."""
active: bool = fields.BooleanField(default=True)
name: str = fields.StringField(required=True)
channel: int = fields.IntegerField(required=True)
guild: int = fields.IntegerField(required=True)
admin: int = fields.IntegerField(required=True)
created_at: datetime = fields.AwareDateTimeField(default=get_now)
class Meta:
collection_name = "redditorfollow"
class Setting:
name = "subredditfollow"

View file

@ -1,36 +1,33 @@
"""Twitter database models."""
from datetime import datetime, timezone
from datetime import datetime
from umongo import Document, fields
from beanie import Document
from jarvis_core.db import JARVIS_INST
from jarvis_core.db.utils import get_now
from jarvis_core.db.utils import NowField
@JARVIS_INST.register
class TwitterAccount(Document):
"""Twitter Account object."""
handle: str = fields.StringField(required=True)
twitter_id: int = fields.IntegerField(required=True)
last_tweet: int = fields.IntegerField(required=True)
last_sync: datetime = fields.AwareDateTimeField(default=get_now)
handle: str
twitter_id: int
last_tweet: int
last_sync: datetime = NowField()
class Meta:
collection_name = "twitteraccount"
class Setting:
name = "twitteraccount"
@JARVIS_INST.register
class TwitterFollow(Document):
"""Twitter Follow object."""
active: bool = fields.BooleanField(default=True)
twitter_id: int = fields.IntegerField(required=True)
channel: int = fields.IntegerField(required=True)
guild: int = fields.IntegerField(required=True)
retweets: bool = fields.BooleanField(default=True)
admin: int = fields.IntegerField(required=True)
created_at: datetime = fields.AwareDateTimeField(default=get_now)
active: bool = True
twitter_id: int
channel: int
guild: int
retweets: bool = True
admin: int
created_at: datetime = NowField()
class Meta:
collection_name = "twitterfollow"
class Setting:
name = "twitterfollow"

View file

@ -1,6 +1,8 @@
from datetime import datetime, timezone
from functools import partial
import nanoid
from pydantic import Field
NANOID_ALPHA = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
@ -13,3 +15,7 @@ def get_now() -> datetime:
def get_id() -> str:
"""Get nanoid."""
return nanoid.generate(NANOID_ALPHA, 12)
NowField = partial(Field, default_factory=get_now)
NanoField = partial(Field, default_factory=get_id)

View file

@ -9,38 +9,6 @@ from jarvis_core.filters import url
DEFAULT_BLOCKSIZE = 8 * 1024 * 1024
class Singleton(object):
REQUIRED = []
OPTIONAL = {}
def __new__(cls, *args: list, **kwargs: dict):
"""Create a new singleton."""
inst = cls.__dict__.get("inst")
if inst is not None:
return inst
inst = object.__new__(cls)
inst.init(*args, **kwargs)
inst._validate()
cls.__inst__ = inst
return inst
def _validate(self) -> None:
for key in self.REQUIRED:
if not getattr(self, key, None):
raise ValueError(f"Missing required key: {key}")
def init(self, **kwargs: dict) -> None:
"""Initialize the object."""
for key, value in kwargs.items():
setattr(self, key, value)
for key, value in self.OPTIONAL.items():
if not getattr(self, key, None):
setattr(self, key, value)
async def hash(
data: str, method: Union[Callable, str] = hashlib.sha256, size: int = DEFAULT_BLOCKSIZE
) -> Tuple[str, int, str]:

798
poetry.lock generated

File diff suppressed because it is too large Load diff

View file

@ -1,26 +1,29 @@
[tool.poetry]
name = "jarvis-core"
version = "0.16.1"
version = "0.18.0"
description = "JARVIS core"
authors = ["Zevaryx <zevaryx@gmail.com>"]
[tool.poetry.dependencies]
python = "^3.10"
orjson = "^3.6.6"
python = ">=3.10,<4"
orjson = { version = "^3.6.6" }
motor = "^3.1.1"
umongo = "^3.1.0"
PyYAML = "^6.0"
PyYAML = { version = "^6.0" }
pytz = "^2022.1"
aiohttp = "^3.8.1"
rich = "^12.3.0"
nanoid = "^2.0.0"
python-dotenv = "^0.21.0"
beanie = "^1.17.0"
pydantic = ">=2.3.0,<3"
[tool.poetry.dev-dependencies]
pytest = "^7.1"
[tool.poetry.group.dev.dependencies]
black = "^23.1.0"
ipython = "^8.5.0"
rich = "^12.6.0"
black = {version = "^22.10.0", allow-prereleases = true}
[build-system]
requires = ["poetry-core>=1.0.0"]