class Item(models.Model): """Модель items""" id = fields.IntField(pk=True) name = fields.CharField(max_length=100) description = fields.TextField(null=True) min_per = fields.IntField() max_per = fields.IntField() price = fields.FloatField() quantity = fields.IntField() date = fields.DatetimeField() # image = fields.CharField(max_length=1000) # owner: fields.ForeignKeyRelation['User'] = fields.ForeignKeyField( # 'models.User', related_name='items' # ) def min_price(self) -> float: return self.price + ((self.price * self.min_per)/100) def mid_price(self) -> float: mid = (self.max_per + self.min_per)/2 return self.price + ((self.price * mid)/100) def max_price(self) -> float: return self.price + ((self.price * self.max_per)/100) class PydanticMeta: computed = ("min_price", "mid_price", "max_price")
class Tournament(Model): id = fields.IntField(pk=True) name = fields.CharField(max_length=255, description="Tournament name", index=True) created = fields.DatetimeField(auto_now_add=True, description="Created datetime") class Meta: table_description = "What Tournaments we have"
class Event(Model): """ Events on the calendar """ event_id = fields.BigIntField(pk=True) #: The name name = fields.TextField() #: What tournaments is a happenin' tournament: fields.ForeignKeyRelation[ "Tournament"] = fields.ForeignKeyField("models.Tournament", related_name="events") reporter: fields.ForeignKeyNullableRelation[ Reporter] = fields.ForeignKeyField("models.Reporter", null=True) participants: fields.ManyToManyRelation["Team"] = fields.ManyToManyField( "models.Team", related_name="events", through="event_team", backward_key="idEvent") modified = fields.DatetimeField(auto_now=True) token = fields.TextField(default=generate_token) alias = fields.IntField(null=True) class Meta: ordering = ["name"] def __str__(self): return self.name
class Bid(Model): id = fields.BigIntField(pk=True) auction = fields.ForeignKeyField('models.Auction', 'bids') bid_amount = fields.BigIntField() bidder = fields.ForeignKeyField('models.Address', 'bids') level = fields.BigIntField() timestamp = fields.DatetimeField()
class TextSummary(models.Model): url = fields.TextField() summary = fields.TextField() created_at = fields.DatetimeField(auto_now_add=True) def __str__(self): return self.url
class Reports(Model): id = fields.IntField(pk=True) user = fields.IntField() item = fields.IntField() type = fields.CharField(max_length=7) notes = fields.TextField(default="") datetime = fields.DatetimeField()
class MatchData(Model): match_id = fields.IntField(pk=True, generated=True) logstf = fields.ForeignKeyField('models.LogstfData', related_name='match_data') match_date = fields.DatetimeField() winning_team = fields.CharField(max_length=4) # Should we reference Players table for each player in the game? players = fields.CharField(max_length=255) length = fields.IntField() red_score = fields.IntField() red_kills = fields.IntField() red_deaths = fields.IntField() red_dmg = fields.IntField() red_charges = fields.IntField() red_drops = fields.IntField() red_firstcaps = fields.IntField() red_caps = fields.IntField() blue_score = fields.IntField() blue_kills = fields.IntField() blue_deaths = fields.IntField() blue_dmg = fields.IntField() blue_charges = fields.IntField() blue_drops = fields.IntField() blue_firstcaps = fields.IntField() blue_caps = fields.IntField() class Meta: table = "matches" table_description = "Stores data on all matches played" unique_together = ('logstf', )
class Logs(Model): id = fields.BigIntField(pk=True) created_at = fields.DatetimeField(auto_now_add=True) content = fields.TextField() class Meta: table = "logs"
class User(models.Model): id = fields.IntField(pk=True) username = fields.CharField(max_length=20, unique=True) first_name = fields.CharField(max_length=50, null=True) last_name = fields.CharField(max_length=50, null=True) category = fields.CharField(max_length=30, default="misc") password_hash = fields.CharField(max_length=128, null=True) created_at = fields.DatetimeField(auto_now_add=True) modified_at = fields.DatetimeField(auto_now=True) def full_name(self) -> str: return f"{self.first_name} {self.last_name}" class PydanticMeta: computed = ["full_name"] exclude = ["password_hash"]
class Password(TimestampModelMixin, models.Model): """密码验证方式""" id = fields.BigIntField(pk=True) shadow = fields.CharField(max_length=512) credential: Fk["Credential"] = fields.ForeignKeyField( "models.Credential", ondelete=fields.CASCADE, related_name="passwords" ) expires_at = fields.DatetimeField(null=True) class Meta: table = "eva_password" @classmethod def from_raw( cls, credential: Credential, raw_password: str, permanent=config.settings.password_permanent ) -> "Password": expires_at = None if permanent else datetime.utcnow() + config.settings.password_age return Password(credential=credential, shadow=encrypt.encrypt_password(raw_password), expires_at=expires_at) @property def is_expired(self): if not self.expires_at: return False return datetime.utcnow() > self.expires_at def validate_password(self, raw_password) -> bool: return encrypt.check_password(self.shadow, raw_password) def set_password(self, raw_password): self.shadow = encrypt.encrypt_password(raw_password)
class BotNotification(Model): id = fields.IntField(pk=True) from_address = fields.CharField(max_length=255) fcm_token = fields.ForeignKeyField("bot_detector.FcmToken", related_name="notifications") created_at = fields.DatetimeField(auto_now_add=True) def __repr__(self): return f"{self.id}-{self.from_address}" @classmethod async def create__and_send_bot_notifications_for_address( cls, from_address): time_before = datetime.now() - timedelta( seconds=settings.SECONDS_TO_SEND_REMINDER_NOTIFICATION) tokens_to_exclude = await cls.filter( Q(from_address=from_address) & Q(created_at__gte=time_before)).values_list("fcm_token__id", flat=True) tokens_for_new_notification = await FcmToken.exclude( id__in=tokens_to_exclude) bot_notifications = [ cls(from_address=from_address, fcm_token=token) for token in tokens_for_new_notification ] push_service.notify_multiple_devices( registration_ids=[ token.token for token in tokens_for_new_notification ], message_title="Bot detected", message_body=f"Bot with address {from_address} detected", ) await cls.bulk_create(bot_notifications)
class Event(models.Model): name = fields.TextField() location = fields.TextField() day_time = fields.DatetimeField() def __str__(self): return self.name
class HealthCheck(models.Model): """ HealthCheck model """ # Id stuff id = fields.IntField(pk=True) uuid = fields.UUIDField() name = fields.CharField(max_length=128, unique=True) created_at = fields.DatetimeField(auto_now_add=True) modified_at = fields.DatetimeField(auto_now=True) period = fields.IntField(default=5) grace = fields.IntField(default=5) # Relations user: fields.ForeignKeyRelation[User] = fields.ForeignKeyField( "models.User")
class Tournament(Model): tid = fields.SmallIntField(pk=True) name = fields.CharField(max_length=100, description="Tournament name", index=True) created = fields.DatetimeField(auto_now_add=True, description="Created */'`/* datetime") class Meta: table_description = "What Tournaments */'`/* we have"
class IPSeed(Model): id = fields.IntField(pk=True) dagCid = fields.CharField(max_length=512, unique=True) dateAdded = fields.DatetimeField(auto_now_add=True) hidden = fields.BooleanField(default=False) status = fields.IntField(default=0)
class Player(Model): discord_id = fields.BigIntField(pk=True) discord_name = fields.CharField(max_length=200) percent_infected = fields.IntField(default=0) cured = fields.BooleanField(default=False) doctor = fields.BooleanField(default=False) immunodeficient = fields.BooleanField(default=False) total_infected_points = fields.IntField(default=0) total_cured_points = fields.IntField(default=0) maximum_infected_points = fields.IntField(default=0) isolation = fields.IntEnumField(Isolation, default=Isolation.normal_life) touched_last = fields.DatetimeField(auto_now_add=True) good = fields.IntEnumField(AlignmentGood) law = fields.IntEnumField(AlignmentLaw) charisma = fields.IntField() inventory: fields.ReverseRelation["Inventory"] achievements: fields.ReverseRelation["Achievements"] statistics: fields.ReverseRelation["Statistics"] def is_dead(self) -> bool: return self.percent_infected >= 100 def is_infected(self) -> bool: return self.percent_infected > 0 def can_be_touched(self) -> bool: if not self.is_dead(): return self.touched_last + datetime.timedelta( hours=3) < datetime.datetime.utcnow() return self.touched_last + datetime.timedelta( hours=1) < datetime.datetime.utcnow() def infect(self, add_infected: int = None) -> None: if add_infected is None: add_infected = random.randint(1, 8) if self.achievements.vaccinated: add_infected = min(0, add_infected) self.total_infected_points += max(0, add_infected) self.total_cured_points -= min(0, add_infected) self.percent_infected += add_infected self.percent_infected = max(self.percent_infected, 0) self.maximum_infected_points = max(self.maximum_infected_points, self.percent_infected) if self.total_infected_points >= 50 and self.percent_infected == 0: self.cured = True # Defining ``__str__`` is also optional, but gives you pretty # represent of model in debugger and interpreter def __str__(self): return self.discord_name
class Requests(Model): id = fields.IntField(pk=True) user = fields.IntField() item = fields.IntField() type = fields.CharField(max_length=7) datetime = fields.DatetimeField() done = fields.BooleanField(default=False)
class Team(models.Model): id = fields.IntField(pk=True) name = fields.CharField(max_length=255) created = fields.DatetimeField(auto_now=True) def __str__(self): return self.name
class RawMail(Model): id = fields.IntField(pk=True) status = fields.CharField(max_length=255) peer = (fields.CharField(max_length=255), ) host_name = (fields.CharField(max_length=255), ) mail_from = (fields.CharField(max_length=255), ) tos = (fields.CharField(max_length=255), ) subject = (fields.CharField(max_length=255), ) received = (fields.DatetimeField(), ) data = fields.TextField() @staticmethod def from_dict(data): rm = RawMail() rm.status = data["status"] rm.peer = data["peer"] rm.host_name = data["host_name"] rm.mail_from = data["from"] rm.tos = data["tos"] rm.subject = data["subject"] rm.received = datetime.datetime.now().isoformat() rm.data = data["data"] return rm
class Tag(tortoise.Model): id = fields.BigIntField(pk=True) server_id = fields.BigIntField() author_id = fields.BigIntField() name = fields.TextField() content = fields.TextField() uses = fields.IntField(default=0) created_at = fields.DatetimeField(auto_now_add=True) class Meta: table = "tags" def __str__(self): return (f"<Tag id={self.id} " f"server_id={self.server_id} " f"author_id={self.author_id} " f"name='{self.name}' " f"content='{self.content}' " f"uses={self.uses} " f"created_at={self.created_at}>") __repr__ = __str__
class PostTag(BaseModel): post_id = fields.IntField() tag_id = fields.IntField() updated_at = fields.DatetimeField(auto_now_add=True) class Meta: table = 'post_tags' @classmethod async def update_multi(cls, post_id, tags): origin_tags = set( [t.name for t in (await Post.sync_get(id=post_id)).tags]) need_add = set(tags) - origin_tags need_del = origin_tags - set(tags) need_add_tag_ids = [] need_del_tag_ids = set() for tag_name in need_add: tag, _ = await Tag.get_or_create(name=tag_name) need_add_tag_ids.append([tag.id, tag_name]) for tag_name in need_del: tag, _ = await Tag.get_or_create(name=tag_name) need_del_tag_ids.add(tag.id) if need_del_tag_ids: await cls.filter(Q(post_id=post_id), Q(tag_id__in=need_del_tag_ids)).delete() for tag_id, _ in sorted(need_add_tag_ids, key=lambda x: tags.index(x[1])): await cls.get_or_create(post_id=post_id, tag_id=tag_id) await clear_mc(MC_KEY_TAGS_BY_POST_ID % post_id)
class BaseModel(Model): # 给予的默认字段 id = fields.IntField(pk=True) created_at = fields.DatetimeField(auto_now_add=True) class Meta: abstract = True
class Tournament(Model): id = fields.IntField(pk=True) name = fields.TextField() created = fields.DatetimeField(auto_now_add=True) def __str__(self): return self.name
class Book(Model): def __init__(self, **kwargs): genres = kwargs.get("genres", []) for genre in genres: if not isinstance(genre, BookGenres): raise TypeError( "{} is not a BookGenres instance".format(genre)) if genres: kwargs["genres"] = [genre.value for genre in genres] super(Book, self).__init__(**kwargs) id = fields.UUIDField(pk=True, default=uuid.uuid4) title = fields.TextField() author = fields.ForeignKeyField("models.Author", related_name="books", null=True) published = fields.DatetimeField(null=True) status = fields.ForeignKeyField("models.BookStatus", null=True) retail_price = fields.IntField(null=True) cost_price = fields.IntField(null=True) run = fields.IntField(null=True) volume = fields.IntField(null=True) # Let's assume we're lazy and don't bother with many-many relationships genres = JSONEncodedField(null=False, default=[BookGenres.existential_fiction.value])
class Category(Model): slug = fields.CharField(max_length=200) name = fields.CharField(max_length=200) created_at = fields.DatetimeField(auto_now_add=True) def __str__(self): return f"{self.pk}#{self.name}"
class BaseModel(Model, metaclass=ModelMeta): id = fields.IntField(pk=True) created_at = fields.DatetimeField(auto_now_add=True) _redis = None class Meta: abstract = True
class WordleResults(Model): uuid = fields.UUIDField(pk=True) name = fields.TextField(default='wordle result') user = fields.ForeignKeyField('models.User', related_name='wordle_results', index=True) guesses = fields.IntField() # guesses to solve word (0 for quit) word = fields.TextField() # word guessed created_at = fields.DatetimeField(null=True, auto_now_add=True) @classmethod async def create_result(cls, discord_user: DiscordUser, guesses: int, word: str) -> None: user = await User.get_by_discord_user(discord_user) result = WordleResults(user=user, guesses=guesses, word=word) await result.save() @classmethod async def fetch_all_by_user(cls, discord_user: DiscordUser) -> Any: user = await User.get_by_discord_user(discord_user) stat = await WordleResults.filter(user=user) return stat class Meta: table = 'wordle_results'
class User(models.Model): username = fields.CharField(unique=True, max_length=50) email = fields.CharField(unique=True, max_length=80) full_name = fields.TextField() hashed_password = fields.TextField() role = fields.TextField(default="user") scopes = fields.TextField(default="user:read") # access_level = fields.IntField(default=1) created_at = fields.DatetimeField(auto_now_add=True) disabled = fields.BooleanField(default=True) def __str__(self): return f"{self.username} <{self.email}>" @staticmethod def _get_password_context() -> CryptContext: return CryptContext(schemes=["bcrypt"], deprecated="auto") def set_password(self, password: str): self.hashed_password = self._get_password_context().hash(password) def verify_password(self, password: str) -> bool: return self._get_password_context().verify(password, self.hashed_password) def set_access_scopes(self, role): access_level = {"admin": 3, "tech": 2, "user": 1} if role not in access_level.keys(): raise ValueError(f"{role} is and invalid role.") self.role = role self.access_level = access_level.get("role")
class NickVerification(Model): class Meta: table = 'nick_verification' key = fields.BigIntField(pk=True, generated=False) discord_user_id = fields.BigIntField(null=True) timestamp = fields.DatetimeField(auto_now=True, null=True)
class CommentTask(models.Model): """ Model comment by task """ user = fields.ForeignKeyField('models.User', related_name='task_comments') task = fields.ForeignKeyField('models.Task', related_name='comments') message = fields.CharField(max_length=1000) create_date = fields.DatetimeField(auto_now_add=True)