class Gallery(db.Document): gid = db.StringField(primary_key=True, unique=True) title = db.StringField() user = db.ReferenceField(User) pub_date = db.DateTimeField(default=datetime.now) @classmethod def pre_delete(cls, sender, document, **kwargs): for image in document.images: image.gallery.remove(document) image.save() @property def images(self): return Image.objects(gallery=self.gid).order_by('-pub-date') def __unicode__(self): return self.title
class Collect(db.Document): """ 书籍/书单收藏模型 """ user = db.ReferenceField(User) type = db.StringField() # 表示是书籍还是书单 ['book', 'booklist'] type_id = db.StringField() time = db.IntField(required=True, default=time_int) @classmethod def sum(cls, object_instance): if isinstance(object_instance, Book): return cls.objects(type="book", type_id=object_instance.isbn).count() elif isinstance(object_instance, BookList): return cls.objects(type="booklist", type_id=str(object_instance.pk)).count() return 0
class Notification(db.Document): user = db.ReferenceField('User', required=True) msg = db.StringField(required=True) date = db.DateTimeField(default=datetime.now()) seen = db.BooleanField(default=False) hash = db.StringField(required=True, unique=True) def clean(self): hash = self.user.id + \ str(self.msg) + \ str(self.date) + \ str(self.seen) self.hash = md5(hash.encode('utf-8')).hexdigest() def __repr__(self): return '<Notification %r>' % (self.id)
class EventSeries(db.Document): """""" date_created = db.DateTimeField(required=True, default=now) date_modified = db.DateTimeField(required=True, default=now) slug = db.StringField(required=True, max_length=255) events = db.ListField(db.ReferenceField("Event")) frequency = db.StringField(default="weekly") every = db.IntField(min_value=1, max_value=30) ends_after = db.BooleanField(default=True) ends_on = db.BooleanField(default=False) num_occurances = db.IntField(default=1) recurrence_end_date = DateField() recurrence_summary = db.StringField() gcal_id = db.StringField() # ID of the first event in the series def delete_one(self, event): """""" self.events.remove(event) event.delete() self.save() def delete_all_except(self, event): """""" for e in self.events[:]: if e != event: e.delete() event.parent_series = None self.delete() def delete_all(self): """""" for e in self.events: e.delete() self.delete() def clean(self): """Update date_modified, and ensure that exactly one of `ends_after` and `ends_on` is True at a time. """ self.date_modified = now() if self.ends_after == self.ends_on: raise ValidationError("ends_on and ends_after should not share a " "value.")
class Recipe(db.DynamicDocument): title = db.StringField(max_length=120, required=True) author = db.ReferenceField(User, reverse_delete_rule=CASCADE) # image of the recipe # img = db.FileField(required=True) # description of the recipe desc = db.StringField(max_length=200, required=True) # ingredient ing = db.StringField(max_length=200, required=True) # step?? step = db.StringField(required=True) prl = db.StringField(required=True) rid = db.SequenceField(required=True) region = db.StringField(max_length=40, required=True) ming = db.StringField(max_length=40, required=True) kind = db.StringField(max_length=40, required=True) works = db.ListField(ReferenceField(Dish)) ts = db.DateTimeField(default=datetime.datetime.now) rate = db.DecimalField(default=0.0,precision=1) ppl = db.IntField(default=1) def get_recipe(): return Recipe.objects().first() @staticmethod def generate_fakes(): import json from random import seed, randint import os counts = User.objects.count() path_to_fakes = url_for("static",filename="fakes/recipes/recipes.json") basedir = os.path.abspath(os.path.dirname(__file__)) static_path = basedir+path_to_fakes recipes = json.load(open(static_path)) for recipe in recipes: r = Recipe.from_json(recipe) while 1: try: r.author = User.objects(id=randint(0,counts-1)).first() break except: continue r.save(force_insert=True)
class Bookmark(db.Document): user = db.ReferenceField(User, required=True) url = db.StringField(required=True) title = db.StringField() description = db.StringField() public = db.BooleanField(default=False) tags = db.ListField(db.StringField()) created_at = db.DateTimeField(default=datetime.datetime.now, required=True) updated_at = db.DateTimeField(required=False) meta = {'ordering': ['-updated_at', '-created_at']} def fetch(self): html = requests.get(self.url).text if html: extracted = extraction.Extractor().extract(html, source_url=self.url) self.title = extracted.title self.description = extracted.description self.updated_at = datetime.datetime.now return True return False def to_dict(self): return { 'id': str(self.id), 'url': self.url, 'title': self.title, 'description': self.description, 'tags': self.tags if self.tags else ['Video', 'Web page', 'Article', 'News'], 'user': str(self.user.id) if self.user else None, 'created_at': str(self.created_at), 'updated_at': str(self.updated_at) if self.updated_at else None }
class Inventory(db.Document): operation = db.IntField(db_field='on', verbose_name='Tip operatie', required=True) # 1 for buying, 2 for selling product = db.ReferenceField('Products', db_field='sk', verbose_name='Produs', required=True) number = db.IntField(db_field='nb', verbose_name='Numar produse', required=True) timestamp = db.DateTimeField(db_field='tm', verbose_name='Data operatie', required=True) reference = db.StringField(db_field='rf', verbose_name='Referinta') operator = db.GenericReferenceField(db_field='op', verbose_name='Operator', required=True)
class StudentSubmissionList(db.EmbeddedDocument): ''' A list of all the submissions a student has made for a specific problem. ''' submissions = db.ListField(db.ReferenceField('Submission')) meta = {"cascade": True} def cleanup(self): for s in self.submissions: s.cleanup() s.delete() self.submissions = [] def addSubmission(self, sub): if len(self.submissions) > 0: self.submissions[-1].isLatest = False self.submissions[-1].save() self.submissions.append(sub)
class User(db.Document): username = db.StringField() password = db.StringField() email = db.EmailField() doc_sequence = db.ReferenceField('Sequence_old') def is_authenticated(self): return True def is_active(self): return True def is_anonymous(self): return False def get_id(self): return unicode(self.id) '''def __init__(self, username, password, email):
class Notice(db.Document): """ 通知模型 """ title = db.StringField(required=True) content = db.StringField(required=True) url = db.StringField() create_time = db.IntField(default=time_int) is_read = db.BooleanField(default=False) read_time = db.IntField() user = db.ReferenceField(User, required=True) def read(self): self.is_read = True self.read_time = time_int() self.save() return True
class Recipe(db.DynamicDocument): title = db.StringField(max_length=120, required=True) author = db.ReferenceField(User, reverse_delete_rule=CASCADE) prl = db.StringField(required=True) desc = db.StringField(max_length=200, required=True) ing = db.StringField(max_length=200, required=True) step = db.StringField(required=True) region = db.StringField(max_length=40, required=True) ming = db.StringField(max_length=40, required=True) kind = db.StringField(max_length=40, required=True) works = db.ListField(ReferenceField(Dish)) ts = db.DateTimeField(default=datetime.datetime.now) rate = db.DecimalField(default=0.0, precision=1) ppl = db.IntField(default=1) def get_recipe(): return Recipe.objects().first()
class Sign(db.Document): create_datetime = db.DateTimeField() # 签到时间 typ = db.StringField() # 签到类型,分为'n'正常签到和's'换班签到 week = db.IntField() # 签到周 user = db.ReferenceField(User,reverse_delete_rule=2) def create(user: User, typ: str, week: int) -> bool: print(user) last_sign = Sign.objects(user=user).order_by('create_datetime').first() if last_sign: if int(last_sign.create_datetime.timestamp() / 7200) != int(datetime.datetime.now().timestamp() / 7200): # 卡两个小时内多次签到的情况 s = Sign(user=user.id,create_datetime=datetime.datetime.now(), typ=typ, week=week) last_sign = s s.save() user.save() return True else: return False else: s = Sign(user=user.id,create_datetime=datetime.datetime.now(), typ=typ, week=week) last_sign = s s.save() user.save() return True def get_by_id(id): return Sign(id=id).first() def get_by_user(user:User) -> dict: return {"signs":[i.get_base_info() for i in Sign.objects(user=user)]} def get_base_info(self) -> dict: return { "id": str(self.id), "create_datetime": self.create_datetime, "week": self.week, "typ": self.typ, "user": self.user }
class Users(db.Document): username = db.StringField(max_length=50, required=True, unique=True) password = db.StringField(max_length=128, required=True) saltGenerator = ''.join( random.SystemRandom().choice(string.ascii_uppercase + string.digits) for _ in range(20)) salt = db.StringField(default=saltGenerator, max_length=20, required=True) userRole = db.StringField(max_length=20, required=True, default="User") userEmail = db.EmailField(required=True) userDescription = db.StringField(default="Undefined", max_length=255, required=False) userProjects = db.ListField(db.ReferenceField('Projects')) userMacros = db.EmbeddedDocumentListField('Macros') userMessages = db.ListField(db.StringField(max_length='1000')) meta = { 'ordering': ['-username'], } def clean(self): if self.username == "" or self.password == "" or self.userEmail == "": msg = "Unable to add empty username and/or password" raise ValidationError(msg) @property def is_authenticated(self): return True @property def is_active(self): return True @property def is_anonymous(self): return False def get_id(self): return self.username
class album(db.Document): id = db.UUIDField() albumtitle = db.StringField(required=False, unique=True) albumartist = db.ReferenceField(artist) musicbrainz_albumartistid = db.StringField() musicbrainz_albumid = db.StringField() coverimage = db.ImageField() def get_coverart_url(self): path = "app/static/media/" filename = "%s.jpg" % self.id if not self.coverimage.size: raise NameError("No image in DB") imgdata = self.coverimage.read() if not imgdata: raise NameError("No image in DB") b_imagedata = bytes(imgdata) output = open("%s%s" % (path, filename), "wb") output.write(b_imagedata) return filename
class GBColumn(db.Document): ''' A column represents a single list of entries. It can be a single problem or one days participation, or one test. ''' name = db.StringField() maxScore = db.DecimalField(default=0) #Map usernames to grade entries scores = db.MapField(db.ReferenceField('GBGrade')) def __init__(self, name, **data): super(GBColumn, self).__init__(**data) self.name = name def getUserScore(self, user): '''Returns a single user grade''' return self.scores[user.keyOfUsername()].totalScore() def cleanup(self): pass
class Purchase(db.Document): billings = db.ListField(db.ReferenceField(Billing)) operator = db.StringField(required=True) warehouse = db.StringField(required=True) source = db.StringField(required=True) create_time = db.IntField(required=True, default=time_int) def price(self): price_sum = 0 for one in self.billings: price_sum += one.get_sum_price() return price_sum def price_real(self): price_sum = 0 for billing in self.billings: for cart in billing.carts: price_sum += cart.real_price return price_sum
class EntrySpec(db.Document): meta = {'db_alias': 'db_cart', 'indexes': ['sku', 'item_id']} # 唯一标识 sku = db.IntField(required=True, unique=True) item_id = db.IntField() title = db.StringField() primary_image = db.StringField() item_available = db.BooleanField() price = db.FloatField() available = db.BooleanField() attributes = db.DictField() images = db.ListField(db.StringField()) attribute_list = db.ListField(db.StringField()) attribute_desc = db.DictField() brand = db.DictField() last_update_date = db.DateTimeField() carts = db.ListField(db.ReferenceField('Cart')) last_empty_date = db.DateTimeField()
class GBGroup(db.Document): ''' Entries are designed to contain columns that are temporall related. Such as all of the problems in a certain week. (This level of granularity isn't accessible in the manual gradebook, this may be a source of a refactor) ''' name = db.StringField(required=True) columns = db.ListField(db.ReferenceField('GBColumn', reverse_delete_rule=PULL)) def __init__(self, name, **data): super(GBGroup, self).__init__(**data) self.name = name def cleanup(self): for c in self.columns: c.cleanup() c.delete() def getWidth(self): return max(len(self.columns), 1) def getHeight(self): return max(len(self.columns)+1, 1)
class User(db.Document): email = db.EmailField(unique=True) first_name = db.StringField(max_length=35, default='') last_name = db.StringField(max_length=35, default='') password = db.StringField(default=True) active = db.BooleanField(default=True) isAdmin = db.BooleanField(default=False) timestamp = db.DateTimeField(default=datetime.datetime.now()) starred_rooms = db.ListField(db.ReferenceField('Room')) def __unicode__(self): return self.email def to_json_dict(self): data = self.to_mongo() data['_id'] = str(data['_id']) data['timestamp'] = time.mktime(data['timestamp'].timetuple()) return { '_id': str(self.id), 'email': self.email, 'first_name': self.first_name, 'last_name': self.last_name } def is_active(self): return self.active def get_id(self): return self.id def is_authenticated(self): return True def set_password(self, plaintext_password): self.password = bcrypt.generate_password_hash(plaintext_password) self.save()
class Team(db.Document): MAX_NAME_LENGTH = 30 DIVISIONS = ( ('1', 'Upper Division'), ('2', 'Lower Division'), ) team_name = db.StringField() # For joining the team in the db teamID = db.StringField(required=True, unique=True) teamPass = db.StringField(required=True) # Password for domjudge domPass = db.StringField(required=True) # Division field division = db.IntField(required=False) # List of participants on team members = db.ListField(db.ReferenceField('Account'), null=True) # Block editing shadowban = db.BooleanField() def __repr__(self): if self.team_name is not None: return '<Team %r>' % self.team_name else: return super(Team, self).__repr__() def __str__(self): if self.team_name: return self.team_name else: return ""
class OngDocument(db.Document): createdAt = db.DateTimeField(default=datetime.datetime.now) updatedAt = db.DateTimeField(default=datetime.datetime.now) name = db.StringField(required=True) description = db.StringField() phone1 = db.StringField() phone2 = db.StringField() email = db.StringField() address = db.DictField() addressNumber = db.StringField() tasks = db.ListField(db.ReferenceField(TaskDocument, reverse_delete_rule=mongoengine.PULL)) # purpose = db.StringField() # site = db.StringField() # logoUrl = db.StringField() indexes = { 'tasks': tasks } def to_dict(self): return { 'id': str(self.id), '_id': str(self.id), 'createdAt': self.createdAt.strftime("%Y-%m-%d %H:%M:%S"), 'updatedAt': self.updatedAt.strftime("%Y-%m-%d %H:%M:%S"), 'name': self.name, 'description': self.description, 'purpose': self.purpose, 'phone1': self.phone1, 'phone2': self.phone2, 'email': self.email, 'site': self.site, 'address': self.address, 'addressNumber': self.addressNumber, 'logoUrl': self.logoUrl, 'tasks': json.dumps([t.to_dict() for t in self.tasks]) }
class Alert(db.Document): user = db.ReferenceField('User', required=True) active = db.BooleanField(required=True, default=True) date = db.DateTimeField(required=True, default=datetime.now()) method = db.StringField(required=True) method_data = db.StringField(required=True) cryptocurrency = db.StringField(required=True, default="BTC") price_direction = db.StringField(required=True, choices=constants.PRICE_DIRECTIONS) price = db.FloatField(required=True, default=0.0) currency = db.StringField(required=True, choices=constants.CURRENCIES) exchange = db.StringField(required=True, choices=constants.EXCHANGES) note = db.StringField() resend_after = db.IntField(required=True, default=21600) #6hrs notify_only_once = db.BooleanField(required=True, default=True) notify_times = db.IntField(required=True, default=0) notify_date = db.DateTimeField(required=False) hash = db.StringField(required=True, unique=True) def clean(self): hash = self.user.email + \ str(self.date) + \ str(self.method) + \ str(self.method_data) + \ str(self.cryptocurrency) + \ str(self.price_direction) + \ str(self.price) + \ str(self.currency) + \ str(self.exchange) + \ str(self.note) + \ str(self.resend_after) + \ str(self.notify_only_once) self.date = datetime.now() self.hash = md5(hash.encode('utf-8')).hexdigest() def __repr__(self): return '<Alert %r>' % (self.id)
class Pet(db.Document): external_id = db.StringField(db_field='ei') name = db.StringField(db_field='n') species = db.StringField(db_field='s') breed = db.StringField(db_field='b') age = db.IntField(db_field='a') store = db.ReferenceField(Store, db_field='st') price = db.DecimalField( db_field='p', precision=2, rounding='ROUND_HALF_UP' ) sold = db.BooleanField(db_field='sl', default=False) received_date = db.DateTimeField(db_field='rd') sold_date = db.DateTimeField(db_field='sd') live = db.BooleanField(db_field='l', default=True) meta = { 'indexes': [ ('external_id', 'live'), ('species', 'breed', 'live'), ('store', 'live') ] }
class ItemDB(db.Document): """The fields for the item that would be saved to the database""" item_id = db.StringField(required=True) store_id = db.StringField(db_field='si', required=True, default='') alert_id = db.StringField(db_field='ai') url = db.URLField(db_field='u', required=True, unique=True) item_name = db.StringField(db_field='in', required=True) item_image = db.StringField(db_field='i') item_description = db.StringField(db_field='d') user_email = db.StringField(db_field='ue', required=True) alert_added = db.BooleanField(db_field='aa', default=False) store = db.ReferenceField(StoresDB, reverse_delete_rule=CASCADE) creation_date = db.DateTimeField(db_field='cd', default=time_now()) alert_deleted = db.BooleanField(db_field='ad', default=False) @classmethod def pre_save(cls, sender, document, **kwargs): """A pre-save function that is called before any item is saved""" document.item_name = document.item_name.lower() document.url = document.url.lower() meta = { 'indexes': ['url', 'user_email', 'alert_added', 'store', 'item_id'] }
class User(db.Document): id = db.SequenceField(primary_key=True) email = db.StringField(required=True,unique=True,index=True) username = db.StringField(max_length=50,required=True,index=True) p_hash = db.StringField(max_length=128,required=True) confirmed = db.BooleanField(default=False) role = db.ReferenceField(Role) last_seen = db.DateTimeField(default=datetime.datetime.now) avatar = db.StringField(default=None) recipe = db.ListField(ReferenceField('Recipe')) dish = db.ListField(ReferenceField('Dish')) def __init__(self,**kwargs): super(User, self).__init__(**kwargs) if self.role is None: if self.email == current_app.config['FY_ADMIN']: self.role = Role.objects(name='Admin').first() else: self.role = Role.objects(default=True).first() if self.avatar is None: self.avatar = "users/"+str(self.id)+".png" @property def password(self): raise AttributeError('password is not a readable attribute') @password.setter def password(self, password): self.p_hash = generate_password_hash(password) def verify_password(self, password): return check_password_hash(self.p_hash, password) # Flask-Login integration def is_authenticated(self): return True def is_active(self): return True def is_anonymous(self): return False def get_id(self): return str(self.id) def generate_confirmToken(self, expiration=3600): s = Serializer(current_app.config['SECRET_KEY'],expiration) return s.dumps({'confirm':self.id}) def confirm(self, token): s = Serializer(current_app.config['SECRET_KEY']) try: data = s.loads(token) except: return False if data.get('confirm') != self.id: return False self.confirmed = True self.save() return True def to_json(self): user = { 'username':self.username, 'last_seen':self.last_seen, 'recipe_created': url_for('api.get_user_recipe', id=self.id, _external=True), 'dish_created': url_for('api.get_user_dish', id=self.id, _external=True), 'num_of_uploads': len(self.recipe) + len(self.dish) } return user @staticmethod def generate_fakes(): import forgery_py import os from random import seed # insert admin admin = User(email=current_app.config['FY_ADMIN'],username='******') admin.password = "******" admin.confirmed = True admin.save() seed() path_to_fakes = url_for("static",filename="fakes/users") basedir = os.path.abspath(os.path.dirname(__file__)) static_path = basedir+path_to_fakes for file in os.listdir(static_path): user = User(email=forgery_py.internet.email_address(), username=forgery_py.internet.user_name(True), confirmed=True, avatar=os.path.join("fakes/users",file)) user.password = forgery_py.lorem_ipsum.word() try: user.save() except: current_app.logger.info("something went wrong...") def is_permitted(self, permission): return self.role is not None and self.role.is_permitted(permission) def is_admin(self): return self.is_permitted(Permission.ADMIN) def ping(self): self.last_seen = datetime.datetime.now self.save()
class Recipe(db.DynamicDocument): title = db.StringField(max_length=120, required=True) author = db.ReferenceField(User, reverse_delete_rule=CASCADE) desc = db.StringField(max_length=500, required=True) ing = db.StringField(max_length=1000, required=True) step = db.StringField(required=True) prl = db.StringField(required=True) rid = db.SequenceField(required=True) region = db.StringField(max_length=40, required=True) ming = db.StringField(max_length=40, required=True) kind = db.StringField(max_length=40, required=True) works = db.ListField(ReferenceField(Dish)) ts = db.DateTimeField(default=datetime.datetime.now) rate = db.DecimalField(default=0.0,precision=1) ppl = db.IntField(default=1) def to_json(self): recipe = { 'url':url_for('api.get_recipe',recipe_id = self.rid, _external=True), 'title':self.title, 'author_id':self.author.id, 'description':self.desc, 'ingredients':self.ing, 'steps':self.step, 'img_url':url_for('static',filename=self.prl,_external =True), 'tags':[self.region,self.ming,self.kind], 'date_created':self.ts, 'rate':str(self.rate), 'people_rated':self.ppl } return recipe @staticmethod def from_json_custom(recipe): title = recipe.get('title') desc = recipe.get('desc') ing = recipe.get('ing') prl = recipe.get('prl') step = recipe.get('step') tags = recipe.get('tags') if tags: region=tags[0] ming = tags[1] kind = tags[2] if title is None or\ desc is None or step is None or\ ing is None or prl is None or\ region is None or ming is None or kind is None: raise ValueError('field missing') recipe = Recipe(title=title,ing=ing,prl=prl,desc=desc,step=step, region=region,ming=ming,kind=kind) return recipe @staticmethod def generate_fakes(): import json from random import seed, randint import os seed() counts = User.objects.count() path_to_fakes = url_for("static",filename="fakes/recipes/recipes.json") basedir = os.path.abspath(os.path.dirname(__file__)) static_path = basedir+path_to_fakes print (static_path) recipes = json.load(open(static_path,encoding='utf-8')).get('recipes') # print (recipes) for recipe in recipes: print (json.dumps(recipe)) r = Recipe.from_json(json.dumps(recipe)) users_count = User.objects.count() offset = randint(0,users_count-1) print (offset) user = User.objects[offset:].first() print (user.id) r.author = user r.save(force_insert=True)
class Access(db.Document): app = db.ReferenceField(App, db_field='a') token = db.StringField(db_field='t') expires = db.DateTimeField(db_field='e')
class User(UserMixin, db.Document): first_name = db.StringField() last_name = db.StringField() password = db.StringField() email = db.StringField() avatar = db.StringField() titles_liked = db.ListField(db.ReferenceField('Title')) titles_disliked = db.ListField(db.ReferenceField('Title')) genres_liked = db.ListField(db.ReferenceField('Genre')) meta = {'collection': 'User'} def set_password(self, password): self.password = generate_password_hash(password) def check_password(self, password): return check_password_hash(self.password, password) def get_id(self): return str((self.id)) def fullname(self): return self.first_name + " " + self.last_name ''' se il parametro like è True allora è un like altrimenti un dislike ''' def manage_titles(self, title, like=True): if like == True: if self.has_liked_title(title): self.update(pull__titles_liked=title) else: self.update(pull__titles_disliked=title) self.titles_liked.append(title) else: if self.has_disliked_title(title): self.update(pull__titles_disliked=title) else: self.update(pull__titles_liked=title) self.titles_disliked.append(title) self.save() def search_titles_disliked(self, title): for t in self.titles_disliked: if t.id == title.id: return t return None def has_disliked_title(self, title): return (self.search_titles_disliked(title) != None) def search_titles_liked(self, title): for t in self.titles_liked: if t.id == title.id: return t return None def has_liked_title(self, title): return (self.search_titles_liked(title) != None) def genres_liked_as_string(self): return '/'.join(str(genre.name) for genre in self.genres_liked) def titles_liked_as_id(self): titles_id = [] for title in self.titles_liked: titles_id.append(title.id) return titles_id def titles_disliked_as_id(self): titles_id = [] for title in self.titles_disliked: titles_id.append(title.id) return titles_id @staticmethod def register(form): email = form.email.data if User.get_by_email(email) is not None: raise Exception("Email già registrata") nUser = User() nUser.first_name = form.first_name.data nUser.last_name = form.last_name.data nUser.email = form.email.data nUser.set_password(form.password.data) nUser.about_me = "" nUser.save() return nUser @staticmethod def login(email, password): user = User.get_by_email(email) if user is None: raise Exception("Email non registrata") if password.strip() == "": raise Exception("Password non inserita") if not user.check_password(password): raise Exception("Password errata") return user @staticmethod def facebook_login(email, fullname): user = User.get_by_email(email) if user is None: names = fullname.split() user = User(first_name=names[0], last_name=names[len(names) - 1], email=email) user.save() return user @staticmethod def get_by_email(email): return User.objects.filter(email=email).first() def get_reset_password_token(self, expires_in=600): return jwt.encode( { 'reset_password': self.get_id(), 'exp': time() + expires_in }, current_app.config['SECRET_KEY'], algorithm='HS256').decode('utf-8') @staticmethod def get_by_id(id): return User.objects.get(id=id) @staticmethod def verify_reset_password_token(token): try: id = jwt.decode(token, app.config['SECRET_KEY'], algorithms=['HS256'])['reset_password'] except: return return User.get_by_id(id)
class Collect(db.Document): timestamp_start = db.DateTimeField(default=datetime.utcnow) timestamp_end = db.DateTimeField() # samples = db.ListField(db.ReferenceField('Sample'), default=list) equipment = db.ReferenceField('Equipment') patient = db.ReferenceField('Patient')
class EventSeries(db.Document): """A model that stores the recurrence information for a recurring event series. :ivar date_created: :class:`mongoengine.fields.DateTimeField` - The date when the series was created. :ivar date_modified: :class:`mongoengine.fields.DateTimeField` - The date when the series was last modified :ivar slug: :class:`mongoengine.fields.StringField` - The URL slug for this event. **Note:** this slug is shared across all :class:`~app.models.Event` s in this series. This is not the event's unique URL, rather the slug that is unique between series objects. :ivar events: :class:`mongoengine.fields.ListField` - A list of :class:`~app.models.Event` s in this series. :ivar frequency: :class:`mongoengine.fields.StringField` - The interval of the occurrence. Can only take the value ``"weekly"``. :ivar every: :class:`mongoengine.fields.IntField` - The number of ``frequency`` units after which the event repeats. For example, ``frequency = "weekly"`` and ``every = 2`` indicates that the event occurs every two weeks. :ivar ends_after: :class:`mongoengine.fields.BooleanField` - True if the event ends after a specific number of occurences. Must be set opposite to ``ends_on``. :ivar ends_on: :class:`mongoengine.fields.BooleanField` - True if the event ends on a certain date. Must be set opposite to ``ends_after``. :ivar num_occurrences: :class:`mongoengine.fields.IntField` - The number of occurrences for a recurring event. Should be set only if ``ends_after`` is ``True``. :ivar recurrence_end_date: :class:`DateField` - The date that the recurrence ends on. Should be set only if ``ends_on`` is ``True``. :ivar recurrence_summary: :class:`mongoengine.fields.StringField` - A plain English explanation of the recurrence. Generated in JavaScript but stored here. :ivar gcal_id: :class:`mongoengine.fields.StringField` - The ID for this event series on Google Calendar. In Google Calendar API responses, this is stored as the ``id`` field for events. If this field is None, then we never got a proper response from Google Calendar when (if) we made a request to create it there. It most likely does not exist on Google Calendar. This is the same as the ``gcal_id`` of the first event in the series. """ # MongoEngine ORM metadata meta = {} date_created = db.DateTimeField(required=True, default=now) date_modified = db.DateTimeField(required=True, default=now) slug = db.StringField(required=True, max_length=255) events = db.ListField(db.ReferenceField("Event")) frequency = db.StringField(default="weekly") every = db.IntField(min_value=1, max_value=30) ends_after = db.BooleanField(default=True) ends_on = db.BooleanField(default=False) num_occurrences = db.IntField(default=1) recurrence_end_date = DateField() recurrence_summary = db.StringField() gcal_id = db.StringField() # ID of the first event in the series def delete_one(self, event): """Deletes ``event`` after removing it from the series. :param event: The event to delete. :type event: :class:`~app.models.Event` """ self.events.remove(event) event.delete() self.save() def delete_all_except(self, event): """Deletes all events in the series except ``event``, and then deletes the series. Should be called when an event's recurrence is disabled. :param event: The event to delete. :type event: :class:`~app.models.Event` """ for e in self.events[:]: if e != event: e.delete() event.parent_series = None self.delete() def delete_all(self): """Deletes all events in the series, and the series itself.""" for e in self.events: e.delete() self.delete() def clean(self): """Called by Mongoengine on every ``.save()`` to the object. Update date_modified, and ensure that exactly one of `ends_after` and `ends_on` is True at a time. :raises: :class:`wtforms.validators.ValidationError` """ self.date_modified = now() if self.ends_after == self.ends_on: raise ValidationError("ends_on and ends_after should not share a " "value.")