class Case(db.Document): patient_name = db.StringField() ambulance_driver = db.StringField() patient_id = db.StringField() driver_id = db.StringField() hospital = db.StringField() report = db.StringField(required=False) issues = db.StringField() problem = db.StringField() status = db.BoolField(required=False) active = db.BoolField() def create(self, obj): self.patient_name = obj["patient_name"] self.ambulance_driver = obj["ambulance_driver"] self.hospital = obj["hospital"] self.problem = obj["problem"] self.issues = obj["issues"] self.patient_id = obj["patient_id"] self.driver_id = obj["driver_id"] self.active = True
class ShoppingList(db.Document): name = db.StringField() quantity = db.FloatField() unit = db.StringField() missing = db.BoolField() def __dict__(self): return { 'name': self.name, 'quantity': self.quantity, 'unit': self.unit, 'missing': self.missing }
class Message(db.Document): receiver = db.StringField() body = db.StringField() date_created = db.CreatedField() read = db.BoolField(default=False) def full_dict(self): response = self.short_dict() response.update({ 'receiver': self.receiver, 'body': self.body, }) return response def short_dict(self): return { 'id': str(self.mongo_id), 'date_created': self.date_created.strftime('%Y-%m-%d %H:%M:%S'), 'read': self.read, }
class User(db.Document): name = db.StringField() phone = db.StringField() password = db.StringField() blood_group = db.StringField() blood_donate = db.BoolField() address = db.StringField() issues = db.StringField(required=False) emergency_contacts = db.ListField(db.StringField(), required=False) aadhar = db.StringField(required=False) location = db.DictField(db.StringField(), required=False) friends = db.ListField(db.StringField(), required=False) def create(self, obj): self.name = obj["name"] self.phone = obj["phone"] self.password = obj["password"] self.blood_group = obj["blood_group"] self.blood_donate = False self.address = obj["address"] self.emergency_contacts = list() self.friends = list() self.location = {"lat": "0", "log": "0"} self.issues = "" self.aadhar = "" # self.aadhar = obj["aadhar"] # self.location = obj["location"] # self.friends = obj["friends"] def toJSON(self): json = dict() json['name'] = self.name json['phone'] = self.phone json['blood_group'] = self.blood_group json['blood_donate'] = self.blood_donate json['address'] = self.address json['issues'] = self.issues json['aadhar'] = self.aadhar return json
class User(db.Document): uniqueID = db.StringField(required=True) member_since = db.DateTimeField(required=True) last_seen = db.DateTimeField(required=True) birthdate = db.DateTimeField(default=None) sex = db.EnumField(db.StringField(), 'male', 'female', default=None) physician_contact_permitted = db.BoolField(default=False, required=True) medical_record_abstraction = db.BoolField(default=False, required=True) data_exchange_cohort = db.BoolField(default=False, required=True) signature = db.StringField(max_length=3, default=None) date_signed = db.DateTimeField(default=None) def createIfNotExistsByUniqueID(self, uniqueID): if self.getByUniqueID(uniqueID) is None: self.uniqueID = uniqueID self.member_since = datetime.utcnow() self.last_seen = datetime.utcnow() self.save() return True def getAll(self): return User.query.all() def getByUniqueID(self, uniqueID): return User.query.filter_by(uniqueID=uniqueID).first() def getUserConsentByUniqueID(self, uniqueID): if self.getByUniqueID(uniqueID).date_signed is not None: return True else: return False def setRelativeConsentByUniqueID(self, uniqueID, sex, birthdate, signature): if sex is None: raise ValueError( 'Bad value for field of type "sex". Reason: "Value cannot be null"' ) if birthdate is None: raise ValueError( 'Bad value for field of type "birthdate". Reason: "Value cannot be null"' ) if signature is None: raise ValueError( 'Bad value for field of type "signature". Reason: "Value cannot be null"' ) User.query.filter(User.uniqueID == uniqueID).set( sex=sex, birthdate=birthdate, signature=signature, date_signed=datetime.utcnow()).execute() return True def setPatientConsentByUniqueID(self, uniqueID, sex, birthdate, signature, physician_contact_permitted=None, medical_record_abstraction=None, data_exchange_cohort=None): self.setRelativeConsentByUniqueID(uniqueID, sex, birthdate, signature) if physician_contact_permitted is None: raise ValueError( 'Bad value for field of type "physician_contact_permitted". Reason: "Value cannot be null"' ) if medical_record_abstraction is None: raise ValueError( 'Bad value for field of type "medical_record_abstraction". Reason: "Value cannot be null"' ) if data_exchange_cohort is None: raise ValueError( 'Bad value for field of type "data_exchange_cohort". Reason: "Value cannot be null"' ) User.query.filter(User.uniqueID == uniqueID).set( sex=sex, birthdate=birthdate, signature=signature, physician_contact_permitted=physician_contact_permitted, medical_record_abstraction=medical_record_abstraction, data_exchange_cohort=data_exchange_cohort, date_signed=datetime.utcnow()).execute() return True def setLastSeenByUniqueID(self, uniqueID): User.query.filter(User.uniqueID == uniqueID).set( last_seen=datetime.utcnow()).execute() return True def getCSVReportInformedConsent(self): data = [ob.serializeInformedConsent() for ob in self.getAll()] filename = str(uuid.uuid4()) + '.csv' csv_file = UnicodeWriter( open(os.path.join(current_app.config['REPORTS_DIR'], filename), "w")) csv_file.writerow([ 'User ID', 'Sex', 'Birthdate', 'Signature', 'Physician Contact Permitted', 'Medical Record Abstraction', 'Data Exchange Cohort', 'Informed Consent' ]) for item in data: csv_file.writerow([ item['uniqueID'], item['sex'], item['birthdate'], item['signature'], item['physician_contact_permitted'], item['medical_record_abstraction'], item['data_exchange_cohort'], item['date_signed'] ]) return filename def serialize(self, roles=[]): d = { "uniqueID": str(self.uniqueID), "member_since": self.member_since.isoformat(), "last_seen": self.last_seen.isoformat() } if Role.patient in roles or Role.relative in roles: d = { "sex": self.sex, "birthdate": utils.Time.DatetimeToDMY(self.birthdate) if self.birthdate is not None else None, "signature": self.signature } if self.date_signed is not None: d["date_signed"] = self.date_signed.isoformat() else: d["date_signed"] = None if Role.patient in roles: d["physician_contact_permitted"] = bool( self.physician_contact_permitted) d["medical_record_abstraction"] = bool( self.medical_record_abstraction) d["data_exchange_cohort"] = bool(self.data_exchange_cohort) return d def serializeInformedConsent(self): d = { "uniqueID": str(self.uniqueID), "sex": self.sex, "birthdate": utils.Time.DatetimeToDMY(self.birthdate) if self.birthdate is not None else None, "signature": self.signature, "physician_contact_permitted": bool(self.physician_contact_permitted), "medical_record_abstraction": bool(self.medical_record_abstraction), "data_exchange_cohort": bool(self.data_exchange_cohort) } if self.date_signed is not None: d["date_signed"] = self.date_signed.isoformat() else: d["date_signed"] = None return d
class Survey(db.Document): user = db.ObjectIdField(User) timestamp = db.DateTimeField(required=True) survey = db.DictField(db.AnythingField(), required=True) tags = db.ListField(db.StringField(), required=True, default=[]) ongoing = db.BoolField(default=True, required=True) def getAll(self, from_datetime=None, until_datetime=None, tags=None, ongoing=None): """ Return all surveys registered. By setting 'from_datetime'm, 'until_datetime', 'tags' or 'ongoing' one could further filter the scope of the query """ # return Survey.query.all() query = db.session.query(Survey) if from_datetime is not None: query.filter(Survey.timestamp >= from_datetime) if until_datetime is not None: query.filter(Survey.timestamp <= until_datetime) if tags is not None: query.filter(Survey.tags.in_(tags)) if ongoing is not None: query.filter(Survey.ongoing == ongoing) return query.all() def getAllByUniqueID(self, uniqueID, from_datetime=None, until_datetime=None, tags=None, ongoing=None): """ Return all surveys registered by a given user. By setting 'from_datetime'm, 'until_datetime', 'tags' or 'ongoing' one could further filter the scope of the query """ # Check if user exists user = User().query.filter(User.uniqueID == uniqueID).first() try: assert not user is None, "User not found" except AssertionError as ax: raise UserNotFound(uniqueID) query = db.session.query(Survey) query.filter(Survey.user == user.mongo_id) if from_datetime is not None: query.filter(Survey.timestamp >= from_datetime) if until_datetime is not None: query.filter(Survey.timestamp <= until_datetime) if tags is not None: query.filter(Survey.tags.in_(tags)) if ongoing is not None: query.filter(Survey.ongoing == ongoing) return query.all() def getByUniqueIDAndID(self, uniqueID, _id): return Survey.query.filter(Survey.user == User().query.filter(User.uniqueID == uniqueID) .first().mongo_id, Survey.mongo_id == _id).first() def getByID(self, survey_id): try: surveys = Survey.query.filter(Survey.mongo_id == survey_id) if surveys.count() == 0: raise SurveyNotFound(survey_id) return surveys.first() except db.BadValueException: raise SurveyNotFound(survey_id) def addByUniqueID(self, uniqueID, survey, tags=[], ongoing=True): self.user = User().query.filter(User.uniqueID == uniqueID).first().mongo_id self.timestamp = datetime.utcnow() self.survey = survey self.tags = tags self.ongoing = ongoing self.save() return True def updateByUniqueIDAndID(self, uniqueID, _id, survey, tags, ongoing): Survey.query.filter(Survey.user == User().query.filter(User.uniqueID == uniqueID).first().mongo_id, Survey.mongo_id == _id).set( survey=survey, tags=tags, ongoing=ongoing, timestamp=datetime.utcnow()).execute() return True def updateByUniqueID(self, _id, survey, tags, ongoing): """ Verify survey exists. Then update its 'survey' content and save it back. """ try: surveys = Survey.query.filter(Survey.mongo_id == _id) if surveys.count() == 0: raise SurveyNotFound(_id) if surveys.count() > 1: raise NonUniqueSurveyIDError(_id) except db.BadValueException as error: raise SurveyNotFound(_id) existing_survey_object = surveys.first() existing_survey_object.survey = survey existing_survey_object.tags = tags existing_survey_object.ongoing = ongoing existing_survey_object.timestamp=datetime.utcnow() existing_survey_object.save() return True def deleteByUniqueID(self, _id): """ Verify survey exists. Then delete it. """ try: surveys = Survey.query.filter(Survey.mongo_id == _id) if surveys.count() == 0: raise SurveyNotFound(_id) if surveys.count() > 1: raise NonUniqueSurveyIDError(_id) except db.BadValueException as error: raise SurveyNotFound(_id) existing_survey_object = surveys.first() existing_survey_object.remove() return True def getCSVReportTagsAndOngoing(self): data = [ob.serializeTagsAndOngoing() for ob in self.getAll()] filename = str(uuid.uuid4()) + '.csv' path = os.path.join(current_app.config['REPORTS_DIR'], filename) csv_file = csv.writer(open(path, mode="w")) csv_file.writerow(['User ID', 'Survey ID', 'timestamp', 'tags', 'ongoing']) for item in data: # the `tags` field can apparently contain arbitrary Unicode data (limited to Latin-1, actually, looking # at the samples collected so far) so we need to escape it to UTF-8 in order to save into a CSV file # According to the Python 2.7 `csv` module docs, "The csv module does not directly support reading # and writing Unicode, but it is 8-bit-clean save for some problems with ASCII NUL characters." # so reading and writing UTF-8 is OK. csv_file.writerow([item['user_id'], item['id'], item['timestamp'], item['tags'].encode('utf-8'), item['ongoing']]) return filename def serialize(self): d = { "id": str(self.mongo_id), "timestamp": self.timestamp.isoformat(), "survey": self.survey, "tags": self.tags, "ongoing": bool(self.ongoing) } return d def serializeTagsAndOngoing(self): d = { "user_id": User().query.filter(User.mongo_id == self.user).first().uniqueID, "id": str(self.mongo_id), "timestamp": self.timestamp.isoformat(), "tags": ', '.join(self.tags), "ongoing": bool(self.ongoing) } return d