def _get_case_payload_batched(self, response, user, last_sync, synclog): synclog.save(**get_safe_write_kwargs()) sync_operation = BatchedCaseSyncOperation(user, last_sync) for batch in sync_operation.batches(): logger.debug(batch) # case blocks case_xml_elements = ( xml.get_case_element(op.case, op.required_updates, self.version) for op in batch.case_updates_to_sync ) for case_elem in case_xml_elements: response.append(case_elem) sync_state = sync_operation.global_state synclog.cases_on_phone = sync_state.actual_owned_cases synclog.dependent_cases_on_phone = sync_state.actual_extended_cases synclog.save(**get_safe_write_kwargs()) # commtrack balance sections commtrack_elements = self.get_stock_payload(sync_state.all_synced_cases) for ct_elem in commtrack_elements: response.append(ct_elem) return response
def request_new_domain(request, form, org, domain_type=None, new_user=True): now = datetime.utcnow() current_user = CouchUser.from_django_user(request.user) commtrack_enabled = domain_type == 'commtrack' dom_req = RegistrationRequest() if new_user: dom_req.request_time = now dom_req.request_ip = get_ip(request) dom_req.activation_guid = uuid.uuid1().hex new_domain = Domain( name=form.cleaned_data['domain_name'], is_active=False, date_created=datetime.utcnow(), commtrack_enabled=commtrack_enabled, creating_user=current_user.username, secure_submissions=True, ) if form.cleaned_data.get('domain_timezone'): new_domain.default_timezone = form.cleaned_data['domain_timezone'] if org: new_domain.organization = org new_domain.hr_name = request.POST.get('domain_hrname', None) or new_domain.name if not new_user: new_domain.is_active = True # ensure no duplicate domain documents get created on cloudant new_domain.save(**get_safe_write_kwargs()) if not new_domain.name: new_domain.name = new_domain._id new_domain.save() # we need to get the name from the _id create_30_day_trial(new_domain) dom_req.domain = new_domain.name if request.user.is_authenticated(): if not current_user: current_user = WebUser() current_user.sync_from_django_user(request.user) current_user.save() current_user.add_domain_membership(new_domain.name, is_admin=True) current_user.save() dom_req.requesting_user_username = request.user.username dom_req.new_user_username = request.user.username if new_user: dom_req.save() send_domain_registration_email(request.user.email, dom_req.domain, dom_req.activation_guid) else: send_global_domain_registration_email(request.user, new_domain.name) send_new_request_update_email(request.user, get_ip(request), new_domain.name, is_new_user=new_user)
def save_verified_number(self, domain, phone_number, verified, backend_id, ivr_backend_id=None, only_one_number_allowed=False): """ Saves the given phone number as this contact's verified phone number. return The VerifiedNumber raises InvalidFormatException if the phone number format is invalid raises PhoneNumberInUseException if the phone number is already in use by another contact """ phone_number = apply_leniency(phone_number) self.verify_unique_number(phone_number) if only_one_number_allowed: v = self.get_verified_number() else: v = self.get_verified_number(phone_number) if v is None: v = VerifiedNumber( owner_doc_type = self.doc_type, owner_id = self._id ) v.domain = domain v.phone_number = phone_number v.verified = verified v.backend_id = backend_id v.ivr_backend_id = ivr_backend_id v.save(**get_safe_write_kwargs()) return v
def testAttachmentsRemoved(self): db = get_db() res = db.save_doc( { '#export_tag': 'tag', 'tag': 'attachments-test', 'p1': 'v1', }, **get_safe_write_kwargs()) doc = db.get(res['id']) doc['_attachments'] = { "attach.txt": { "content_type": "text/plain", "data": "some content", }, } db.save_doc(doc) config = ExportConfiguration(db, ['attachments-test'], cleanup_fn=None) schema = config.get_latest_schema() self.assertTrue('_attachments' in schema) docs = list(config.get_docs()) self.assertEqual(1, len(docs)) self.assertTrue('_attachments' in docs[0]) # check that it works both explicitly and by default explicit_config = ExportConfiguration(db, ['attachments-test'], cleanup_fn=clear_attachments) default_config = ExportConfiguration(db, ['attachments-test']) for config in (explicit_config, default_config): schema = config.get_latest_schema() self.assertFalse('_attachments' in schema) docs = list(config.get_docs()) self.assertEqual(1, len(docs)) self.assertFalse('_attachments' in docs[0])
def save_verified_number(self, domain, phone_number, verified, backend_id=None, ivr_backend_id=None, only_one_number_allowed=False): """ Saves the given phone number as this contact's verified phone number. backend_id - the name of an SMSBackend to use when sending SMS to this number; if specified, this will override any project or global settings for which backend will be used to send sms to this number return The VerifiedNumber raises InvalidFormatException if the phone number format is invalid raises PhoneNumberInUseException if the phone number is already in use by another contact """ phone_number = apply_leniency(phone_number) self.verify_unique_number(phone_number) if only_one_number_allowed: v = self.get_verified_number() else: v = self.get_verified_number(phone_number) if v is None: v = VerifiedNumber( owner_doc_type = self.doc_type, owner_id = self._id ) v.domain = domain v.phone_number = phone_number v.verified = verified v.backend_id = backend_id v.ivr_backend_id = ivr_backend_id v.save(**get_safe_write_kwargs()) return v
def update_indicator(self, indicator_def, save_on_update=True, logger=None): existing_indicators = self.computed_.get(indicator_def.namespace, {}) updated_indicators, is_update = indicator_def.update_computed_namespace( existing_indicators, self) if is_update: self.computed_[indicator_def.namespace] = updated_indicators self.computed_modified_on_ = datetime.datetime.utcnow() if logger: logger.info( "[INDICATOR %(namespace)s %(domain)s] Updating %(indicator_type)s:%(indicator_slug)s " "in %(document_type)s [%(document_id)s]." % { 'namespace': indicator_def.namespace, 'domain': indicator_def.domain, 'indicator_type': indicator_def.__class__.__name__, 'indicator_slug': indicator_def.slug, 'document_type': self.__class__.__name__, 'document_id': self._id, }) if save_on_update: self.save(**get_safe_write_kwargs()) if logger: logger.debug("Saved %s." % self._id) return is_update
def bootstrap_domain(domain_name=TEST_DOMAIN): # little test utility that makes a commtrack-enabled domain with # a default config and a location domain_obj = create_domain(domain_name) domain_obj.commtrack_enabled = True domain_obj.save(**get_safe_write_kwargs()) return domain_obj
def test_get_last(self): indices = ["a string", ["a", "list"]] save_args = get_safe_write_kwargs() for index in indices: self.addCleanup( lambda idx: [cp.delete() for cp in ExportSchema.get_all_checkpoints(idx)], index) for index in indices: self.assertEqual(None, ExportSchema.last(index)) dt = datetime.utcnow() schema1 = ExportSchema(index=index, timestamp=dt) schema1.save(**save_args) self.assert_docs_equal(schema1, ExportSchema.last(index)) schema2 = ExportSchema(index=index, timestamp=dt + timedelta(seconds=1)) schema2.save(**save_args) self.assert_docs_equal(schema2, ExportSchema.last(index)) schema3 = ExportSchema(index=index, timestamp=dt - timedelta(seconds=1)) schema3.save(**save_args) # still schema2 (which has a later date than schema3) self.assert_docs_equal(schema2, ExportSchema.last(index))
def update_indicators_in_bulk(self, indicators, save_on_update=True, logger=None): is_update = False for indicator in indicators: try: if self.update_indicator(indicator, save_on_update=False, logger=logger): is_update = True except Exception: logger.exception("[INDICATOR %(namespace)s %(domain)s] Failed to update %(indicator_type)s: " "%(indicator_slug)s in %(document_type)s [%(document_id)s]." % { 'namespace': indicator.namespace, 'domain': indicator.domain, 'indicator_type': indicator.__class__.__name__, 'indicator_slug': indicator.slug, 'document_type': self.__class__.__name__, 'document_id': self._id, }) if is_update and save_on_update: try: self.save(**get_safe_write_kwargs()) if logger: logger.info("Saved %s." % self._id) except ResourceConflict: logger.error("[INDICATOR %(domain)s] Resource conflict failed to save document indicators for " "%(document_type)s [%(document_id)s]." % { 'domain': self.domain, 'document_type': self.__class__.__name__, 'document_id': self._id, }) return is_update
def bootstrap_domain(domain_name): # little test utility that makes a commtrack-enabled domain with # a default config and a location domain_obj = create_domain(domain_name) domain_obj.save(**get_safe_write_kwargs()) domain_obj.convert_to_commtrack() return domain_obj
def testComputedRemoved(self): db = get_db() db.save_doc( { '#export_tag': 'tag', 'tag': 'computed-test', 'p1': 'v1', 'computed_': { 'ignore': 'this stuff' } }, **get_safe_write_kwargs()) config = ExportConfiguration(db, ['computed-test'], cleanup_fn=None) schema = config.get_latest_schema() self.assertTrue('computed_' in schema) docs = list(config.get_docs()) self.assertEqual(1, len(docs)) self.assertTrue('computed_' in docs[0]) # check that it works both explicitly and by default explicit_config = ExportConfiguration(db, ['computed-test'], cleanup_fn=clear_computed) default_config = ExportConfiguration(db, ['computed-test']) for config in (explicit_config, default_config): schema = config.get_latest_schema() self.assertFalse('computed_' in schema) docs = list(config.get_docs()) self.assertEqual(1, len(docs)) self.assertFalse('computed_' in docs[0])
def testComputedRemoved(self): db = get_db() db.save_doc({ '#export_tag': 'tag', 'tag': 'computed-test', 'p1': 'v1', 'computed_': { 'ignore': 'this stuff' } }, **get_safe_write_kwargs() ) config = ExportConfiguration(db, ['computed-test'], cleanup_fn=None) schema = config.get_latest_schema() self.assertTrue('computed_' in schema) docs = list(config.get_docs()) self.assertEqual(1, len(docs)) self.assertTrue('computed_' in docs[0]) # check that it works both explicitly and by default explicit_config = ExportConfiguration(db, ['computed-test'], cleanup_fn=clear_computed) default_config = ExportConfiguration(db, ['computed-test']) for config in (explicit_config, default_config): schema = config.get_latest_schema() self.assertFalse('computed_' in schema) docs = list(config.get_docs()) self.assertEqual(1, len(docs)) self.assertFalse('computed_' in docs[0])
def save_verified_number(self, domain, phone_number, verified, backend_id, ivr_backend_id=None, only_one_number_allowed=False): """ Saves the given phone number as this contact's verified phone number. return The VerifiedNumber raises InvalidFormatException if the phone number format is invalid raises PhoneNumberInUseException if the phone number is already in use by another contact """ phone_number = apply_leniency(phone_number) self.verify_unique_number(phone_number) if only_one_number_allowed: v = self.get_verified_number() else: v = self.get_verified_number(phone_number) if v is None: v = VerifiedNumber(owner_doc_type=self.doc_type, owner_id=self._id) v.domain = domain v.phone_number = phone_number v.verified = verified v.backend_id = backend_id v.ivr_backend_id = ivr_backend_id v.save(**get_safe_write_kwargs()) return v
def save_verified_number(self, domain, phone_number, verified, backend_id=None, ivr_backend_id=None, only_one_number_allowed=False): """ Saves the given phone number as this contact's verified phone number. backend_id - the name of an SMSBackend to use when sending SMS to this number; if specified, this will override any project or global settings for which backend will be used to send sms to this number return The VerifiedNumber raises InvalidFormatException if the phone number format is invalid raises PhoneNumberInUseException if the phone number is already in use by another contact """ phone_number = apply_leniency(phone_number) self.verify_unique_number(phone_number) if only_one_number_allowed: v = self.get_verified_number() else: v = self.get_verified_number(phone_number) if v is None: v = VerifiedNumber(owner_doc_type=self.doc_type, owner_id=self._id) v.domain = domain v.phone_number = phone_number v.verified = verified v.backend_id = backend_id v.ivr_backend_id = ivr_backend_id v.save(**get_safe_write_kwargs()) return v
def _get_case_payload(self, response, user, last_sync, synclog): sync_operation = user.get_case_updates(last_sync) synclog.cases_on_phone = [ CaseState.from_case(c) for c in sync_operation.actual_owned_cases ] synclog.dependent_cases_on_phone = [ CaseState.from_case(c) for c in sync_operation.actual_extended_cases ] synclog.save(**get_safe_write_kwargs()) # case blocks case_xml_elements = ( xml.get_case_element(op.case, op.required_updates, self.version) for op in sync_operation.actual_cases_to_sync ) for case_elem in case_xml_elements: response.append(case_elem) # commtrack balance sections case_state_list = [CaseState.from_case(op.case) for op in sync_operation.actual_cases_to_sync] commtrack_elements = self.get_stock_payload(case_state_list) for ct_elem in commtrack_elements: response.append(ct_elem) return response
def testAttachmentsRemoved(self): db = get_db() res = db.save_doc({ '#export_tag': 'tag', 'tag': 'attachments-test', 'p1': 'v1', }, **get_safe_write_kwargs() ) doc = db.get(res['id']) doc['_attachments'] = { "attach.txt": { "content_type": "text/plain", "data": "some content", }, } db.save_doc(doc) config = ExportConfiguration(db, ['attachments-test'], cleanup_fn=None) schema = config.get_latest_schema() self.assertTrue('_attachments' in schema) docs = list(config.get_docs()) self.assertEqual(1, len(docs)) self.assertTrue('_attachments' in docs[0]) # check that it works both explicitly and by default explicit_config = ExportConfiguration(db, ['attachments-test'], cleanup_fn=clear_attachments) default_config = ExportConfiguration(db, ['attachments-test']) for config in (explicit_config, default_config): schema = config.get_latest_schema() self.assertFalse('_attachments' in schema) docs = list(config.get_docs()) self.assertEqual(1, len(docs)) self.assertFalse('_attachments' in docs[0])
def get_or_create_with_name(cls, name, is_active=False): result = cls.view("domain/domains", key=name, reduce=False, include_docs=True).first() if result: return result else: new_domain = Domain(name=name, is_active=is_active, date_created=datetime.utcnow()) new_domain.save(**get_safe_write_kwargs()) return new_domain
def request_new_domain(request, form, org, domain_type=None, new_user=True): now = datetime.utcnow() current_user = CouchUser.from_django_user(request.user) commtrack_enabled = domain_type == 'commtrack' dom_req = RegistrationRequest() if new_user: dom_req.request_time = now dom_req.request_ip = get_ip(request) dom_req.activation_guid = uuid.uuid1().hex new_domain = Domain(name=form.cleaned_data['domain_name'], is_active=False, date_created=datetime.utcnow(), commtrack_enabled=commtrack_enabled, creating_user=current_user.username) bootstrap_default(new_domain) if org: new_domain.organization = org new_domain.hr_name = request.POST.get('domain_hrname', None) or new_domain.name if not new_user: new_domain.is_active = True # ensure no duplicate domain documents get created on cloudant new_domain.save(**get_safe_write_kwargs()) if not new_domain.name: new_domain.name = new_domain._id new_domain.save() # we need to get the name from the _id dom_req.domain = new_domain.name if request.user.is_authenticated(): if not current_user: current_user = WebUser() current_user.sync_from_django_user(request.user) current_user.save() current_user.add_domain_membership(new_domain.name, is_admin=True) current_user.save() dom_req.requesting_user_username = request.user.username dom_req.new_user_username = request.user.username if new_user: dom_req.save() send_domain_registration_email(request.user.email, dom_req.domain, dom_req.activation_guid) else: send_global_domain_registration_email(request.user, new_domain.name) send_new_domain_request_update_email(request.user, get_ip(request), new_domain.name, is_new_user=new_user)
def get_payload(self): user = self.user last_sync = self.sync_log self.validate() cached_payload = self.get_cached_payload() if cached_payload: return cached_payload sync_operation = user.get_case_updates(last_sync) case_xml_elements = [ xml.get_case_element(op.case, op.required_updates, self.version) for op in sync_operation.actual_cases_to_sync ] commtrack_elements = self.get_stock_payload(sync_operation) last_seq = str(get_db().info()["update_seq"]) # create a sync log for this previous_log_id = last_sync.get_id if last_sync else None synclog = SyncLog( user_id=user.user_id, last_seq=last_seq, owner_ids_on_phone=user.get_owner_ids(), date=datetime.utcnow(), previous_log_id=previous_log_id, cases_on_phone=[CaseState.from_case(c) for c in sync_operation.actual_owned_cases], dependent_cases_on_phone=[CaseState.from_case(c) for c in sync_operation.actual_extended_cases], ) synclog.save(**get_safe_write_kwargs()) # start with standard response response = get_response_element( "Successfully restored account %s!" % user.username, ResponseNature.OTA_RESTORE_SUCCESS ) # add sync token info response.append(xml.get_sync_element(synclog.get_id)) # registration block response.append(xml.get_registration_element(user)) # fixture block for fixture in generator.get_fixtures(user, self.version, last_sync): response.append(fixture) # case blocks for case_elem in case_xml_elements: response.append(case_elem) for ct_elem in commtrack_elements: response.append(ct_elem) if self.items: response.attrib["items"] = "%d" % len(response.getchildren()) resp = xml.tostring(response) self.set_cached_payload_if_enabled(resp) return resp
def bootstrap_domain(domain_name=TEST_DOMAIN, requisitions_enabled=False): # little test utility that makes a commtrack-enabled domain with # a default config and a location domain_obj = create_domain(domain_name) domain_obj.commtrack_enabled = True domain_obj.save(**get_safe_write_kwargs()) bootstrap_commtrack_settings_if_necessary(domain_obj, requisitions_enabled) return domain_obj
def create_sync_log(self): previous_log_id = None if self.is_initial else self.last_sync_log._id last_seq = str(get_db().info()["update_seq"]) new_synclog = SyncLog(user_id=self.user.user_id, last_seq=last_seq, owner_ids_on_phone=list(self.owner_ids), date=datetime.utcnow(), previous_log_id=previous_log_id) new_synclog.save(**get_safe_write_kwargs()) return new_synclog
def bootstrap(id=None, to_console=''): """ Create an instance of the test backend in the database """ backend = MobileBackend(domain=[], description='test backend', outbound_module='corehq.apps.sms.backend.test', outbound_params={'to_console': True}) if id: backend._id = id backend.save(**get_safe_write_kwargs()) return backend
def create_sync_log(self): previous_log_id = None if self.is_initial else self.last_sync_log._id last_seq = str(get_db().info()["update_seq"]) new_synclog = SyncLog( user_id=self.user.user_id, last_seq=last_seq, owner_ids_on_phone=list(self.owner_ids), date=datetime.utcnow(), previous_log_id=previous_log_id ) new_synclog.save(**get_safe_write_kwargs()) return new_synclog
def get_payload(self): """ This function currently returns either a full string payload or a string name of a file that contains the contents of the payload. If FILE_RESTORE toggle is enabled, then this will return the filename, otherwise it will return the full string payload """ user = self.user last_synclog = self.sync_log self.validate() cached_response = self.get_cached_payload() if cached_response.exists(): return cached_response start_time = datetime.utcnow() last_seq = str(get_db().info()["update_seq"]) # create a sync log for this previous_log_id = last_synclog.get_id if last_synclog else None new_synclog = SyncLog( user_id=user.user_id, last_seq=last_seq, owner_ids_on_phone=user.get_owner_ids(), date=datetime.utcnow(), previous_log_id=previous_log_id ) new_synclog.save(**get_safe_write_kwargs()) # start with standard response with get_restore_class(user)(user.username, items=self.items) as response: # add sync token info response.append(xml.get_sync_element(new_synclog.get_id)) # registration block response.append(xml.get_registration_element(user)) # fixture block for fixture in generator.get_fixtures(user, self.version, last_synclog): response.append(fixture) case_response, self.num_batches = get_case_payload_batched( self.domain, self.stock_settings, self.version, user, last_synclog, new_synclog ) combined_response = response + case_response case_response.close() combined_response.finalize() duration = datetime.utcnow() - start_time new_synclog.duration = duration.seconds new_synclog.save() self.set_cached_payload_if_necessary(combined_response, duration) return combined_response
def get_payload(self): user = self.user last_sync = self.sync_log self.validate() cached_payload = self.get_cached_payload() if cached_payload: return cached_payload start_time = datetime.utcnow() last_seq = str(get_db().info()["update_seq"]) # create a sync log for this previous_log_id = last_sync.get_id if last_sync else None synclog = SyncLog( user_id=user.user_id, last_seq=last_seq, owner_ids_on_phone=user.get_owner_ids(), date=datetime.utcnow(), previous_log_id=previous_log_id ) synclog.save(**get_safe_write_kwargs()) # start with standard response batch_enabled = BATCHED_RESTORE.enabled(self.user.domain) or BATCHED_RESTORE.enabled(self.user.username) logger.debug('Batch restore enabled: %s', batch_enabled) if batch_enabled: response = StringRestoreResponse(user.username, items=self.items) else: response = EtreeRestoreResponse(user.username, items=self.items) # add sync token info response.append(xml.get_sync_element(synclog.get_id)) # registration block response.append(xml.get_registration_element(user)) # fixture block for fixture in generator.get_fixtures(user, self.version, last_sync): response.append(fixture) payload_fn = self._get_case_payload_batched if batch_enabled else self._get_case_payload response = payload_fn(response, user, last_sync, synclog) resp = str(response) duration = datetime.utcnow() - start_time synclog.duration = duration.seconds synclog.save() add_custom_parameter('restore_response_size', response.num_items) self.set_cached_payload_if_necessary(resp, duration) return resp
def bootstrap(id=None, to_console=True): """ Create an instance of the test backend in the database """ backend = TestBackend( description='test backend', is_global=True, to_console=to_console, ) if id: backend._id = id backend.name = id.strip().upper() backend.save(**get_safe_write_kwargs()) return backend
def bootstrap(id=None, to_console=''): """ Create an instance of the test backend in the database """ backend = MobileBackend( domain=[], description='test backend', outbound_module='corehq.apps.sms.backend.test', outbound_params={'to_console': True} ) if id: backend._id = id backend.save(**get_safe_write_kwargs()) return backend
def post_from_settings(instance, extras=None): extras = extras or {} # HACK: for cloudant force update all nodes at once # to prevent 412 race condition extras.update(get_safe_write_kwargs()) url = settings.XFORMS_POST_URL if not extras else "%s?%s" % \ (settings.XFORMS_POST_URL, urllib.urlencode(extras)) if settings.COUCH_USERNAME: return post_authenticated_data(instance, url, settings.COUCH_USERNAME, settings.COUCH_PASSWORD) else: return post_unauthenticated_data(instance, url)
def get_or_create_with_name(cls, name, is_active=False, secure_submissions=True): result = cls.view("domain/domains", key=name, reduce=False, include_docs=True).first() if result: return result else: new_domain = Domain( name=name, is_active=is_active, date_created=datetime.utcnow(), secure_submissions=secure_submissions, ) new_domain.migrations = DomainMigrations(has_migrated_permissions=True) new_domain.save(**get_safe_write_kwargs()) return new_domain
def get_or_create_with_name(cls, name, is_active=False, secure_submissions=True, use_sql_backend=False): result = cls.view("domain/domains", key=name, reduce=False, include_docs=True).first() if result: return result else: new_domain = Domain( name=name, is_active=is_active, date_created=datetime.utcnow(), secure_submissions=secure_submissions, use_livequery=True, use_sql_backend=use_sql_backend, ) new_domain.save(**get_safe_write_kwargs()) return new_domain
def testGetLast(self): indices = ["a string", ["a", "list"]] save_args = get_safe_write_kwargs() for index in indices: self.assertEqual(None, ExportSchema.last(index)) dt = datetime.utcnow() schema1 = ExportSchema(index=index, timestamp=dt) schema1.save(**save_args) self.assertEqual(schema1._id, ExportSchema.last(index)._id) schema2 = ExportSchema(index=index, timestamp=dt + timedelta(seconds=1)) schema2.save(**save_args) self.assertEqual(schema2._id, ExportSchema.last(index)._id) schema3 = ExportSchema(index=index, timestamp=dt - timedelta(seconds=1)) schema3.save(**save_args) self.assertEqual(schema2._id, ExportSchema.last(index)._id)
def get_case_payload_batched(domain, stock_settings, version, user, last_synclog, new_synclog): response = get_restore_class(user)() sync_operation = BatchedCaseSyncOperation(user, last_synclog) for update in sync_operation.get_all_case_updates(): element = xml.get_case_element(update.case, update.required_updates, version) response.append(element) sync_state = sync_operation.global_state new_synclog.cases_on_phone = sync_state.actual_owned_cases new_synclog.dependent_cases_on_phone = sync_state.actual_extended_cases new_synclog.save(**get_safe_write_kwargs()) # commtrack balance sections commtrack_elements = get_stock_payload(domain, stock_settings, sync_state.all_synced_cases) response.extend(commtrack_elements) return response, sync_operation.batch_count
def testGetLast(self): indices = ["a string", ["a", "list"]] save_args = get_safe_write_kwargs() for index in indices: self.assertEqual(None, ExportSchema.last(index)) # by design, if something has a timestamp it always wins out, even # if something has a higher seq dt = datetime.utcnow() schema1 = ExportSchema(seq="2", index=index, timestamp=dt) schema1.save(**save_args) self.assertEqual(schema1._id, ExportSchema.last(index)._id) schema2 = ExportSchema(seq="1", index=index, timestamp=dt + timedelta(seconds=1)) schema2.save(**save_args) self.assertEqual(schema2._id, ExportSchema.last(index)._id) schema3 = ExportSchema(seq="3", index=index, timestamp=dt - timedelta(seconds=1)) schema3.save(**save_args) self.assertEqual(schema2._id, ExportSchema.last(index)._id)
def update_indicator(self, indicator_def, save_on_update=True, logger=None): existing_indicators = self.computed_.get(indicator_def.namespace, {}) updated_indicators, is_update = indicator_def.update_computed_namespace(existing_indicators, self) if is_update: self.computed_[indicator_def.namespace] = updated_indicators self.computed_modified_on_ = datetime.datetime.utcnow() if logger: logger.info("[INDICATOR %(namespace)s %(domain)s] Updating %(indicator_type)s:%(indicator_slug)s " "in %(document_type)s [%(document_id)s]." % { 'namespace': indicator_def.namespace, 'domain': indicator_def.domain, 'indicator_type': indicator_def.__class__.__name__, 'indicator_slug': indicator_def.slug, 'document_type': self.__class__.__name__, 'document_id': self._id, }) if save_on_update: self.save(**get_safe_write_kwargs()) if logger: logger.debug("Saved %s." % self._id) return is_update
def get_or_create_with_name(cls, name, is_active=False, secure_submissions=True): result = cls.view("domain/domains", key=name, reduce=False, include_docs=True).first() if result: return result else: new_domain = Domain( name=name, is_active=is_active, date_created=datetime.utcnow(), secure_submissions=secure_submissions, ) new_domain.migrations = DomainMigrations( has_migrated_permissions=True) new_domain.save(**get_safe_write_kwargs()) return new_domain
def update_indicators_in_bulk(self, indicators, save_on_update=True, logger=None): is_update = False for indicator in indicators: try: if self.update_indicator(indicator, save_on_update=False, logger=logger): is_update = True except Exception: logger.exception( "[INDICATOR %(namespace)s %(domain)s] Failed to update %(indicator_type)s: " "%(indicator_slug)s in %(document_type)s [%(document_id)s]." % { 'namespace': indicator.namespace, 'domain': indicator.domain, 'indicator_type': indicator.__class__.__name__, 'indicator_slug': indicator.slug, 'document_type': self.__class__.__name__, 'document_id': self._id, }) if is_update and save_on_update: try: self.save(**get_safe_write_kwargs()) if logger: logger.info("Saved %s." % self._id) except ResourceConflict: logger.error( "[INDICATOR %(domain)s] Resource conflict failed to save document indicators for " "%(document_type)s [%(document_id)s]." % { 'domain': self.domain, 'document_type': self.__class__.__name__, 'document_id': self._id, }) return is_update
def test_get_last(self): indices = ["a string", ["a", "list"]] save_args = get_safe_write_kwargs() for index in indices: self.addCleanup( lambda idx: [cp.delete() for cp in ExportSchema.get_all_checkpoints(idx)], index ) for index in indices: self.assertEqual(None, ExportSchema.last(index)) dt = datetime.utcnow() schema1 = ExportSchema(index=index, timestamp=dt) schema1.save(**save_args) self.assert_docs_equal(schema1, ExportSchema.last(index)) schema2 = ExportSchema(index=index, timestamp=dt + timedelta(seconds=1)) schema2.save(**save_args) self.assert_docs_equal(schema2, ExportSchema.last(index)) schema3 = ExportSchema(index=index, timestamp=dt - timedelta(seconds=1)) schema3.save(**save_args) # still schema2 (which has a later date than schema3) self.assert_docs_equal(schema2, ExportSchema.last(index))
def testComputedRemoved(self): db = get_db() db.save_doc( {"#export_tag": "tag", "tag": "computed-test", "p1": "v1", "computed_": {"ignore": "this stuff"}}, **get_safe_write_kwargs() ) config = ExportConfiguration(db, ["computed-test"], cleanup_fn=None) schema = config.get_latest_schema() self.assertTrue("computed_" in schema) docs = list(config.get_docs()) self.assertEqual(1, len(docs)) self.assertTrue("computed_" in docs[0]) # check that it works both explicitly and by default explicit_config = ExportConfiguration(db, ["computed-test"], cleanup_fn=clear_computed) default_config = ExportConfiguration(db, ["computed-test"]) for config in (explicit_config, default_config): schema = config.get_latest_schema() self.assertFalse("computed_" in schema) docs = list(config.get_docs()) self.assertEqual(1, len(docs)) self.assertFalse("computed_" in docs[0])
for op in sync_operation.actual_cases_to_sync] commtrack_elements = self.get_stock_payload(sync_operation) last_seq = str(get_db().info()["update_seq"]) # create a sync log for this previous_log_id = last_sync.get_id if last_sync else None synclog = SyncLog(user_id=user.user_id, last_seq=last_seq, owner_ids_on_phone=user.get_owner_ids(), date=datetime.utcnow(), previous_log_id=previous_log_id, cases_on_phone=[CaseState.from_case(c) for c in \ sync_operation.actual_owned_cases], dependent_cases_on_phone=[CaseState.from_case(c) for c in \ sync_operation.actual_extended_cases]) synclog.save(**get_safe_write_kwargs()) # start with standard response response = get_response_element( "Successfully restored account %s!" % user.username, ResponseNature.OTA_RESTORE_SUCCESS) # add sync token info response.append(xml.get_sync_element(synclog.get_id)) # registration block response.append(xml.get_registration_element(user)) # fixture block for fixture in generator.get_fixtures(user, self.version, last_sync): response.append(fixture) # case blocks for case_elem in case_xml_elements:
def request_new_domain(request, form, is_new_user=True): now = datetime.utcnow() current_user = CouchUser.from_django_user(request.user, strict=True) dom_req = RegistrationRequest() if is_new_user: dom_req.request_time = now dom_req.request_ip = get_ip(request) dom_req.activation_guid = uuid.uuid1().hex project_name = form.cleaned_data.get('hr_name') or form.cleaned_data.get( 'project_name') name = name_to_url(project_name, "project") with CriticalSection(['request_domain_name_{}'.format(name)]): name = Domain.generate_name(name) new_domain = Domain(name=name, hr_name=project_name, is_active=False, date_created=datetime.utcnow(), creating_user=current_user.username, secure_submissions=True, use_sql_backend=True, first_domain_for_user=is_new_user) # Avoid projects created by dimagi.com staff members as self started new_domain.internal.self_started = not current_user.is_dimagi if form.cleaned_data.get('domain_timezone'): new_domain.default_timezone = form.cleaned_data['domain_timezone'] if not is_new_user: new_domain.is_active = True # ensure no duplicate domain documents get created on cloudant new_domain.save(**get_safe_write_kwargs()) if not new_domain.name: new_domain.name = new_domain._id new_domain.save() # we need to get the name from the _id dom_req.domain = new_domain.name if not settings.ENTERPRISE_MODE: _setup_subscription(new_domain.name, current_user) UserRole.init_domain_with_presets(new_domain.name) if request.user.is_authenticated: if not current_user: current_user = WebUser() current_user.sync_from_django_user(request.user) current_user.save() current_user.add_domain_membership(new_domain.name, is_admin=True) current_user.save() dom_req.requesting_user_username = request.user.username dom_req.new_user_username = request.user.username elif is_new_user: _soft_assert_registration_issues( f"A new user {request.user.username} was not added to their domain " f"{new_domain.name} during registration") if is_new_user: dom_req.save() if settings.IS_SAAS_ENVIRONMENT: # Load template apps to the user's new domain in parallel from corehq.apps.app_manager.tasks import load_appcues_template_app header = [ load_appcues_template_app.si(new_domain.name, current_user.username, slug) for slug in APPCUES_APP_SLUGS ] callback = send_domain_registration_email.si( request.user.email, dom_req.domain, dom_req.activation_guid, request.user.get_full_name(), request.user.first_name) chord(header)(callback) else: send_domain_registration_email(request.user.email, dom_req.domain, dom_req.activation_guid, request.user.get_full_name(), request.user.first_name) send_new_request_update_email(request.user, get_ip(request), new_domain.name, is_new_user=is_new_user) send_hubspot_form(HUBSPOT_CREATED_NEW_PROJECT_SPACE_FORM_ID, request) return new_domain.name
def request_new_domain(request, form, is_new_user=True): now = datetime.utcnow() current_user = CouchUser.from_django_user(request.user) dom_req = RegistrationRequest() if is_new_user: dom_req.request_time = now dom_req.request_ip = get_ip(request) dom_req.activation_guid = uuid.uuid1().hex project_name = form.cleaned_data.get('hr_name') or form.cleaned_data.get( 'project_name') name = name_to_url(project_name, "project") with CriticalSection(['request_domain_name_{}'.format(name)]): name = Domain.generate_name(name) new_domain = Domain(name=name, hr_name=project_name, is_active=False, date_created=datetime.utcnow(), creating_user=current_user.username, secure_submissions=True, use_sql_backend=True, first_domain_for_user=is_new_user) if form.cleaned_data.get('domain_timezone'): new_domain.default_timezone = form.cleaned_data['domain_timezone'] if not is_new_user: new_domain.is_active = True # ensure no duplicate domain documents get created on cloudant new_domain.save(**get_safe_write_kwargs()) if not new_domain.name: new_domain.name = new_domain._id new_domain.save() # we need to get the name from the _id if is_new_user: # Only new-user domains are eligible for Advanced trial # domains with no subscription are equivalent to be on free Community plan create_30_day_advanced_trial(new_domain, current_user.username) else: ensure_explicit_community_subscription(new_domain.name, date.today()) UserRole.init_domain_with_presets(new_domain.name) # add user's email as contact email for billing account for the domain account = BillingAccount.get_account_by_domain(new_domain.name) billing_contact, _ = BillingContactInfo.objects.get_or_create( account=account) billing_contact.email_list = [current_user.email] billing_contact.save() dom_req.domain = new_domain.name if request.user.is_authenticated(): if not current_user: current_user = WebUser() current_user.sync_from_django_user(request.user) current_user.save() current_user.add_domain_membership(new_domain.name, is_admin=True) current_user.save() dom_req.requesting_user_username = request.user.username dom_req.new_user_username = request.user.username if is_new_user: dom_req.save() send_domain_registration_email(request.user.email, dom_req.domain, dom_req.activation_guid, request.user.get_full_name()) send_new_request_update_email(request.user, get_ip(request), new_domain.name, is_new_user=is_new_user) meta = get_meta(request) track_created_new_project_space_on_hubspot.delay(current_user, request.COOKIES, meta) return new_domain.name
def request_new_domain(request, form, org, domain_type=None, new_user=True): now = datetime.utcnow() current_user = CouchUser.from_django_user(request.user) commtrack_enabled = domain_type == 'commtrack' dom_req = RegistrationRequest() if new_user: dom_req.request_time = now dom_req.request_ip = get_ip(request) dom_req.activation_guid = uuid.uuid1().hex new_domain = Domain( name=form.cleaned_data['domain_name'], is_active=False, date_created=datetime.utcnow(), commtrack_enabled=commtrack_enabled, creating_user=current_user.username, secure_submissions=True, ) if form.cleaned_data.get('domain_timezone'): new_domain.default_timezone = form.cleaned_data['domain_timezone'] if org: new_domain.organization = org new_domain.hr_name = request.POST.get('domain_hrname', None) or new_domain.name if not new_user: new_domain.is_active = True # ensure no duplicate domain documents get created on cloudant new_domain.save(**get_safe_write_kwargs()) if not new_domain.name: new_domain.name = new_domain._id new_domain.save() # we need to get the name from the _id # Create a 30 Day Trial subscription to the Advanced Plan advanced_plan_version = DefaultProductPlan.get_default_plan_by_domain( new_domain, edition=SoftwarePlanEdition.ADVANCED, is_trial=True ) expiration_date = date.today() + timedelta(days=30) trial_account = BillingAccount.objects.get_or_create( name="Trial Account for %s" % new_domain.name, currency=Currency.get_default(), created_by_domain=new_domain.name, account_type=BillingAccountType.TRIAL, )[0] trial_subscription = Subscription.new_domain_subscription( trial_account, new_domain.name, advanced_plan_version, date_end=expiration_date, adjustment_method=SubscriptionAdjustmentMethod.TRIAL, is_trial=True, ) trial_subscription.is_active = True trial_subscription.save() dom_req.domain = new_domain.name if request.user.is_authenticated(): if not current_user: current_user = WebUser() current_user.sync_from_django_user(request.user) current_user.save() current_user.add_domain_membership(new_domain.name, is_admin=True) current_user.save() dom_req.requesting_user_username = request.user.username dom_req.new_user_username = request.user.username if new_user: dom_req.save() send_domain_registration_email(request.user.email, dom_req.domain, dom_req.activation_guid) else: send_global_domain_registration_email(request.user, new_domain.name) send_new_request_update_email(request.user, get_ip(request), new_domain.name, is_new_user=new_user)
def request_new_domain(request, form, org, domain_type=None, new_user=True): now = datetime.utcnow() current_user = CouchUser.from_django_user(request.user) dom_req = RegistrationRequest() if new_user: dom_req.request_time = now dom_req.request_ip = get_ip(request) dom_req.activation_guid = uuid.uuid1().hex name = form.cleaned_data['hr_name'] with CriticalSection(['request_domain_name_{}'.format(name)]): name = Domain.generate_name(name) new_domain = Domain( name=name, hr_name=form.cleaned_data['hr_name'], is_active=False, date_created=datetime.utcnow(), creating_user=current_user.username, secure_submissions=True, ) if form.cleaned_data.get('domain_timezone'): new_domain.default_timezone = form.cleaned_data['domain_timezone'] if org: new_domain.organization = org new_domain.hr_name = request.POST.get('domain_hrname', None) or new_domain.name if not new_user: new_domain.is_active = True # ensure no duplicate domain documents get created on cloudant new_domain.save(**get_safe_write_kwargs()) if domain_type == 'commtrack': new_domain.convert_to_commtrack() if not new_domain.name: new_domain.name = new_domain._id new_domain.save() # we need to get the name from the _id create_30_day_trial(new_domain) dom_req.domain = new_domain.name if request.user.is_authenticated(): if not current_user: current_user = WebUser() current_user.sync_from_django_user(request.user) current_user.save() current_user.add_domain_membership(new_domain.name, is_admin=True) current_user.save() dom_req.requesting_user_username = request.user.username dom_req.new_user_username = request.user.username if new_user: dom_req.save() send_domain_registration_email(request.user.email, dom_req.domain, dom_req.activation_guid) else: send_global_domain_registration_email(request.user, new_domain.name) send_new_request_update_email(request.user, get_ip(request), new_domain.name, is_new_user=new_user) return new_domain.name
def post_it(self, **kwargs): doc = {'#export_tag': 'tag', 'tag': 'test_custom'} doc.update(kwargs) self.db.save_doc(doc, **get_safe_write_kwargs())
def testAttachmentsRemoved(self): db = get_db() res = db.save_doc({"#export_tag": "tag", "tag": "attachments-test", "p1": "v1"}, **get_safe_write_kwargs()) doc = db.get(res["id"]) db.put_attachment(doc, "some content", "attach.txt") config = ExportConfiguration(db, ["attachments-test"], cleanup_fn=None) schema = config.get_latest_schema() self.assertTrue("_attachments" in schema) docs = list(config.get_docs()) self.assertEqual(1, len(docs)) self.assertTrue("_attachments" in docs[0]) # check that it works both explicitly and by default explicit_config = ExportConfiguration(db, ["attachments-test"], cleanup_fn=clear_attachments) default_config = ExportConfiguration(db, ["attachments-test"]) for config in (explicit_config, default_config): schema = config.get_latest_schema() self.assertFalse("_attachments" in schema) docs = list(config.get_docs()) self.assertEqual(1, len(docs)) self.assertFalse("_attachments" in docs[0])
def request_new_domain(request, form, is_new_user=True): now = datetime.utcnow() current_user = CouchUser.from_django_user(request.user, strict=True) dom_req = RegistrationRequest() if is_new_user: dom_req.request_time = now dom_req.request_ip = get_ip(request) dom_req.activation_guid = uuid.uuid1().hex project_name = form.cleaned_data.get('hr_name') or form.cleaned_data.get('project_name') name = name_to_url(project_name, "project") with CriticalSection(['request_domain_name_{}'.format(name)]): name = Domain.generate_name(name) new_domain = Domain( name=name, hr_name=project_name, is_active=False, date_created=datetime.utcnow(), creating_user=current_user.username, secure_submissions=True, use_sql_backend=True, first_domain_for_user=is_new_user ) # Avoid projects created by dimagi.com staff members as self started new_domain.internal.self_started = not current_user.is_dimagi if form.cleaned_data.get('domain_timezone'): new_domain.default_timezone = form.cleaned_data['domain_timezone'] if not is_new_user: new_domain.is_active = True # ensure no duplicate domain documents get created on cloudant new_domain.save(**get_safe_write_kwargs()) if not new_domain.name: new_domain.name = new_domain._id new_domain.save() # we need to get the name from the _id if is_new_user: # Only new-user domains are eligible for Advanced trial # domains with no subscription are equivalent to be on free Community plan create_30_day_advanced_trial(new_domain, current_user.username) else: ensure_explicit_community_subscription( new_domain.name, date.today(), SubscriptionAdjustmentMethod.USER, web_user=current_user.username, ) UserRole.init_domain_with_presets(new_domain.name) # add user's email as contact email for billing account for the domain account = BillingAccount.get_account_by_domain(new_domain.name) billing_contact, _ = BillingContactInfo.objects.get_or_create(account=account) billing_contact.email_list = [current_user.email] billing_contact.save() dom_req.domain = new_domain.name if request.user.is_authenticated: if not current_user: current_user = WebUser() current_user.sync_from_django_user(request.user) current_user.save() current_user.add_domain_membership(new_domain.name, is_admin=True) current_user.save() dom_req.requesting_user_username = request.user.username dom_req.new_user_username = request.user.username if is_new_user: dom_req.save() if settings.IS_SAAS_ENVIRONMENT: from corehq.apps.app_manager.tasks import load_appcues_template_app chain( load_appcues_template_app.si(new_domain.name, current_user.username, HEALTH_APP), load_appcues_template_app.si(new_domain.name, current_user.username, AGG_APP), load_appcues_template_app.si(new_domain.name, current_user.username, WASH_APP), send_domain_registration_email.si( request.user.email, dom_req.domain, dom_req.activation_guid, request.user.get_full_name(), request.user.first_name ) ).apply_async() else: send_domain_registration_email(request.user.email, dom_req.domain, dom_req.activation_guid, request.user.get_full_name(), request.user.first_name) send_new_request_update_email(request.user, get_ip(request), new_domain.name, is_new_user=is_new_user) send_hubspot_form(HUBSPOT_CREATED_NEW_PROJECT_SPACE_FORM_ID, request) return new_domain.name
def request_new_domain(request, form, is_new_user=True): now = datetime.utcnow() current_user = CouchUser.from_django_user(request.user, strict=True) dom_req = RegistrationRequest() if is_new_user: dom_req.request_time = now dom_req.request_ip = get_ip(request) dom_req.activation_guid = uuid.uuid1().hex project_name = form.cleaned_data.get('hr_name') or form.cleaned_data.get( 'project_name') name = name_to_url(project_name, "project") with CriticalSection(['request_domain_name_{}'.format(name)]): name = Domain.generate_name(name) new_domain = Domain(name=name, hr_name=project_name, is_active=False, date_created=datetime.utcnow(), creating_user=current_user.username, secure_submissions=True, use_sql_backend=True, first_domain_for_user=is_new_user) # Avoid projects created by dimagi.com staff members as self started new_domain.internal.self_started = not current_user.is_dimagi if form.cleaned_data.get('domain_timezone'): new_domain.default_timezone = form.cleaned_data['domain_timezone'] if not is_new_user: new_domain.is_active = True # ensure no duplicate domain documents get created on cloudant new_domain.save(**get_safe_write_kwargs()) if not new_domain.name: new_domain.name = new_domain._id new_domain.save() # we need to get the name from the _id with transaction.atomic(): if is_new_user: # Only new-user domains are eligible for Advanced trial # domains with no subscription are equivalent to be on free Community plan create_30_day_advanced_trial(new_domain, current_user.username) else: ensure_explicit_community_subscription( new_domain.name, date.today(), SubscriptionAdjustmentMethod.USER, web_user=current_user.username, ) UserRole.init_domain_with_presets(new_domain.name) # add user's email as contact email for billing account for the domain account = BillingAccount.get_account_by_domain(new_domain.name) billing_contact, _ = BillingContactInfo.objects.get_or_create( account=account) billing_contact.email_list = [current_user.email] billing_contact.save() dom_req.domain = new_domain.name if request.user.is_authenticated: if not current_user: current_user = WebUser() current_user.sync_from_django_user(request.user) current_user.save() current_user.add_domain_membership(new_domain.name, is_admin=True) current_user.save() dom_req.requesting_user_username = request.user.username dom_req.new_user_username = request.user.username if is_new_user: dom_req.save() if settings.IS_SAAS_ENVIRONMENT: # Load template apps to the user's new domain in parallel from corehq.apps.app_manager.tasks import load_appcues_template_app header = [ load_appcues_template_app.si(new_domain.name, current_user.username, slug) for slug in APPCUES_APP_SLUGS ] callback = send_domain_registration_email.si( request.user.email, dom_req.domain, dom_req.activation_guid, request.user.get_full_name(), request.user.first_name) chord(header)(callback) else: send_domain_registration_email(request.user.email, dom_req.domain, dom_req.activation_guid, request.user.get_full_name(), request.user.first_name) send_new_request_update_email(request.user, get_ip(request), new_domain.name, is_new_user=is_new_user) send_hubspot_form(HUBSPOT_CREATED_NEW_PROJECT_SPACE_FORM_ID, request) return new_domain.name