class NurseModel(RidDocument): rid = SequenceField( unique=True ) # Overriding to use own counter rather than the one common to all RidDocument childs. user = ReferenceField(UserModel, required=True, unique=True, reverse_delete_rule=2) name = StringField(min_lenght=1, max_length=255, required=True) treatment_types = ListField(ReferenceField(TreatmentTypeModel, required=False), default=list) agenda = SortedListField(DateTimeField(), required=False, default=list()) def clean(self): errs = dict() self.agenda.sort() for i in range(len(self.agenda) - 1): if self.agenda[i].date() == self.agenda[i + 1].date(): errs["agenda"] = "Can only have one agenda per day!" duplicates = find_duplicates(self.treatment_types) if duplicates: errs[ "treatment_types"] = f"Treatment types list cannot contains duplicate elements." if errs: raise ValidationError(errors=errs)
class Course(db.Document): no = StringField(required=True) name = StringField(required=True) teacher = ReferenceField(Teacher, required=True) teacher_name = StringField(required=True) credit = StringField() detail = StringField(default="") target = StringField(default="") like = ListField(ReferenceField(User, deref=True), default=lambda: []) like_count = IntField(default=0) refrences = StringField(default="") heat = IntField(default=0) evaluations_count = IntField(default=0) # evaluations = ListField(ReferenceField(Evaluation), default=lambda: []) rating = FloatField(default=lambda: 0, required=True) school = StringField(required=True) category = StringField(default="") tags = ListField(StringField(), default=lambda: []) terms = SortedListField(StringField(), reverse=True, default=lambda: []) meta = { 'strict': False, 'ordering': ['-heat'], 'indexes': ['heat', 'credit', 'no', 'name', 'teacher_name'] } def __unicode__(self): return '{}-{}-{}'.format(self.name, self.no, self.teacher)
class PlanoAula(Document): professor = ReferenceField(User) disciplina = ReferenceField(Disciplina) curso = ReferenceField(Curso) turma = StringField() turno = StringField() data = DateTimeField() aulas = SortedListField(EmbeddedDocumentField(Aula), ordering="data") #etapas = ListField(Etapa) ac1 = ListField(AtvPeso, default=[]) ac2 = ListField(AtvPeso, default=[]) af = ListField(StringField(), default=[]) sub = ListField(StringField(), default=[]) def to_dict(self): aulas_array = [] for aula in self.aulas: aulas_array.append(aula) return dict(id=str(self.pk), professor=dict(id=str(self.professor.pk), nome=self.professor.name), disciplina=dict(id=str(self.disciplina.pk), nome=self.disciplina.nome), curso=dict(id=str(self.curso.pk), nome=self.curso.nome), turno=self.turno, turma=self.turma, aulas=aulas_array)
class Habit(Document, AuditableModel): name = StringField(max_length=1024, required=True) past_goals = ListField(EmbeddedDocumentField(Goal)) user = ReferenceField(User, required=True) public = BooleanField(required=True) x_list = SortedListField(StringField()) daily_goal = EmbeddedDocumentField(Goal) start_date = DateTimeField(required=True) end_date = DateTimeField(default=None) def create_habit(self, user, **kwargs): start_date, end_date = map( lambda x: arrow.get(x).datetime if x else None, (kwargs.get('start_date'), kwargs.get('end_date'))) if kwargs.get('type') == "daily": new_daily_goal = DailyGoal(type=kwargs.get('type'), label_text=kwargs.get('label_text')) self.daily_goal = new_daily_goal self.user = user self.name = kwargs.get('name') self.start_date = start_date or arrow.now().datetime self.public = kwargs.get('public') self.end_date = end_date return super(Habit, self).save()
class History(Document): user = ReferenceField(User, unique=True) records = SortedListField(EmbeddedDocumentField(Record), ordering="timestamp", reverse=True) @staticmethod def get_history_records(user, limit=5): """get_history""" history = History.objects(user=user).first() if history: return history.records[:limit] else: return [] @staticmethod def insert_history_record(user, msg): """insert history to a user""" record = Record(msg=msg) history = History.objects(user=user).first() if not history: history = History(user=user, records=[]) history.records.append(record) history.save() return record
class User(Document): username = StringField(unique=True, required=True) email = StringField(unique=True, required=True) password = StringField(required=True) # currently email is enabled groups = SortedListField(EmbeddedDocumentField(Group), ordering='groupName') meta = {'ordering': ['+username']}
class Topic(Document): # TODO Add indexes name = StringField(required=True) category = ReferenceField(Category) user = ReferenceField(User) creation_date = DateTimeField(default=datetime.utcnow) last_post_date = DateTimeField() posts = SortedListField(EmbeddedDocumentField(Post), ordering="post_date", reverse=True)
class Transaction(Document): giver = ReferenceField(User) recipient = ReferenceField(User) amount = IntField() reason = StringField() category = StringField() upvote = IntField() downvote = IntField() voters = SortedListField(ReferenceField(User), ordering='name') thanks = BooleanField() createdate = DateTimeField()
class DeletedComment(CommentBase): """ Comment that was deleted. Used for comment parents and acts as a placeholder. """ replies = SortedListField(ReferenceField('Comment'), default=list()) timestamp = DateTimeField(required=True, default=datetime.now()) def to_json(self): return super(DeletedComment, self).to_json()
class Calendar(db.Document, ModelCore): name = StringField(required=True, unique=True) room_size = IntField(required=True) therapies = SortedListField(field=StringField(max_length=20)) def to_dict(self): serial = {} serial['name'] = self.name serial['room_size'] = self.room_size serial['therapies'] = self.therapies return serial
class CommentBase(Document, JsonMixin, TimestampOrderableMixin): replies = SortedListField(ReferenceField('Comment'), default=list()) timestamp = DateTimeField(required=True, default=datetime.now()) meta = { 'allow_inheritance': True, 'abstract': True, } @property def parent(self): return self.__class__.objects(replies__in=[ self, ]).first()
class Transaction(mgo.Document): giver = ReferenceField(User) recipient = ReferenceField(User) amount = mgo.IntField(required='true') reason = StringField() category = StringField() upvote = IntField() downvote = IntField() voters = SortedListField(ReferenceField(User), ordering='name') thanks = BooleanField() # createdate = DateTimeField(default=datetime.now()) createdate = DateTimeField() meta = { 'ordering': ['+createdate'] }
class ExerciseLog(Document): user = ReferenceField(User, required=True) wordname = StringField(required=True) word = ReferenceField(Word, required=True) review = DateTimeField(required=True) sentences = SortedListField(EmbeddedDocumentField(SentenceLog), ordering="time", reverse=True) def calucate_review(self): count = 0 for s in reversed(self.sentences): if not s.result: break count += 1 delta = ebbinghaus.get(count, timedelta(days=15)) self.review = datetime.utcnow() + delta @classmethod def review_count(cls, user, start, end): data = ExerciseLog.objects(user=user, review__gt=start, review__lt=end).\ aggregate( {'$group' : {'_id' : {'$dateToString' : { 'date': "$review", 'format': "%Y/%m/%d", } }, 'count' : { '$sum' : 1 }}}, {'$sort': {'_id': 1}} ) return {i['_id']: i['count'] for i in list(data)} @classmethod def exercise_count(cls, user, start, end): data = ExerciseLog.objects(user=user).\ aggregate( {"$match": {"sentences.time": {"$gte": start, "$lte": end}}}, {"$project":{'_id':0, 'sentences.time': 1, 'sentences.result':1}}, {"$unwind":"$sentences"}, {"$match": {"sentences.time": {"$gte": start, "$lte": end}}}, {'$project': {'day': '$sentences.time', 'result': '$sentences.result'}}, {'$group': { '_id': {'$dateToString' : { 'date': "$day", 'format': "%Y/%m/%d", } }, 'count': { '$sum': 1 } } }, {'$sort': {'_id': 1}} ) return {i['_id']: i['count'] for i in list(data)}
class Therapist(db.Document, ModelCore): name = StringField(required=True, max_length=200) slug = StringField(required=True, max_length=20) phone = StringField(required=True, max_length=20) email = EmailField(required=True, max_length=50, unique=True) specialties = SortedListField(field=StringField(max_length=20)) last_modified = DateTimeField(default=datetime.now) def to_dict(self): serial = {} serial['name'] = self.name serial['slug'] = self.slug serial['phone'] = self.phone serial['email'] = self.email serial['last_modified'] = self.last_modified serial['specialties'] = self.specialties return serial
class Discussion(JsonMixin, Document): """ User comments pertaining to a part of 1Base. As with any wiki, a disagreement may arise. Discussions are there to allow users to state ther opinion on a particular issue. """ title = StringField() comments = SortedListField(ReferenceField(Comment), required=True) is_locked = BooleanField(default=False) meta = { 'allow_inheritance': True, } @property def starter(self): """ Return the comment that started the discussion. """ return self.comments[0]
class Post(PermissionMixin, Document): author = ReferenceField('users.User', reverse_delete_rule=CASCADE) title = StringField(max_length=120, required=True) content = StringField(max_length=1024, required=True) tags = ListField(StringField(max_length=50)) comments = SortedListField(EmbeddedDocumentField(Comment)) page_views = IntField(default=0) create_time = DateTimeField(default=timezone.now) __object_name__ = 'Post' __acl__ = [ (Allow, EveryOne, 'view'), (Allow, Authenticated, 'add'), (Allow, Owner, 'change'), (Allow, Owner, 'delete'), ] meta = { 'ordering': ['-create_time'], } @classmethod def get_by_id(cls, id): return cls.objects.get(id=id) @classmethod def create_post(cls, username, title, content): user = User.get_by_uesrname(username) post = cls(author=user, title=title, content=content) post.save() return post def is_owner(self, username): return self.author.username == username @property def last_comment(self): return self.comments[-1]
class ContestRank(Document): contest_pk = IntField(required=True) user = SortedListField(ReferenceField(RankUser))
class Day(EmbeddedDocument): date = StringField(required=True) status = StringField(default='P') members = SortedListField(EmbeddedDocumentField(Member), ordering='name')
class ObjQnA(QnA): content = SortedListField(EmbeddedDocumentField(ObjQnAContent), ordering='version', reverse=True, required=True)
class Group(EmbeddedDocument): groupName = StringField(required=True) allMembers = SortedListField(EmbeddedDocumentField(Member), ordering='name') calendar = SortedListField(EmbeddedDocumentField(Day), ordering='date')
class Variant(Document): # document_id is a md5 string created by institute_genelist_caseid_variantid: document_id = StringField(primary_key=True) # variant_id is a md5 string created by variant_id variant_id = StringField(required=True) # display name in variant_id (no md5) display_name = StringField(required=True) # The variant can be either a reserch variant or a clinical variant. # For research variants we display all the available information while # the clinical variants hae limited annotation fields. variant_type = StringField(required=True, choices=('research', 'clinical')) # case_id is a string like owner_caseid case_id = StringField(required=True) chromosome = StringField(required=True) position = IntField(required=True) reference = StringField(required=True) alternative = StringField(required=True) rank_score = FloatField(required=True) variant_rank = IntField(required=True) institute = ReferenceField('Institute', required=True) quality = FloatField() filters = ListField(StringField()) samples = ListField(EmbeddedDocumentField(GTCall)) genetic_models = ListField(StringField(choices=GENETIC_MODELS)) compounds = SortedListField(EmbeddedDocumentField(Compound), ordering='combined_score', reverse=True) genes = ListField(EmbeddedDocumentField(Gene)) db_snp_ids = ListField(StringField()) # Gene ids: hgnc_symbols = ListField(StringField()) ensembl_gene_ids = ListField(StringField()) # Frequencies: thousand_genomes_frequency = FloatField() exac_frequency = FloatField() local_frequency = FloatField() # Predicted deleteriousness: cadd_score = FloatField() clnsig = IntField() @property def has_comments(self): """ Return True is there are any comments for this variant in the database """ if Event.objects(verb='comment', variant_id=self.variant_id, institute=self.institute): return True return False @property def clnsig_human(self): return { 0: 'Uncertain significance', 1: 'not provided', 2: 'Benign', 3: 'Likely benign', 4: 'Likely pathogenic', 5: 'Pathogenic', 6: 'drug response', 7: 'histocompatibility', 255: 'other' }.get(self.clnsig, 'not provided') # Conservation: phast_conservation = ListField(StringField(choices=CONSERVATION)) gerp_conservation = ListField(StringField(choices=CONSERVATION)) phylop_conservation = ListField(StringField(choices=CONSERVATION)) # Database options: gene_lists = ListField(StringField()) expected_inheritance = ListField(StringField()) manual_rank = IntField(choices=[0, 1, 2, 3, 4, 5]) acmg_evaluation = StringField(choices=ACMG_TERMS) @property def omim_annotations(self): """Returns a list with OMIM id(s).""" if len(self.genes) == 1: annotations = (str(gene.omim_gene_entry) for gene in self.genes if gene.omim_gene_entry) else: annotations = (':'.join( [gene.hgnc_symbol, str(gene.omim_gene_entry)]) for gene in self.genes if gene.omim_gene_entry) # flatten the list of list of omim ids return annotations @property def omim_annotation_links(self): """Return a list of OMIM id links.""" base_url = 'http://www.omim.org/entry' for omim_id_str in self.omim_annotations: # handle cases with variant overlapping multiple genes omim_id_parts = omim_id_str.split(':') if len(omim_id_parts) == 1: # single gene overlap omim_id = omim_id_parts[0] else: # multiple genes omim_id = omim_id_parts[1] yield (omim_id_str, "{base}/{id}".format(base=base_url, id=omim_id)) @property def omim_phenotypes(self): """Return a list of OMIM phenotypes with related gene information.""" for gene in self.genes: for phenotype in gene.omim_phenotypes: yield gene, phenotype @property def omim_inheritance_models(self): """Return a list of OMIM inheritance models (phenotype based).""" models = ((phenotype.disease_models for phenotype in gene.omim_phenotypes) for gene in self.genes) # untangle multiple nested list of list of lists... return set( itertools.chain.from_iterable( itertools.chain.from_iterable(models))) @property def region_annotations(self): """Returns a list with region annotation(s).""" region_annotations = [] if len(self.genes) == 1: return [gene.region_annotation for gene in self.genes] else: for gene in self.genes: region_annotations.append(':'.join( [gene.hgnc_symbol, gene.region_annotation])) return region_annotations @property def sift_predictions(self): """Return a list with the sift prediction(s) for this variant. The most severe for each gene. """ sift_predictions = [] if len(self.genes) == 1: sift_predictions = [(gene.sift_prediction or '-') for gene in self.genes] else: for gene in self.genes: sift_predictions.append(':'.join( [gene.hgnc_symbol, gene.sift_prediction or '-'])) return sift_predictions @property def polyphen_predictions(self): """Return a list with the polyphen prediction(s) for this variant. The most severe for each gene. """ polyphen_predictions = [] if len(self.genes) == 1: polyphen_predictions = [(gene.polyphen_prediction or '-') for gene in self.genes] else: for gene in self.genes: polyphen_predictions.append(':'.join( [gene.hgnc_symbol, gene.polyphen_prediction or '-'])) return polyphen_predictions @property def is_matching_inheritance(self): """Match expected (OMIM) with annotated inheritance models.""" omim_models = self.omim_inheritance_models for model in self.genetic_models: for omim_model in omim_models: if (model == omim_model) or (omim_model in model): return True return False @property def functional_annotations(self): """Return a list with the functional annotation(s) for this variant. The most severe for each gene.""" functional_annotations = [] if len(self.genes) == 1: functional_annotations = [ gene.functional_annotation for gene in self.genes ] else: for gene in self.genes: functional_annotations.append(':'.join( [gene.hgnc_symbol, gene.functional_annotation or ''])) return functional_annotations @property def transcripts(self): """Yield all transcripts as a flat iterator. For each transcript both the parent gene object as well as the transcript is yielded. Yields: class, class: Gene and Transcript ODM """ # loop over each gene in order for gene in self.genes: # loop over each child transcript for the gene for transcript in gene.transcripts: # yield the parent gene, child transcript combo yield transcript @property def refseq_transcripts(self): """Yield all transcripts with a RefSeq id.""" for transcript in self.transcripts: if transcript.refseq_ids: yield transcript @property def protein_changes(self): for transcript in self.refseq_transcripts: yield transcript.stringify() @property def end_position(self): # bases contained in alternative allele alt_bases = len(self.alternative) # vs. reference allele bases = max(len(self.reference), alt_bases) return self.position + (bases - 1) # This is exactly the same as variant_id... @property def frequency(self): """Returns a judgement on the overall frequency of the variant. Combines multiple metrics into a single call. """ most_common_frequency = max(self.thousand_genomes_frequency, self.exac_frequency) if most_common_frequency > .05: return 'common' elif most_common_frequency > .01: return 'uncommon' else: return 'rare' @property def manual_rank_level(self): return { 1: 'low', 2: 'low', 3: 'medium', 4: 'medium', 5: 'high' }.get(self.manual_rank, 'unknown') @property def exac_link(self): """Compose link to ExAC website for a variant position.""" url_template = ("http://exac.broadinstitute.org/variant/" "{this.chromosome}-{this.position}-{this.reference}" "-{this.alternative}") return url_template.format(this=self) @property def ucsc_link(self): url_template = ( "http://genome.ucsc.edu/cgi-bin/hgTracks?db=hg19&" "position=chr{this.chromosome}:{this.position}-{this.position}&dgv=pack&knownGene=pack&omimGene=pack" ) return url_template.format(this=self) def __unicode__(self): return self.display_name