def account_update(actor_id, account_dto, _dto=True): """Updates account information. :param actor_id: (int) ID of the account. :param account_dto: (dto.accounts.AccountDto) DTO with updated information. :return: (dto.accounts.AccountDto) if _dto is True. (kinds.accounts.Account) if _dto is False. """ asserts.type_of(account_dto, AccountDto) ac = account_by_id(actor_id, _dto=False) acd = account_dto def has_changed(pdto, pndb): return pdto is not None and pdto != pndb if ac.id != acd.id: raise exp.PermissionExp() if has_changed(acd.first, ac.first): ac.first = acd.first if has_changed(acd.last, ac.last): ac.last = acd.last if has_changed(acd.phone_number, ac.phone_number): ac.phone_number = acd.phone_number if has_changed(acd.account_type, ac.account_type): ac.account_type = acd.account_type # First-time caregiver. if ac.account_type == AccountType.Caregiver and ac.caregiver_id is None: caregiver = Caregiver(account_id=ac.id) caregiver.put() ac.caregiver_id = caregiver.id ac.put() if _dto: return AccountDto.from_account_ndb(ac) return ac
def query(actor_id, query_dto): """Retrieves caregivers with given search critieria. :param actor_id: (int) ID of the account. :param query_dto: (dto.search.SearchQueryDto) search query. :return: (list<dto.search.SearchResultDto>) search results. """ asserts.type_of(query_dto, SearchQueryDto) cls, qdto = Caregiver, query_dto q = cls.query() if qdto.zipcode: q = q.filter(cls.zipcode == qdto.zipcode) if qdto.live_in: q = q.filter(cls.live_in == qdto.live_in) if qdto.gender: q = q.filter(cls.gender == qdto.gender) if qdto.care_services: nd = [cls.care_services == c for c in qdto.care_services] q = q.filter(ndb.AND(*nd)) if qdto.licenses: nd = [cls.licenses == l for l in qdto.licenses] q = q.filter(ndb.AND(*nd)) if qdto.expertise: nd = [cls.expertise == e for e in qdto.expertise] q = q.filter(ndb.AND(*nd)) if qdto.transportation: nd = [cls.transportation == t for t in qdto.transportation] q = q.filter(ndb.AND(*nd)) if qdto.languages: nd = [cls.languages == l for l in qdto.languages] q = q.filter(ndb.AND(*nd)) cursor = Cursor(urlsafe=qdto.cursor) if qdto.cursor is not None else None results, cursor, more = q.fetch_page(15, start_cursor=cursor) return _build_results_dto(actor_id, results, cursor, more)
def patient_update(actor_id, patient_dto, _dto=True): """Creates or updates a single patient for the given account. :param actor_id: (int) ID of the account performing the action. :param patient_dto: (dto.accounts.PatientDto) patient DTO from request. :return: (dto.accounts.PatientDto) if _dto is True (kinds.accounts.Patient) if _dto is False """ asserts.type_of(patient_dto, PatientDto) def has_changed(pdto, pndb): return pdto is not None and pdto != pndb account = account_by_id(actor_id, _dto=False) if asserts.is_valid_id_type(patient_dto.id): patient = patient_by_id(actor_id, patient_dto.id, _dto=False) else: patient = Patient(account_id=actor_id) # Lazily update values. # TODO: validate each property individually. for p in PatientDto._props: pdto = getattr(patient_dto, p, None) if has_changed(pdto, getattr(patient, p, None)): setattr(patient, p, pdto) patient.put() if patient.id not in account.patient_ids: account.patient_ids.append(patient.id) account.put() if not _dto: return patient return PatientDto.from_patient_ndb(patient)
def create_thread_ndb(actor_id, recipients, text, subject=''): """Creates a new thread with given recipients, body text, and subject. TODO(kanat): check if recipient is a valid account. :param actor_id: (int) ID of the account acting. :param recipients: (list) list of account IDs in the thread. :param text: (str) body text of the initial message. :param subject: (str) optional subject line of the thread. :return: (kinds.messages.Thread) """ asserts.valid_id_type(actor_id) asserts.not_empty(recipients) asserts.type_of(text, basestring) asserts.type_of(subject, basestring) thd = Thread() for account_id in set(recipients): if account_id != actor_id: thd.add_member(account_id) if not len(thd.members): raise exp.BadRequestExp('Recipients not specified.') thd.add_member(actor_id) thd.put() # Populate MessageDto. message_dto = MessageDto() message_dto.thread_id = thd.id message_dto.text = text send_ndb(actor_id, message_dto) return thd
def caregiver_update(actor_id, caregiver_dto, _dto=True): """Updates the caregiver information associated with the given account. :param actor_id: (int) ID of the account performing the action. :param caregiver_dto: (dto.accounts.CaregiverDto) caregiver DTO from request. :return: (dto.accounts.CaregiverDto) if _dto is True (kinds.accounts.Caregiver) if _dto is False """ asserts.type_of(caregiver_dto, CaregiverDto) cg = caregiver_by_account(actor_id, _dto=False) cgd = caregiver_dto def has_changed(pdto, pndb): return pdto is not None and pdto != pndb if has_changed(cgd.zipcode, cg.zipcode): cg.zipcode = cgd.zipcode if has_changed(cgd.gender, cg.gender): cg.gender = cgd.gender if has_changed(cgd.dob, cg.dob): cg.dob = cgd.dob if has_changed(cgd.headline, cg.headline): if len(cgd.headline) > 100: cgd.headline = cgd.headline[:100] cg.headline = cgd.headline if has_changed(cgd.bio, cg.bio): if len(cgd.bio) > 5000: cgd.bio = cgd.bio[:5000] cg.bio = cgd.bio if has_changed(cgd.care_services, cg.care_services): cg.care_services = cgd.care_services if has_changed(cgd.gender_preference, cg.gender_preference): cg.gender_preference = cgd.gender_preference if has_changed(cgd.expertise, cg.expertise): cg.expertise = cgd.expertise if has_changed(cgd.licenses, cg.licenses): cg.licenses = cgd.licenses if has_changed(cgd.certifications, cg.certifications): cg.certifications = cgd.certifications if has_changed(cgd.transportation, cg.transportation): cg.transportation = cgd.transportation if has_changed(cgd.languages, cg.languages): cg.languages = cgd.languages if has_changed(cgd.allergies, cg.allergies): cg.allergies = cgd.allergies if has_changed(cgd.live_in, cg.live_in): cg.live_in = cgd.live_in cg.put() if not _dto: return cg return CaregiverDto.from_caregiver_ndb(cg)
def to_account_dto(cls, account_api): """Translates the given AccountApiModel to an AccountDto. :param account_api: (api.accounts.AccountApiModel) :return: (dto.accounts.AccountDto) """ asserts.type_of(account_api, AccountApiModel) account_dto = AccountDto() map_props(account_dto, account_api, AccountDto._props) return account_dto
def from_job_dto(cls, job_dto): """Translates the given JobDto to an JobApiModel. :param job_dto: (dto.jobs.JobDto) :return: (api.jobs.JobApiModel) """ asserts.type_of(job_dto, JobDto) job_api = JobApiModel() map_props(job_api, job_dto, JobDto._props) return job_api.ToMessage()
def to_patient_dto(cls, patient_api): """Translates the given PatientApiModel to a PatientDto. :param patient_api: (api.accounts.PatientApiModel) :return: (dto.accounts.PatientDto) """ asserts.type_of(patient_api, PatientApiModel) patient_dto = PatientDto() map_props(patient_dto, patient_api, PatientDto._props) return patient_dto
def from_caregiver_dto(cls, caregiver_dto): """Translates the given CaregiverDto to a CaregiverApiModel. :param caregiver_dto: (dto.accounts.CaregiverDto) :return: (api.accounts.CaregiverApiModel) """ asserts.type_of(caregiver_dto, CaregiverDto) caregiver_api = CaregiverApiModel() map_props(caregiver_api, caregiver_dto, CaregiverDto._props) return caregiver_api.ToMessage()
def to_caregiver_dto(cls, caregiver_api): """Translates the given CaregiverApiModel to a CaregiverDto. :param caregiver_api: (api.accounts.CaregiverApiModel) :return: (dto.accounts.CaregiverDto) """ asserts.type_of(caregiver_api, CaregiverApiModel) caregiver_dto = CaregiverDto() map_props(caregiver_dto, caregiver_api, CaregiverDto._props) return caregiver_dto
def from_message_ndb(cls, message_ndb): """Translates the given Message to MessageDto. :param message_ndb: (kinds.messages.Message) :return: (dto.messages.MessageDto) """ asserts.type_of(message_ndb, Message) message_dto = MessageDto() map_props(message_dto, message_ndb, MessageDto._props) return message_dto
def from_conn_dto(cls, pending_dto): """Translates the given PendingDto to a PendingConnApiModel. :param pending_dto: (dto.connections.PendingDto) :return: (api.connections.PendingConnApiModel) """ asserts.type_of(pending_dto, PendingDto) pendingconn_api = PendingConnApiModel() map_props(pendingconn_api, pending_dto, PendingDto._props) return pendingconn_api.ToMessage()
def from_account_dto(cls, account_dto): """Translates the given AccountDto to an AccountApiModel. :param account_dto: (dto.accounts.AccountDto) :return: (api.accounts.AccountApiModel) """ asserts.type_of(account_dto, AccountDto) account_api = AccountApiModel() map_props(account_api, account_dto, AccountDto._props) return account_api.ToMessage()
def from_account_ndb(cls, account_ndb): """Translates the given Account NDB to AccountDto. :param account_ndb: (kinds.accounts.Account) :return: (dto.accounts.AccountDto) """ asserts.type_of(account_ndb, Account) account_dto = AccountDto() map_props(account_dto, account_ndb, cls._props) return account_dto
def from_patient_ndb(cls, patient_ndb): """Translates the given Patient NDB to PatientDto. :param patient_ndb: (kinds.accounts.Patient) :return: (dto.accounts.PatientDto) """ asserts.type_of(patient_ndb, Patient) patient_dto = PatientDto() map_props(patient_dto, patient_ndb, cls._props) return patient_dto
def to_patient_ndb(cls, patient_dto): """Translates the given PatientDto to Patient NDB model. :param patient_dto: (dto.accounts.PatientDto) :return: (kinds.accounts.Patient) """ asserts.type_of(patient_dto, PatientDto) patient_ndb = Patient() map_props(patient_ndb, patient_dto, cls._props) return patient_ndb
def to_query_dto(cls, search_api): """Translates the given SearchApiModel into a SearchQueryDto. :param search_api: (api.search.SearchApiModel) :return: (dto.search.SearchQueryDto) """ asserts.type_of(search_api, SearchApiModel) query_dto = SearchQueryDto() map_props(query_dto, search_api, SearchQueryDto._props) return query_dto
def from_user_dto(cls, user_dto): """Translates the given UserDto to a UserApiModel. :param user_dto: (dto.accounts.UserDto) :return: (api.accounts.UserApiModel) """ asserts.type_of(user_dto, UserDto) user_api = UserApiModel() map_props(user_api, user_dto, UserDto._props) return user_api
def to_caregiver_ndb(cls, caregiver_dto): """Translates the given CaregiverDto to Caregiver NDB model. :param caregiver_dto: (dto.accounts.CaregiverDto) :return: (kinds.accounts.Caregiver) """ asserts.type_of(caregiver_dto, CaregiverDto) caregiver_ndb = Caregiver() map_props(caregiver_ndb, caregiver_dto, cls._props) return caregiver_ndb
def from_conn_dto(cls, conn_dto): """Translates the given ConnDto to a ConnApiModel. :param conn_dto: (dto.connections.ConnDto) :return: (api.connections.ConnApiModel) """ asserts.type_of(conn_dto, ConnDto) conn_api = ConnApiModel() map_props(conn_api, conn_dto, ConnDto._props) return conn_api.ToMessage()
def from_caregiver_ndb(cls, caregiver_ndb): """Translates the given Caregiver NDB to CaregiverDto. :param caregiver_ndb: (kinds.accounts.Caregiver) :return: (dto.accounts.CaregiverDto) """ asserts.type_of(caregiver_ndb, Caregiver) caregiver_dto = CaregiverDto() map_props(caregiver_dto, caregiver_ndb, cls._props) return caregiver_dto
def from_patient_dto(cls, patient_dto): """Translates the given PatientDto to a PatientApiModel. :param patient_dto: (dto.accounts.PatientDto) :return: (api.accounts.PatientApiModel) """ asserts.type_of(patient_dto, PatientDto) patient_api = PatientApiModel() map_props(patient_api, patient_dto, PatientDto._props) return patient_api.ToMessage()
def to_job_dto(cls, job_api): """Translates the given JobApiModel to a JobDto. :param job_api: (api.jobs.JobApiModel) :return: (dto.jobs.JobDto) """ asserts.type_of(job_api, JobApiModel) job_dto = JobDto() map_props(job_dto, job_api, JobDto._props) return job_dto
def from_job_ndb(cls, job_ndb): """Translates the given Job to JobDto. :param job_ndb: (kinds.jobs.Job) :return: (dto.jobs.JobDto) """ asserts.type_of(job_ndb, Job) job_dto = JobDto() map_props(job_dto, job_ndb, JobDto._props) return job_dto
def from_account_ndb(cls, account_ndb): """Builds a UserDto from the given Account NDB model. :param account_ndb: :return: """ asserts.type_of(account_ndb, Account) user_dto = UserDto() map_props(user_dto, account_ndb, cls._props) user_dto.account_id = account_ndb.id return user_dto
def to_job_ndb(cls, job_dto): """Translates the given JobDto to Job. :param job_dto: (dto.jobs.JobDto) :return: (kinds.jobs.Job) """ asserts.type_of(job_dto, JobDto) job_ndb = Job() map_props(job_ndb, job_dto, Job._props) return job_ndb
def from_result_dto(cls, result_dto): """Translates the given SearchResultDto into a SearchResultApiModel. :param result_dto: (dto.search.SearchResultDto) :return (api.search.SearchResultApiModel) """ asserts.type_of(result_dto, SearchResultDto) result_api = SearchResultApiModel( user=UserApiModel.from_user_dto(result_dto.user)) map_props(result_api, result_dto, SearchResultDto._props) return result_api.ToMessage()
def to_account_ndb(cls, account_dto): """Translates the given AccountDto to Account NDB model. :param account_dto: (dto.accounts.AccountDto) :return: (kinds.accounts.Account) """ asserts.type_of(account_dto, AccountDto) # For now, the attributes map 1:1. It will not always be the case. # For example, convert enum values to enum indices. account_ndb = Account() map_props(account_ndb, account_dto, cls._props) return account_ndb
def login(email, password_raw, auth_id_pre='local:'): """Checks if given credentials are valid. :param email: (str) Email address. :param password_raw: (str) Raw password. :param auth_id_pre: (str) Auth ID prefix. :return: (dto.accounts.AccountDto) or (None) """ asserts.type_of(email, basestring) asserts.type_of(password_raw, basestring) email = email.lower() auth_id = auth_id_pre + email account = Account.get_by_auth_password(auth_id, password_raw) return AccountDto.from_account_ndb(account)
def from_message_dto(cls, message_dto): """Translates the given MessageDto to a MessageApiModel. :param message_dto: (dto.messages.MessageDto) :return (api.messages.MessageApiModel) """ asserts.type_of(message_dto, MessageDto) message_api = MessageApiModel( id=message_dto.id, thread_id=message_dto.thread_id, created=message_dto.created, text=message_dto.text, sender=UserApiModel.from_user_dto(message_dto.sender), ) return message_api.ToMessage()