class ThreadUpvote(Document): user_id = fields.ObjectIdField() # Integer? thread_id = fields.ObjectIdField() # Integer? user = fields.ReferenceField("User") # Integer? thread = fields.ReferenceField("Thread") # Integer? class Meta: collection_name = "thread_upvotes"
class CommentUpvote(Document): user_id = fields.ObjectIdField() # Integer? comment_id = fields.ObjectIdField() # Integer? user = fields.ReferenceField("User") # Integer? comment = fields.ReferenceField("Comment") # Integer? class Meta: collection_name = "comment_upvotes"
class FillFormResult(EmbeddedDocument): # pylint: disable=abstract-method """ A document that stores the result of a form-filling task. """ result = fields.StrField(required=True, validate=validate.OneOf( [x.value for x in FillFormResultType])) time_logged = fields.DateTimeField(required=True) course = fields.ObjectIdField(required=False, default=None, allow_none=True) form_screenshot_id = fields.ObjectIdField(required=False, allow_none=True) confirmation_screenshot_id = fields.ObjectIdField(required=False, allow_none=True)
class TestFillFormResult(EmbeddedDocument): # pylint: disable=abstract-method """ A document that stores the result of a form-filling task. """ result = fields.StrField( required=True ) # validation disabled here because we treat these as readonly time_logged = fields.DateTimeField(required=True) course = fields.ObjectIdField(required=False, default=None, allow_none=True) form_screenshot_id = fields.ObjectIdField(required=False, allow_none=True) confirmation_screenshot_id = fields.ObjectIdField(required=False, allow_none=True)
class Comment(EmbeddedDocument): id = fields.ObjectIdField(default=ObjectId()) content = fields.StrField() created_by = fields.ReferenceField("User") created_at = fields.DateTimeField(default=datetime.now) updated_at = fields.DateTimeField(default=datetime.now)
class ProductDocument(Document): category = fields.ObjectIdField(required=True) name = fields.StringField(required=True) description = fields.StringField(required=True) price = fields.FloatField(required=True) image_url = fields.StringField() available_from = fields.StringField(required=True) available_till = fields.StringField(required=True)
class OrderDocument(Document): products = fields.ListField(fields.ReferenceField(ProductDocument), required=True) cafe = fields.ObjectIdField(required=True) user_id = fields.StringField(required=True, unique=True) order_time = fields.DateTimeField(required=True) code = fields.IntegerField(required=True) price = fields.FloatField(required=True) deletion_time = fields.DateTimeField(allow_none=True)
class User(Document): id = fields.ObjectIdField() full_name = fields.StrField() email = fields.EmailField(unique=True) username = fields.StrField(unique=True) hashed_password = fields.StrField() last_password_updated_at = fields.DateTimeField() scopes = fields.ListField(fields.StrField(), default=[]) created_at = fields.DateTimeField(default=datetime.now()) updated_at = fields.DateTimeField(default=datetime.now()) class Meta: collection_name = 'user' collection = db.user @classmethod async def get(cls, id: str): if not ObjectId.is_valid(id): return None user = await cls.find_one({'_id': ObjectId(id)}) return user def check_password(self, password: str): if self.hashed_password: return PWD_CONTEXT.verify(password, self.hashed_password) def set_password(self, password: str): self.hashed_password = PWD_CONTEXT.hash(password) self.last_password_updated_at = datetime.now() def create_access_token(self, expires_delta: timedelta = None): now = datetime.utcnow() if expires_delta: expire = now + expires_delta else: expire = now + timedelta(minutes=15) to_encode = { 'exp': expire, 'iat': now, 'sub': str(self.id), 'scope': ' '.join(self.scopes) if self.scopes else '' } encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM) return encoded_jwt @classmethod async def get_by_username(cls, username: str): return await cls.find_one({'username': username}) @classmethod async def register_new_user(cls, email: str, full_name: str, username: str, password: str): user = cls(email=email, full_name=full_name, username=username) user.set_password(password) await user.commit() return user
class Artefact(Document): name = fields.StrField(required=True) projectId = fields.ObjectIdField(required=False) # SOP sopFileName = fields.StrField(required=False) encodedFileId = fields.ObjectIdField(required=False) artefactClass = fields.StrField(required=False) description = fields.StrField(required=False) owner = fields.StrField(required=False) revision = fields.StrField(required=False) processingPerson = fields.StrField() createdDate = fields.DateTimeField( validate=validate.Range(min=datetime(1900, 1, 1))) updatedDate = fields.DateTimeField( validate=validate.Range(min=datetime(1900, 1, 1))) class Meta: collection_name = "Artefacts"
class TestFillLockboxFailure(EmbeddedDocument): # pylint: disable=abstract-method """ A document used to report lockbox failures to fenetre. """ _id = fields.ObjectIdField(required=True) time_logged = fields.DateTimeField(required=True) kind = fields.StrField(required=True) # same as above message = fields.StrField(required=False, default="")
class CafeOrder(Document): user_id = fields.StrField() provider = fields.StrField() confirm_code = fields.StrField() order_id = fields.StrField() order_time = fields.StrField() cook_time = fields.StrField() special_price = fields.IntField() price = fields.IntField() order_code = fields.StrField() bot_order = fields.ObjectIdField()
class MSReadySample(Document): name = fields.StrField(required=True) projectId = fields.ObjectIdField(required=True) clinicalSamples = fields.ListField(fields.ObjectIdField, required=False) intermediateSampleId = fields.ObjectIdField(required=True) msReadySampleName = fields.StrField(required=False) workflowTag = fields.StrField(required=False) quality = fields.StrField(required=False) peptideNo = fields.FloatField(required=False) description = fields.StrField(required=False) concentration = fields.StrField(required=False) processingPerson = fields.StrField(required=False) currentLocation = fields.StrField(required=False) createdDate = fields.DateTimeField( validate=validate.Range(min=datetime(1900, 1, 1))) updatedDate = fields.DateTimeField( validate=validate.Range(min=datetime(1900, 1, 1))) class Meta: collection_name = "msReadySample"
class SWATHAnalysis(Document): swathId = fields.IntegerField(required=False) name = fields.StrField(required=True) projectId = fields.ObjectIdField(required=True) clinicalSamples = fields.ListField(fields.ObjectIdField, required=False) msRunIds = fields.ListField(fields.ObjectIdField, required=False) protocolId = fields.StrField(required=True) protocolName = fields.StrField(required=False) sopFileName = fields.StrField(required=False) proteinMatrixFileName = fields.StrField(required=False) description = fields.StrField(required=False) workflowTag = fields.StrField(required=False) spectralLibraryId = fields.ObjectIdField(required=True) createdDate = fields.DateTimeField( validate=validate.Range(min=datetime(1900, 1, 1))) updatedDate = fields.DateTimeField( validate=validate.Range(min=datetime(1900, 1, 1))) class Meta: collection_name = "SWATHAnalysis"
class LockboxFailure(EmbeddedDocument): # pylint: disable=abstract-method """ A document used to report lockbox failures to fenetre. Taken from fenetre/db.py. """ _id = fields.ObjectIdField(required=True) time_logged = fields.DateTimeField(required=True) kind = fields.StrField(required=True, validate=validate.OneOf( [x.value for x in LockboxFailureType])) message = fields.StrField(required=False, default="")
class Form(Document): sub_fields = fields.ListField(fields.EmbeddedField(FormField), default=list, validate=_validate_form_fields) # id of file in gridfs, should be a png representative_thumbnail = fields.ObjectIdField(default=None) # Friendly title for this form configuration name = fields.StrField() # is this form the default? if there are multiple of these, uh panic # TODO: use io_validate to check that is_default = fields.BoolField(default=False)
class FormFillingTest(Document): # pylint: disable=abstract-method """ Represents finished/inprogress tests of form filling """ # config to test course_config = fields.ObjectIdField(required=True) # with information from this user requested_by = fields.ObjectIdField( required=False) # holds which user (fenetre) can see this time_executed = fields.DateTimeField(required=False, allow_none=True) # status is_finished = fields.BoolField(default=False) in_progress = fields.BoolField(default=False) is_scheduled = fields.BoolField(default=False) # results errors = fields.ListField(fields.EmbeddedField(LockboxFailure), default=[]) fill_result = fields.EmbeddedField(FillFormResult, default=None, allow_none=True)
class MSRun(Document): runId = fields.IntegerField(required=False) name = fields.StrField(required=True) projectId = fields.ObjectIdField(required=True) clinicalSamples = fields.ListField(fields.ObjectIdField, required=False) msReadySampleId = fields.ObjectIdField(required=True) msReadySampleName = fields.StrField(required=False) protocolId = fields.StrField(required=True) protocolName = fields.StrField(required=False) sopFileName = fields.StrField(required=False) description = fields.StrField(required=False) instrumentId = fields.StrField(required=True) instrumentMethod = fields.StrField(required=False) runCode = fields.StrField(required=False) status = fields.StrField(required=False) processingPerson = fields.StrField(required=False) workflowTag = fields.StrField(required=False) createdDate = fields.DateTimeField( validate=validate.Range(min=datetime(1900, 1, 1))) updatedDate = fields.DateTimeField( validate=validate.Range(min=datetime(1900, 1, 1))) class Meta: collection_name = "MSRun"
class Subreddit(Document): """ """ # __tablename__ = 'subreddits_subreddit' # id = db.Column(db.Integer, primary_key=True) # name = db.Column(db.String(SUBREDDIT.MAX_NAME), unique=True) name = fields.StrField(validate=validate.Length(max=SUBREDDIT.MAX_NAME), unique=True) # desc = db.Column(db.String(SUBREDDIT.MAX_DESCRIPTION)) desc = fields.StrField(validate=validate.Length( max=SUBREDDIT.MAX_DESCRIPTION)) # admin_id = db.Column(db.Integer, db.ForeignKey('users_user.id')) admin_id = fields.ObjectIdField() admin = fields.ReferenceField("User") # created_on = db.Column(db.DateTime, default=db.func.now()) # updated_on = db.Column(db.DateTime, default=db.func.now(), onupdate=db.func.now()) date_created = fields.DateTimeField(default=datetime.datetime.now()) date_updated = fields.DateTimeField(default=datetime.datetime.now()) # threads = db.relationship('Thread', backref='subreddit', lazy='dynamic') # threads = fields.ReferenceField("Thread") # Integer? status = fields.IntegerField(default=SUBREDDIT.ALIVE) class Meta: collection_name = 'subreddits' # collection = db.subreddits def __repr__(self): return '<Subreddit %r>' % (self.name) def get_threads(self, order_by='timestamp'): """ default order by timestamp """ # if order_by == 'timestamp': # return self.threads.order_by(db.desc(Thread.created_on)).\ # all()[:SUBREDDIT.MAX_THREADS] # else: # return self.threads.order_by(db.desc(Thread.created_on)).\ # all()[:SUBREDDIT.MAX_THREADS] threads = threads_model.Thread.find({'subreddit_id': self.id }) #[:SUBREDDIT.MAX_THREADS] return threads
class ClinicalSample(Document): clinicalSampleCode = fields.StringField(required=True) sampleCounter = fields.IntegerField(required=True) name = fields.StrField(required=True) projectId = fields.ObjectIdField(required=True) workflowTag = fields.StrField(required=False) quality = fields.StrField(required=False) description = fields.StrField() processingPerson = fields.StrField() createdDate = fields.DateTimeField( validate=validate.Range(min=datetime(1900, 1, 1))) updatedDate = fields.DateTimeField( validate=validate.Range(min=datetime(1900, 1, 1))) class Meta: collection_name = "clinicalSample"
class IntermediateSample(Document): name = fields.StrField(required=True) projectId = fields.ObjectIdField(required=True) clinicalSamples = fields.ListField(fields.ObjectIdField, required=False) parentSamples = fields.ListField(fields.ObjectIdField, required=False) protocolName = fields.StrField(required=True) workflowTag = fields.StrField(required=False) sopFileName = fields.StrField(required=False) description = fields.StrField() processingPerson = fields.StrField() createdDate = fields.DateTimeField( validate=validate.Range(min=datetime(1900, 1, 1))) updatedDate = fields.DateTimeField( validate=validate.Range(min=datetime(1900, 1, 1))) class Meta: collection_name = "intermediateSample"
class Form(Document): # pylint: disable=abstract-method """ Configuration for a form type to fill out. Taken from fenetre/db.py. """ sub_fields = fields.ListField(fields.EmbeddedField(FormField)) # id of file in gridfs, should be a png representative_thumbnail = fields.ObjectIdField(default=None) # Friendly title for this form configuration name = fields.StrField() # is this form the default? is_default = fields.BoolField(default=False)
class CachedFormGeometry(Document): # pylint: disable=abstract-method """ A document used for caching results to requests for form geometry. """ url = fields.URLField(required=True, unique=True) # Token of the user that requested this form geometry # used to limit requests per user requested_by = fields.StrField(required=False, allow_none=True) geometry = fields.ListField(fields.EmbeddedField(FormGeometryEntry), required=False, allow_none=True) auth_required = fields.BoolField(required=False, allow_none=True) screenshot_file_id = fields.ObjectIdField(required=False, allow_none=True) grab_screenshot = fields.BoolField(default=False) response_status = fields.IntField(required=False) error = fields.StrField(required=False)
class Product(Document): id = fields.ObjectIdField(attribute='_id') name = fields.StringField() description = fields.StringField() properties = fields.DictField() class Meta: collection = db.product def toFullDict(self): return { 'id': str(self.id), 'name': self.name, 'description': self.description, 'properties': self.properties } def toSmallDict(self): return {'id': str(self.id), 'name': self.name}
class SpectralLibrary(Document): libId = fields.IntegerField(required=False) name = fields.StrField(required=True) projectId = fields.ObjectIdField(required=True) clinicalSamples = fields.ListField(fields.ObjectIdField, required=False) msRunIds = fields.ListField(fields.ObjectIdField, required=False) protocolId = fields.StrField(required=True) protocolName = fields.StrField(required=False) sopFileName = fields.StrField(required=False) specLibFilename = fields.StrField(required=False) description = fields.StrField(required=False) proteinDatabaseOrganism = fields.StrField(required=True) proteinDatabaseVersion = fields.StrField(required=True) workflowTag = fields.StrField(required=False) createdDate = fields.DateTimeField( validate=validate.Range(min=datetime(1900, 1, 1))) updatedDate = fields.DateTimeField( validate=validate.Range(min=datetime(1900, 1, 1))) class Meta: collection_name = "SpectralLibrary"
class CafeEmployeeDocument(Document): username = fields.StringField(required=True, unique=True, validate=[Length(min=6, max=60)]) password = fields.StringField(required=True) cafe = fields.ObjectIdField(required=True) token = fields.StringField(required=True) @staticmethod def hash_password(password): return sha256(password.encode('UTF-8')).hexdigest() @classmethod async def find_user_by_credentials(cls, username, password): if not username or not password: return None hashed_password = cls.hash_password(password) return await cls.find_one({ 'username': username, 'password': hashed_password })
class User(Document): # pylint: disable=abstract-method """ A user in the private database. """ token = fields.StrField(required=True, unique=True, validate=validate.Length(equal=64)) # The following 4 values could be unconfigured # Since the server only updates these after it validates credentials, # if both login and password exist, they're guaranteed to be valid credentials login = fields.StrField(required=False, unique=True, validate=validate.Regexp(r"\d+")) password = BinaryField(required=False) # Populated when credentials are set/updated # A value of null indicates either credentials are unset, # or the courses are in the process of being populated # An empty array indicates no courses found courses = fields.ListField(fields.ObjectIdField(), required=False, allow_none=True) # Should be set as soon as valid credentials are detected email = fields.EmailField(required=False, allow_none=True) active = fields.BoolField(default=True) errors = fields.ListField(fields.EmbeddedField(LockboxFailure), default=[]) last_fill_form_result = fields.EmbeddedField(FillFormResult, default=None, allow_none=True) grade = fields.IntField(required=False, allow_none=True, default=None) first_name = fields.StrField(required=False, allow_none=True, default=None, validate=lambda s: s is None or len(s)) last_name = fields.StrField(required=False, allow_none=True, default=None, validate=lambda s: s is None or len(s))
class Doc(Document): id = fields.ObjectIdField(attribute='_id') ref = fields.ReferenceField('Doc') gen_ref = fields.GenericReferenceField()
class Member(Document): class Meta: strict = False # General id = fields.IntegerField(attribute="_id") joined_at = fields.DateTimeField(default=None) suspended = fields.BooleanField(default=False) # Pokémon next_idx = fields.IntegerField(default=1) selected_id = fields.ObjectIdField(required=True) order_by = fields.StringField(default="number") # Pokédex pokedex = fields.DictField(fields.StringField(), fields.IntegerField(), default=dict) shinies_caught = fields.IntegerField(default=0) # Shop balance = fields.IntegerField(default=0) premium_balance = fields.IntegerField(default=0) redeems = fields.IntegerField(default=0) redeems_purchased = fields.DictField(fields.IntegerField(), fields.IntegerField(), default=dict) embed_colors = fields.IntegerField(default=0) # Shiny Hunt shiny_hunt = fields.IntegerField(default=None) shiny_streak = fields.IntegerField(default=0) # Boosts boost_expires = fields.DateTimeField(default=datetime.min) shiny_charm_expires = fields.DateTimeField(default=datetime.min) # Voting last_voted = fields.DateTimeField(default=datetime.min) need_vote_reminder = fields.BooleanField(default=False) vote_total = fields.IntegerField(default=0) vote_streak = fields.IntegerField(default=0) gifts_normal = fields.IntegerField(default=0) gifts_great = fields.IntegerField(default=0) gifts_ultra = fields.IntegerField(default=0) gifts_master = fields.IntegerField(default=0) # Settings show_balance = fields.BooleanField(default=True) silence = fields.BooleanField(default=False) # Events halloween_tickets = fields.IntegerField(default=0) hquests = fields.DictField(fields.StringField(), fields.BooleanField(), default=dict) hquest_progress = fields.DictField(fields.StringField(), fields.IntegerField(), default=dict) halloween_badge = fields.BooleanField(default=False) @property def selected_pokemon(self): try: return next( filter(lambda x: x.number == int(self.selected), self.pokemon)) except StopIteration: return None @property def boost_active(self): return datetime.utcnow() < self.boost_expires @property def shiny_charm_active(self): return datetime.utcnow() < self.shiny_charm_expires @property def shiny_hunt_multiplier(self): # NOTE math.log is the natural log (log base e) return 1 + math.log(1 + self.shiny_streak / 30) def determine_shiny(self, species): chance = 1 / 4096 if self.shiny_charm_active: chance *= 1.2 if self.shiny_hunt == species.dex_number: chance *= self.shiny_hunt_multiplier return random.random() < chance
class PokemonBase(MixinDocument): class Meta: strict = False abstract = True # General id = fields.ObjectIdField(attribute="_id") timestamp = fields.DateTimeField(default=datetime.utcnow) owner_id = fields.IntegerField(required=True) idx = fields.IntegerField(required=True) # Details species_id = fields.IntegerField(required=True) level = fields.IntegerField(required=True) xp = fields.IntegerField(required=True) nature = fields.StringField(required=True) shiny = fields.BooleanField(required=True) # Stats iv_hp = fields.IntegerField(required=True) iv_atk = fields.IntegerField(required=True) iv_defn = fields.IntegerField(required=True) iv_satk = fields.IntegerField(required=True) iv_sdef = fields.IntegerField(required=True) iv_spd = fields.IntegerField(required=True) iv_total = fields.IntegerField(required=False) # Customization nickname = fields.StringField(default=None) favorite = fields.BooleanField(default=False) held_item = fields.IntegerField(default=None) moves = fields.ListField(fields.IntegerField, default=list) has_color = fields.BooleanField(default=False) color = fields.IntegerField(default=None) _hp = None ailments = None stages = None def __format__(self, spec): if self.shiny: name = "✨ " else: name = "" if "l" in spec: name += f"Level {self.level} " elif "L" in spec: name += f"L{self.level} " if "p" in spec: name += f"{self.iv_percentage:.2%} " if self.bot.sprites.status and "i" in spec: sprite = self.bot.sprites.get(self.species.dex_number, shiny=self.shiny) name = sprite + " " + name name += str(self.species) if self.nickname is not None and "n" in spec: name += ' "' + self.nickname + '"' if self.favorite and "f" in spec: name += " ❤️" return name def __str__(self): return f"{self}" @classmethod def random(cls, **kwargs): ivs = [random_iv() for i in range(6)] return cls( iv_hp=ivs[0], iv_atk=ivs[1], iv_defn=ivs[2], iv_satk=ivs[3], iv_sdef=ivs[4], iv_spd=ivs[5], iv_total=sum(ivs), nature=random_nature(), shiny=random.randint(1, 4096) == 1, **kwargs, ) @property def species(self): return self.bot.data.species_by_number(self.species_id) @property def max_xp(self): return 250 + 25 * self.level @property def max_hp(self): if self.species_id == 292: return 1 return ((2 * self.species.base_stats.hp + self.iv_hp + 5) * self.level // 100 + self.level + 10) @property def hp(self): if self._hp is None: return self.max_hp return self._hp @hp.setter def hp(self, value): self._hp = value @property def atk(self): return calc_stat(self, "atk") @property def defn(self): return calc_stat(self, "defn") @property def satk(self): return calc_stat(self, "satk") @property def sdef(self): return calc_stat(self, "sdef") @property def spd(self): return calc_stat(self, "spd") @property def iv_percentage(self): return (self.iv_hp / 31 + self.iv_atk / 31 + self.iv_defn / 31 + self.iv_satk / 31 + self.iv_sdef / 31 + self.iv_spd / 31) / 6 def get_next_evolution(self, is_day): if self.species.evolution_to is None or self.held_item == 13001: return None possible = [] for evo in self.species.evolution_to.items: if not isinstance(evo.trigger, models.LevelTrigger): continue can = True if evo.trigger.level and self.level < evo.trigger.level: can = False if evo.trigger.item and self.held_item != evo.trigger.item_id: can = False if evo.trigger.move_id and evo.trigger.move_id not in self.moves: can = False if evo.trigger.move_type_id and not any([ self.bot.data.move_by_number(x).type_id == evo.trigger.move_type_id for x in self.moves ]): can = False if evo.trigger.time == "day" and not is_day or evo.trigger.time == "night" and is_day: can = False if evo.trigger.relative_stats == 1 and self.atk <= self.defn: can = False if evo.trigger.relative_stats == -1 and self.defn <= self.atk: can = False if evo.trigger.relative_stats == 0 and self.atk != self.defn: can = False if can: possible.append(evo.target) if len(possible) == 0: return None return random.choice(possible) def can_evolve(self, ctx): return self.get_next_evolution() is not None
class Parent(Document): id = fields.ObjectIdField(attribute='_id', default=ObjectId) name = fields.StrField()