class TodoItem(Model, MongoCollectionMixin): _id = ObjectIdField(primary_key=True) user = DBRefField(User, required=True) state = IntegerField(default=0, choices=[0, 1, 2, 3, 4, 5]) priority = IntegerField(default=0, choices=[0, 1, 2]) text = StringField(required=True) due = DateTimeField()
class Room(BaseModel): name = StringField(primary_key=True) title = StringField() default = BooleanField( default=False ) # new users will be added to this channel as they join in active = BooleanField(default=True) access = IntegerField( default=ACCESS_PUBLIC, choices=[ACCESS_PUBLIC, ACCESS_PROTECTED, ACCESS_PRIVATE]) owner = DBRefField(User, required=True) members = ListField(DBRefField(User), default=[]) class Meta: name = 'rooms' indices = [{ 'name': '_name', 'fields': [('name', ASCENDING)], 'unique': True }] async def add_member(self, db, user): ''' Adds a new user to the list of room members, if memeber doesn't exist already ''' # use model's pk as query query = {self.primary_key: self.pk} # push review result = await db[self.get_collection_name()].update_one( filter=query, update={ '$addToSet': { 'members': DBRefField(User).to_python(user) } }, ) return result async def remove_member(self, db, user): pass
async def add_member(self, db, user): ''' Adds a new user to the list of room members, if memeber doesn't exist already ''' # use model's pk as query query = {self.primary_key: self.pk} # push review result = await db[self.get_collection_name()].update_one( filter=query, update={ '$addToSet': { 'members': DBRefField(User).to_python(user) } }, ) return result
class Session(Model, MongoCollectionMixin): _id = ObjectIdField(projection=None) created = DateTimeField(default=datetime.datetime.utcnow()) token = StringField(primary_key=True) user = DBRefField(User, required=True) class Meta: namespace = 'account' name = 'sessions' indices = [{ 'name': '_token', 'fields': [('token', ASCENDING)], }, { 'name': '_user', 'fields': [('user', ASCENDING)], 'unique': True }, { 'name': '_created', 'fields': [('created', ASCENDING)], 'expireAfterSeconds': TOKEN_EXPIRY }] @classmethod async def get_or_create(cls, db, user: User): ''' Find or create a token for given user. Do not use ``insert`` or ``create`` directly but rather this method. Token automatically expires after TOKEN_EXPIRE ''' user_ref = DBRefField(User).to_python(user) token_data = await db[cls.get_collection_name()].find_one_and_update( filter={'user': user_ref}, update={ '$set': { 'user': user_ref }, '$setOnInsert': { 'token': uuid.uuid4().hex, 'created': datetime.datetime.utcnow() } }, upsert=True, return_document=True) if token_data: return cls.create_model(token_data) return None
class Entry(BaseModel): user = DBRefField(User, required=True) room = StringField(required=True) text = StringField(required=True) class Meta: name = 'entries' creation_args = { 'capped': True, 'max': CAPACITY, 'size': CAPACITY * ENTRY_SIZE } indices = [{ 'name': '_user', 'fields': [('user', ASCENDING)], }, { 'name': '_room', 'fields': [('room', ASCENDING)], }]
async def get_or_create(cls, db, user: User): ''' Find or create a token for given user. Do not use ``insert`` or ``create`` directly but rather this method. Token automatically expires after TOKEN_EXPIRE ''' user_ref = DBRefField(User).to_python(user) token_data = await db[cls.get_collection_name()].find_one_and_update( filter={'user': user_ref}, update={ '$set': { 'user': user_ref }, '$setOnInsert': { 'token': uuid.uuid4().hex, 'created': datetime.datetime.utcnow() } }, upsert=True, return_document=True) if token_data: return cls.create_model(token_data) return None
class UserAction(Model, MongoCollectionMixin): USER_ACTION_CHOICES = ( (0, 'Unknown'), (1, 'Activate'), (2, 'Reset Password'), (2, 'Reset Passcode'), (4, 'Change Email Address'), ) USER_ACTION_STATE_CHOICES = ( (0, 'Active'), (1, 'Completed'), (1, 'Expired'), ) _id = ObjectIdField(projection=None) key = StringField(primary_key=True) user = DBRefField(User, required=True) action = IntegerField(choices=[x for x, _ in USER_ACTION_CHOICES]) state = IntegerField(default=0, choices=[x for x, _ in USER_ACTION_STATE_CHOICES]) class Meta: name = 'user_actions' namespace = 'account' indices = [{ 'name': '_user_and_action', 'fields': [('user', ASCENDING), ('action', ASCENDING)], 'unique': True, # 'partialFilterExpression': {'action': {'$ne': 0}} # unique if action is active }] @classmethod def create_apikey(cls, username): salt = hashlib.sha1(str( random.random()).encode('utf-8')).hexdigest()[:5] return hashlib.sha1((salt + username).encode('utf-8')).hexdigest()