def testOTARestore(self): self.assertEqual(0, len(CommCareCase.view("case/by_user", reduce=False).all())) file_path = os.path.join(os.path.dirname(__file__), "data", "multicase", "parallel_cases.xml") with open(file_path, "rb") as f: xml_data = f.read() form = post_xform_to_couch(xml_data) process_cases(sender="testharness", xform=form) self.assertEqual(4, len(CommCareCase.view("case/by_user", reduce=False).all()))
def get_supply_point(domain, site_code): loc = Location.view('commtrack/locations_by_code', key=[domain, site_code.lower()], include_docs=True).first() if loc: case = CommCareCase.view('commtrack/supply_point_by_loc', key=[domain, loc._id], include_docs=True).first()
def testTopLevelExclusion(self): """ Entire forms tagged as device logs should be excluded """ self.assertEqual(0, len(CommCareCase.view("case/by_user", include_docs=True, reduce=False).all())) file_path = os.path.join(os.path.dirname(__file__), "data", "exclusion", "device_report.xml") with open(file_path, "rb") as f: xml_data = f.read() form = post_xform_to_couch(xml_data) process_cases(form) self.assertEqual(0, len(CommCareCase.view("case/by_user", include_docs=True, reduce=False).all()))
def testMixed(self): self.assertEqual( 0, len(CommCareCase.view("case/by_user", reduce=False).all())) file_path = os.path.join(os.path.dirname(__file__), "data", "multicase", "mixed_cases.xml") with open(file_path, "rb") as f: xml_data = f.read() form = post_xform_to_couch(xml_data) process_cases(form) self.assertEqual( 4, len(CommCareCase.view("case/by_user", reduce=False).all()))
def testLotsOfSubcases(self): """ How do we do when submitting a form with multiple blocks for the same case? """ self.assertEqual(0, len(CommCareCase.view("case/by_user", reduce=False).all())) file_path = os.path.join(os.path.dirname(__file__), "data", "bugs", "lots_of_subcases.xml") with open(file_path, "rb") as f: xml_data = f.read() form = post_xform_to_couch(xml_data) # before the bug was fixed this call failed process_cases(form) self.assertEqual(11, len(CommCareCase.view("case/by_user", reduce=False).all()))
def testNestedExclusion(self): """ Blocks inside forms tagged as device logs should be excluded """ self.assertEqual(0, len(CommCareCase.view("case/by_user", include_docs=True, reduce=False).all())) file_path = os.path.join(os.path.dirname(__file__), "data", "exclusion", "nested_device_report.xml") with open(file_path, "rb") as f: xml_data = f.read() form = post_xform_to_couch(xml_data) process_cases(form) self.assertEqual(1, len(CommCareCase.view("case/by_user", include_docs=True, reduce=False).all())) case = CommCareCase.get("case_in_form") self.assertEqual("form case", case.name)
def device_data(request): if "data" not in request.POST: return HttpResponseBadRequest("Missing 'data' POST parameter.") data = request.POST.get("data") data = data.strip() data_points = data.split(",") device_id = None for data_point in data_points: key_value = data_point.partition("=") key = key_value[0].strip().upper() value = key_value[2].strip() if key == "SN": device_id = value break if device_id is None: return HttpResponseBadRequest("Missing 'SN' in data string.") # This view lookup is an implicit assert that either one device exists # with the given device_id, or no devices exist with this device_id. case = CommCareCase.view("wisepill/device", key=[device_id], include_docs=True).one() event = WisePillDeviceEvent( domain=case.domain if case is not None else None, data=data, received_on=datetime.utcnow(), case_id=case.case_id if case is not None else None, processed=False, ) event.save() if case is not None: survey_keywords = SurveyKeyword.get_all(case.domain) for survey_keyword in survey_keywords: if survey_keyword.keyword.upper() == "DEVICE_EVENT": for survey_keyword_action in survey_keyword.actions: if survey_keyword_action.action == METHOD_STRUCTURED_SMS: handle_structured_sms(survey_keyword, survey_keyword_action, case, None, "DEVICE_EVENT,%s" % data, send_response=False) event.processed = True event.save() break
def testLotsOfSubcases(self): """ How do we do when submitting a form with multiple blocks for the same case? """ self.assertEqual( 0, len(CommCareCase.view("case/by_user", reduce=False).all())) file_path = os.path.join(os.path.dirname(__file__), "data", "bugs", "lots_of_subcases.xml") with open(file_path, "rb") as f: xml_data = f.read() form = post_xform_to_couch(xml_data) # before the bug was fixed this call failed process_cases(form) self.assertEqual( 11, len(CommCareCase.view("case/by_user", reduce=False).all()))
def handle(self, *args, **options): key = make_form_couch_key("hsph") test_forms = XFormInstance.view( 'reports_forms/all_forms', reduce=False, startkey=key, endkey=key + ["2012-11-07"], include_docs=True, ).all() test_cases = CommCareCase.view( 'reports/case_activity', reduce=False, startkey=["", "hsph"], endkey=["", "hsph", "2012-11-07"], include_docs=True, ).all() print "\nDELETING TEST HSPH FORMS" for form in test_forms: if form.domain == "hsph": sys.stdout.write(".") sys.stdout.flush() form.delete() print "\n\nDELETING TEST HSPH CASES" for case in test_cases: if case.domain == "hsph": sys.stdout.write(".") sys.stdout.flush() case.delete()
def _testCornerCaseDatatypeBugs(self, value): self.assertEqual(0, len(CommCareCase.view("case/by_user", reduce=False).all())) def _test(custom_format_args): case_id = uuid.uuid4().hex format_args = { 'case_id': case_id, 'form_id': uuid.uuid4().hex, 'user_id': uuid.uuid4().hex, 'case_name': 'data corner cases', 'case_type': 'datatype-check', } format_args.update(custom_format_args) for filename in ['bugs_in_case_create_datatypes.xml', 'bugs_in_case_update_datatypes.xml']: file_path = os.path.join(os.path.dirname(__file__), "data", "bugs", filename) with open(file_path, "rb") as f: xml_data = f.read() xml_data = xml_data.format(**format_args) form = post_xform_to_couch(xml_data) # before the bug was fixed this call failed process_cases(form) case = CommCareCase.get(case_id) self.assertEqual(format_args['user_id'], case.user_id) self.assertEqual(format_args['case_name'], case.name) self.assertEqual(format_args['case_type'], case.type) _test({'case_name': value}) _test({'case_type': value}) _test({'user_id': value})
def open_cases_json(request, domain): delete_ids = json.loads(request.GET.get('delete_ids', 'false')) delete_doc_types = json.loads(request.GET.get('delete_doc_types', 'true')) username = request.GET.get("username", None) cases = CommCareCase.view('hqcase/open_cases', startkey=[domain], endkey=[domain, {}], reduce=False, include_docs=True) user_id_to_type_to_cases = defaultdict(lambda:defaultdict(list)) for case in cases: case_json = deepcopy(case.to_json()) user_id_to_type_to_cases[case.user_id][case.type].append(case_json) del case_json['domain'] if delete_ids: del case_json['_id'] del case_json['_rev'] del case_json['user_id'] # del case_json['type'] del case_json['doc_type'] case_json['actions'] = [action.action_type for action in case.actions] case_json['referrals'] = [referral.type for referral in case.referrals] usercases = [{ "username": user_id_to_username(user_id), "cases": [{"type": type, "cases":cases} for (type, cases) in type_to_cases.items()] } for (user_id, type_to_cases) in user_id_to_type_to_cases.items()] usercases.sort(key=lambda x: x['username']) return HttpResponse(json.dumps(usercases))
def testDuplicateCasePropertiesBug(self): """ How do we do when submitting multiple values for the same property in an update block """ self.assertEqual(0, len(CommCareCase.view("case/by_user", reduce=False).all())) file_path = os.path.join(os.path.dirname(__file__), "data", "bugs", "duplicate_case_properties.xml") with open(file_path, "rb") as f: xml_data = f.read() form = post_xform_to_couch(xml_data) # before the bug was fixed this call failed process_cases(form) case = CommCareCase.get(form.xpath("form/case/@case_id")) # make sure the property is there, but empty self.assertEqual("", case.foo) file_path = os.path.join(os.path.dirname(__file__), "data", "bugs", "duplicate_case_properties_2.xml") with open(file_path, "rb") as f: xml_data = f.read() form = post_xform_to_couch(xml_data) process_cases(form) case = CommCareCase.get(form.xpath("form/case/@case_id")) # make sure the property takes the last defined value self.assertEqual("2", case.bar)
def explode_cases(request, domain, template="hqcase/explode_cases.html"): if request.method == 'POST': user_id = request.POST['user_id'] user = CommCareUser.get_by_user_id(user_id, domain) factor = request.POST.get('factor', '2') try: factor = int(factor) except ValueError: messages.error(request, 'factor must be an int; was: %s' % factor) else: keys = [[domain, owner_id, False] for owner_id in user.get_owner_ids()] for case in CommCareCase.view('hqcase/by_owner', keys=keys, include_docs=True, reduce=False ): # we'll be screwing with this guy, so make him unsaveable case.save = None for i in range(factor - 1): case._id = uuid.uuid4().hex case_block = get_case_xml(case, (const.CASE_ACTION_CREATE, const.CASE_ACTION_UPDATE), version='2.0') submit_case_blocks(case_block, domain) messages.success(request, "All of %s's cases were exploded by a factor of %d" % (user.raw_username, factor)) return render(request, template, { 'domain': domain, 'users': CommCareUser.by_domain(domain), })
def process(domain, instance): """process an incoming commtrack stock report instance""" config = CommtrackConfig.for_domain(domain) root = etree.fromstring(instance) transactions = unpack_transactions(root, config) case_ids = [tx["case_id"] for tx in transactions] cases = dict((c._id, c) for c in CommCareCase.view("_all_docs", keys=case_ids, include_docs=True)) # ensure transaction types are processed in the correct order def transaction_order(tx): return [action.action_name for action in config.actions].index(tx["action"]) transactions.sort(key=transaction_order) # apply all transactions to each product case in bulk transactions_by_product = map_reduce(lambda tx: [(tx["case_id"],)], data=transactions, include_docs=True) for product_id, txs in transactions_by_product.iteritems(): product_case = cases[product_id] case_block, reconciliations = process_product_transactions(product_case, txs) for recon in reconciliations: root.append(recon) root.append(case_block) submission = etree.tostring(root) logger.debug("submitting: %s" % submission) submit_time = root.find(".//%s" % _("timeStart", META_XMLNS)).text spoof_submission(get_submit_url(domain), submission, headers={"HTTP_X_SUBMIT_TIME": submit_time})
def get_number_of_cases_by_filters(domain, owner_id, case_type, status=None, date_range=None): """ Get number of cases in a domain filtered by a number of different fields: domain: required, non-null owner_id: required, non-null case_type: optional, no filter applied if null status: optional, no filter applied if null date_range: optional (start, end) tuple, no filter applied if null returns number of matching cases """ from casexml.apps.case.models import CommCareCase couch_key = [domain, status or {}, case_type or {}, owner_id] start_date, end_date = date_range or (None, None) start_date_key = [start_date.isoformat()] if start_date else [] end_date_key = [end_date.isoformat()] if end_date else [{}] results = CommCareCase.view( 'case/by_date_modified_owner', reduce=True, startkey=couch_key + start_date_key, endkey=couch_key + end_date_key, ).one() return results['value'] if results else 0
def _get_cases(self): case_ids = get_case_ids_in_domain(self.domain) return CommCareCase.view( '_all_docs', keys=case_ids, include_docs=True, )
def handle(self, *args, **options): if len(args) != 1: raise CommandError('Usage: %s\n%s' % (self.args, self.help)) domain = args[0] view_name = 'hqcase/all_cases' key = [domain, {}, {}] case_ids = CommCareCase.view(view_name, startkey=key, endkey=key + [{}], reduce=False, include_docs=False, wrapper=lambda r: r['id'] ) print 'loading %s cases in %s' % (len(case_ids), domain) def stream_cases(all_case_ids): for case_ids in chunked(all_case_ids, 1000): for case in wrapped_docs(CommCareCase, keys=case_ids): # for case in CommCareCase.view('_all_docs', keys=case_ids, include_docs=True): yield case count = 0 for c in stream_cases(case_ids): count += 1 print 'read %s cases' % count
def handle(self, *args, **options): key = make_form_couch_key("hsph") test_forms = XFormInstance.view('reports_forms/all_forms', reduce=False, startkey=key, endkey=key+["2012-11-07"], include_docs=True, ).all() test_cases = CommCareCase.view('reports/case_activity', reduce=False, startkey=["","hsph"], endkey=["","hsph","2012-11-07"], include_docs=True, ).all() print "\nDELETING TEST HSPH FORMS" for form in test_forms: if form.domain == "hsph": sys.stdout.write(".") sys.stdout.flush() form.delete() print "\n\nDELETING TEST HSPH CASES" for case in test_cases: if case.domain == "hsph": sys.stdout.write(".") sys.stdout.flush() case.delete() print "\n"
def handle(self, *args, **options): if len(args) != 1: raise CommandError('Usage: %s\n%s' % (self.args, self.help)) domain = args[0] view_name = 'hqcase/all_cases' key = [domain, {}, {}] case_ids = CommCareCase.view(view_name, startkey=key, endkey=key + [{}], reduce=False, include_docs=False, wrapper=lambda r: r['id']) print 'loading %s cases in %s' % (len(case_ids), domain) def stream_cases(all_case_ids): for case_ids in chunked(all_case_ids, 1000): for case in wrapped_docs(CommCareCase, keys=case_ids): # for case in CommCareCase.view('_all_docs', keys=case_ids, include_docs=True): yield case count = 0 for c in stream_cases(case_ids): count += 1 print 'read %s cases' % count
def open_cases_json(request, domain): delete_ids = json.loads(request.GET.get("delete_ids", "false")) cases = CommCareCase.view( "hqcase/open_cases", startkey=[domain], endkey=[domain, {}], reduce=False, include_docs=True ) user_id_to_type_to_cases = defaultdict(lambda: defaultdict(list)) for case in cases: case_json = deepcopy(case.to_json()) user_id_to_type_to_cases[case.user_id][case.type].append(case_json) del case_json["domain"] if delete_ids: del case_json["_id"] del case_json["_rev"] del case_json["user_id"] # del case_json['type'] del case_json["doc_type"] case_json["actions"] = [action.action_type for action in case.actions] case_json["referrals"] = [referral.type for referral in case.referrals] usercases = [ { "username": user_id_to_username(user_id), "cases": [{"type": type, "cases": cases} for (type, cases) in type_to_cases.items()], } for (user_id, type_to_cases) in user_id_to_type_to_cases.items() ] usercases.sort(key=lambda x: x["username"]) return HttpResponse(json.dumps(usercases))
def _testCornerCaseDatatypeBugs(self, value): self.assertEqual( 0, len(CommCareCase.view("case/by_user", reduce=False).all())) def _test(custom_format_args): case_id = uuid.uuid4().hex format_args = { 'case_id': case_id, 'form_id': uuid.uuid4().hex, 'user_id': uuid.uuid4().hex, 'case_name': 'data corner cases', 'case_type': 'datatype-check', } format_args.update(custom_format_args) for filename in [ 'bugs_in_case_create_datatypes.xml', 'bugs_in_case_update_datatypes.xml' ]: file_path = os.path.join(os.path.dirname(__file__), "data", "bugs", filename) with open(file_path, "rb") as f: xml_data = f.read() xml_data = xml_data.format(**format_args) form = post_xform_to_couch(xml_data) # before the bug was fixed this call failed process_cases(form) case = CommCareCase.get(case_id) self.assertEqual(format_args['user_id'], case.user_id) self.assertEqual(format_args['case_name'], case.name) self.assertEqual(format_args['case_type'], case.type) _test({'case_name': value}) _test({'case_type': value}) _test({'user_id': value})
def explode_cases(request, domain, template="hqcase/explode_cases.html"): if request.method == 'POST': user_id = request.POST['user_id'] user = CommCareUser.get_by_user_id(user_id, domain) factor = request.POST.get('factor', '2') try: factor = int(factor) except ValueError: messages.error(request, 'factor must be an int; was: %s' % factor) else: keys = [[domain, owner_id, False] for owner_id in user.get_owner_ids()] for case in CommCareCase.view('hqcase/by_owner', keys=keys, include_docs=True, reduce=False): # we'll be screwing with this guy, so make him unsaveable case.save = None for i in range(factor - 1): case._id = uuid.uuid4().hex case_block = get_case_xml( case, (const.CASE_ACTION_CREATE, const.CASE_ACTION_UPDATE), version='2.0') submit_case_blocks(case_block, domain) messages.success( request, "All of %s's cases were exploded by a factor of %d" % (user.raw_username, factor))
def get_case_ids_in_domain_by_owner(domain, owner_id=None, owner_id__in=None, closed=None): """ get case_ids for open, closed, or all cases in a domain that belong to an owner_id or list of owner_ids domain: required owner_id: a single owner_id to filter on owner_id__in: a list of owner ids to filter on. A case matches if it belongs to any of them. You cannot specify both this and owner_id closed: True (only closed cases), False (only open cases), or None (all) returns a list of case_ids """ assert not (owner_id__in and owner_id) assert closed in (True, False, None) if closed is None: closed_flags = [True, False] else: closed_flags = [closed] if owner_id: owner_id__in = [owner_id] return [ res["id"] for res in CommCareCase.view( 'cases_by_owner/view', keys=[[domain, owner_id, closed_flag] for owner_id in owner_id__in for closed_flag in closed_flags], include_docs=False, reduce=False, ) ]
def testDuplicateCasePropertiesBug(self): """ How do we do when submitting multiple values for the same property in an update block """ self.assertEqual( 0, len(CommCareCase.view("case/by_user", reduce=False).all())) file_path = os.path.join(os.path.dirname(__file__), "data", "bugs", "duplicate_case_properties.xml") with open(file_path, "rb") as f: xml_data = f.read() form = post_xform_to_couch(xml_data) # before the bug was fixed this call failed process_cases(form) case = CommCareCase.get(form.xpath("form/case/@case_id")) # make sure the property is there, but empty self.assertEqual("", case.foo) file_path = os.path.join(os.path.dirname(__file__), "data", "bugs", "duplicate_case_properties_2.xml") with open(file_path, "rb") as f: xml_data = f.read() form = post_xform_to_couch(xml_data) process_cases(form) case = CommCareCase.get(form.xpath("form/case/@case_id")) # make sure the property takes the last defined value self.assertEqual("2", case.bar)
def cases(self): keys = [[self.domain, owner_id, False] for owner_id in self.all_owner_ids] return CommCareCase.view('hqcase/by_owner', keys=keys, include_docs=True, reduce=False)
def _get_cases_by_domain_hq_user_id(domain, user_id, case_type, include_docs): return CommCareCase.view( 'case_by_domain_hq_user_id_type/view', key=[domain, user_id, case_type], reduce=False, include_docs=include_docs ).all()
def open_cases_json(request, domain): delete_ids = json.loads(request.GET.get('delete_ids', 'false')) cases = CommCareCase.view('hqcase/open_cases', startkey=[domain], endkey=[domain, {}], reduce=False, include_docs=True) user_id_to_type_to_cases = defaultdict(lambda:defaultdict(list)) for case in cases: case_json = deepcopy(case.to_json()) user_id_to_type_to_cases[case.user_id][case.type].append(case_json) del case_json['domain'] if delete_ids: del case_json['_id'] del case_json['_rev'] del case_json['user_id'] # del case_json['type'] del case_json['doc_type'] case_json['actions'] = [action.action_type for action in case.actions] case_json['referrals'] = [referral.type for referral in case.referrals] usercases = [{ "username": user_id_to_username(user_id), "cases": [{"type": type, "cases":cases} for (type, cases) in type_to_cases.items()] } for (user_id, type_to_cases) in user_id_to_type_to_cases.items()] usercases.sort(key=lambda x: x['username']) return HttpResponse(json.dumps(usercases))
def update_indicators_for_case_type(self, case_type, domain): print "\n\n\nFetching %s cases in domain %s...." % (case_type, domain) key = ["all type", domain, case_type] relevant_indicators = CaseIndicatorDefinition.get_all( namespace=MVP.NAMESPACE, domain=domain, case_type=case_type ) if relevant_indicators: all_cases = get_db().view("case/all_cases", reduce=True, startkey=key, endkey=key+[{}] ).first() num_cases = all_cases['value'] if all_cases else 0 print "\nFound the following Case Indicator Definitions for Case Type %s in Domain %s" % (case_type, domain) print "--%s\n" % "\n--".join([i.slug for i in relevant_indicators]) print "Found %d possible cases for update." % num_cases get_cases = lambda skip, limit: CommCareCase.view("case/all_cases", reduce=False, include_docs=True, startkey=key, endkey=key+[{}], skip=skip, limit=limit ).all() self._throttle_updates("Cases of type %s in %s" % (case_type, domain), relevant_indicators, num_cases, domain, get_cases)
def process(domain, instance): """process an incoming commtrack stock report instance""" config = CommtrackConfig.for_domain(domain) root = etree.fromstring(instance) user_id, transactions = unpack_transactions(root, config) transactions = list(normalize_transactions(transactions)) def get_transactions(all_tx, type_filter): """get all the transactions of the relevant type (filtered by type_filter), grouped by product (returns a dict of 'product subcase id' => list of transactions), with each set of transactions sorted in the correct order for processing """ return map_reduce( lambda tx: [(tx.case_id, )], lambda v: sorted(v, key=lambda tx: tx.priority_order ), # important! data=filter(type_filter, all_tx), include_docs=True) # split transactions by type and product stock_transactions = get_transactions(transactions, lambda tx: tx.category == 'stock') requisition_transactions = get_transactions( transactions, lambda tx: tx.category == 'requisition') case_ids = list( set(itertools.chain(*[tx.get_case_ids() for tx in transactions]))) cases = dict((c._id, c) for c in CommCareCase.view( '_all_docs', keys=case_ids, include_docs=True)) # TODO: code to auto generate / update requisitions from transactions if # project is configured for that. # TODO: when we start receiving commcare-submitted reports, we should be using a server time rather # than relying on timeStart (however timeStart is set to server time for reports received via sms) submit_time = root.find('.//%s' % _('timeStart', META_XMLNS)).text post_processed_transactions = list(transactions) for product_id, product_case in cases.iteritems(): stock_txs = stock_transactions.get(product_id, []) if stock_txs: case_block, reconciliations = process_product_transactions( user_id, submit_time, product_case, stock_txs) root.append(case_block) post_processed_transactions.extend(reconciliations) req_txs = requisition_transactions.get(product_id, []) if req_txs and config.requisitions_enabled: req = RequisitionState.from_transactions(user_id, product_case, req_txs) case_block = etree.fromstring(req.to_xml()) root.append(case_block) replace_transactions(root, post_processed_transactions) submission = etree.tostring(root) logger.debug('submitting: %s' % submission) spoof_submission(get_submit_url(domain), submission, headers={'HTTP_X_SUBMIT_TIME': submit_time}, hqsubmission=False)
def get_owned_cases(domain, user_id, closed=False): """ Get all cases in a domain owned by a particular user. """ try: user = CouchUser.get_by_user_id(user_id, domain) except KeyError: user = None try: owner_ids = user.get_owner_ids() except AttributeError: owner_ids = [user_id] @list @inline def keys(): for owner_id in owner_ids: if closed is None: yield [owner_id, True] yield [owner_id, False] else: yield [owner_id, closed] cases = CommCareCase.view('case/by_owner', keys=keys, include_docs=True, reduce=False) # demo_user cases! return [case.get_json() for case in cases if case.domain == domain]
def rows(self): results = self.verbose_results[self.indicator.fluff_calculator.primary] numerators = self.verbose_results['numerator'] def _reconcile(numerators, denominators): def _is_match(num, denom): return num['id'] == denom['id'] and num['key'][-1] == denom['key'][-1] num_copy = copy(numerators) for denom in denominators: denom['in_num'] = False for num in num_copy: if _is_match(num, denom): num_copy.remove(num) denom['in_num'] = True break if num_copy: logging.error('expected no indicators left in the numerator but found some') def _key(result): return (result['in_num'], result['key'][-1]) _reconcile(numerators, results) results = sorted(results, key=_key) case_ids = set([res['id'] for res in results]) cases = dict((c._id, c) for c in CommCareCase.view('_all_docs', keys=list(case_ids), include_docs=True)) return [ self.indicator.as_row(cases[result['id']], self.fluff_results, fluff_row=result) for result in results ]
def handle(self, *args, **options): domain, group_name = args group = Group.by_name(domain, name=group_name) owner_ids = get_all_owner_ids_from_group(group) pillow = CareBiharFluffPillow() db = CommCareCase.get_db() greenlets = [] def process_case(case): pillow.change_transport(pillow.change_transform(case)) for i, owner_id in enumerate(owner_ids): print '{0}/{1} owner_ids'.format(i, len(owner_ids)) rows = CommCareCase.view( 'hqcase/by_owner', startkey=[domain, owner_id], endkey=[domain, owner_id, {}], reduce=False, ).all() case_ids = [row['id'] for row in rows] print '{0} case_ids'.format(len(case_ids)) for case in iter_docs(db, case_ids): g = gevent.Greenlet.spawn(process_case, case) greenlets.append(g) gevent.joinall(greenlets)
def get_cases_in_domain_by_external_id(domain, external_id): return CommCareCase.view( 'cases_by_domain_external_id/view', key=[domain, external_id], reduce=False, include_docs=True, ).all()
def generate_case_export_payload(domain, include_closed, format, group, user_filter): """ Returns a FileWrapper object, which only the file backend in django-soil supports """ view_name = 'hqcase/all_cases' if include_closed else 'hqcase/open_cases' key = [domain, {}, {}] case_ids = CommCareCase.view(view_name, startkey=key, endkey=key + [{}], reduce=False, include_docs=False, wrapper=lambda r: r['id'] ) def stream_cases(all_case_ids): for case_ids in chunked(all_case_ids, 500): for case in CommCareCase.view('_all_docs', keys=case_ids, include_docs=True): yield case # todo deal with cached user dict here users = get_all_users_by_domain(domain, group=group, user_filter=user_filter) groups = Group.get_case_sharing_groups(domain) fd, path = tempfile.mkstemp() with os.fdopen(fd, 'wb') as file: workbook = WorkBook(file, format) export_cases_and_referrals(domain, stream_cases(case_ids), workbook, users=users, groups=groups) export_users(users, workbook) workbook.close() return FileWrapper(open(path))
def form_data(request, domain, instance_id): timezone = util.get_timezone(request.couch_user.user_id, domain) try: instance = XFormInstance.get(instance_id) except Exception: raise Http404() try: assert(domain == instance.domain) except AssertionError: raise Http404() cases = CommCareCase.view("case/by_xform_id", key=instance_id, reduce=False, include_docs=True).all() try: form_name = instance.get_form["@name"] except KeyError: form_name = "Untitled Form" is_archived = instance.doc_type == "XFormArchived" if is_archived: messages.info(request, _("This form is archived. To restore it, click 'Restore this form' at the bottom of the page.")) return render(request, "reports/reportdata/form_data.html", dict(domain=domain, instance=instance, cases=cases, timezone=timezone, slug=inspect.SubmitHistory.slug, is_archived=is_archived, form_data=dict(name=form_name, modified=instance.received_on)))
def _get_cases(xforms): cases = [] for case in CommCareCase.view('case/by_xform_id', keys=[xform.get_id for xform in xforms], reduce=False, include_docs=True).all(): cases.append(case) return cases
def delete_all_data(request, domain, template="cleanup/delete_all_data.html"): if request.method == 'GET': return render(request, template, { 'domain': domain }) key = make_form_couch_key(domain) xforms = XFormInstance.view('reports_forms/all_forms', startkey=key, endkey=key+[{}], include_docs=True, reduce=False ) cases = CommCareCase.view('case/by_date_modified', startkey=[domain, {}, {}], endkey=[domain, {}, {}, {}], include_docs=True, reduce=False ) suffix = DELETED_SUFFIX deletion_id = random_hex() for thing_list in (xforms, cases): for thing in thing_list: thing.doc_type += suffix thing['-deletion_id'] = deletion_id thing.save() return HttpResponseRedirect(reverse('homepage'))
def testAttachInCreate(self): self.assertEqual(0, len(CommCareCase.view("case/by_user", reduce=False).all())) file_path = os.path.join(os.path.dirname(__file__), "data", "attachments", "create_with_attach.xml") with open(file_path, "rb") as f: xml_data = f.read() attach_name = "fruity.jpg" attachment_path = os.path.join(os.path.dirname(__file__), "data", "attachments", attach_name) with open(attachment_path, "rb") as attachment: uf = UploadedFile(attachment, attach_name) form = post_xform_to_couch(xml_data, {attach_name: uf}) self.assertEqual(1, len(form.attachments)) fileback = form.fetch_attachment(attach_name) # rewind the pointer before comparing attachment.seek(0) self.assertEqual(hashlib.md5(fileback).hexdigest(), hashlib.md5(attachment.read()).hexdigest()) process_cases(sender="testharness", xform=form) case = CommCareCase.get(form.xpath("form/case/case_id")) self.assertEqual(1, len(case.attachments)) self.assertEqual(form.get_id, case.attachments[0][0]) self.assertEqual(attach_name, case.attachments[0][1])
def product_subcases(supply_point): """given a supply point, return all the sub-cases for each product stocked at that supply point actually returns a mapping: product doc id => sub-case id ACTUALLY returns a dict that will create non-existent product sub-cases on demand """ product_subcase_uuids = [ix.referenced_id for ix in supply_point.reverse_indices if ix.identifier == const.PARENT_CASE_REF] product_subcases = CommCareCase.view('_all_docs', keys=product_subcase_uuids, include_docs=True) product_subcase_mapping = dict((subcase.dynamic_properties().get('product'), subcase._id) for subcase in product_subcases) def create_product_subcase(product_uuid): return make_supply_point_product(supply_point, product_uuid)._id class DefaultDict(dict): """similar to collections.defaultdict(), but factory function has access to 'key' """ def __init__(self, factory, *args, **kwargs): super(DefaultDict, self).__init__(*args, **kwargs) self.factory = factory def __getitem__(self, key): if key in self: val = self.get(key) else: val = self.factory(key) self[key] = val return val return DefaultDict(create_product_subcase, product_subcase_mapping)
def explode_cases(request, domain, template="hqcase/explode_cases.html"): if request.method == 'POST': user_id = request.POST['user_id'] user = CommCareUser.get_by_user_id(user_id, domain) factor = request.POST.get('factor', '2') try: factor = int(factor) except ValueError: messages.error(request, 'factor must be an int; was: %s' % factor) else: keys = [[domain, owner_id, False] for owner_id in user.get_owner_ids()] for case in CommCareCase.view('hqcase/by_owner', keys=keys, include_docs=True, reduce=False ): for i in range(factor - 1): new_case_id = uuid.uuid4().hex case_block, attachments = make_creating_casexml(case, new_case_id) submit_case_blocks(case_block, domain, attachments=attachments) messages.success(request, "All of %s's cases were exploded by a factor of %d" % (user.raw_username, factor)) return render(request, template, { 'domain': domain, 'users': CommCareUser.by_domain(domain), })
def get_case(self, external_id): case = CommCareCase.view("hqcase/by_domain_external_id", key=[self.domain, external_id], include_docs=True, reduce=False, ).one() return case
def download_cases(request, domain): include_closed = json.loads(request.GET.get('include_closed', 'false')) format = Format.from_format(request.GET.get('format') or Format.XLS_2007) view_name = 'hqcase/all_cases' if include_closed else 'hqcase/open_cases' key = [domain, {}, {}] cases = CommCareCase.view(view_name, startkey=key, endkey=key + [{}], reduce=False, include_docs=True) # group, users = util.get_group_params(domain, **json_request(request.GET)) group = request.GET.get('group', None) user_filter, _ = FilterUsersField.get_user_filter(request) # todo deal with cached user dict here users = get_all_users_by_domain(domain, group=group, user_filter=user_filter) groups = Group.get_case_sharing_groups(domain) # if not group: # users.extend(CommCareUser.by_domain(domain, is_active=False)) workbook = WorkBook() export_cases_and_referrals(cases, workbook, users=users, groups=groups) export_users(users, workbook) response = HttpResponse(workbook.format(format.slug)) response['Content-Type'] = "%s" % format.mimetype response['Content-Disposition'] = "attachment; filename={domain}_data.{ext}".format(domain=domain, ext=format.extension) return response
def get_case_ids_in_domain_by_owner(domain, owner_id=None, owner_id__in=None, closed=None): """ get case_ids for open, closed, or all cases in a domain that belong to an owner_id or list of owner_ids domain: required owner_id: a single owner_id to filter on owner_id__in: a list of owner ids to filter on. A case matches if it belongs to any of them. You cannot specify both this and owner_id closed: True (only closed cases), False (only open cases), or None (all) returns a list of case_ids """ assert not (owner_id__in and owner_id) assert closed in (True, False, None) if closed is None: closed_flags = [True, False] else: closed_flags = [closed] if owner_id: owner_id__in = [owner_id] return [res["id"] for res in CommCareCase.view( 'cases_by_owner/view', keys=[[domain, owner_id, closed_flag] for owner_id in owner_id__in for closed_flag in closed_flags], include_docs=False, reduce=False, )]
def query(stale="ok", **kwargs): subs = [dict( userID = r['key'][1], username = r['key'][2], deviceID = r['key'][3], submissions = r['value']['count'], start = r['value']['start'].split('T')[0], end = r['value']['end' ].split('T')[0] ) for r in get_db().view('cleanup/case_submissions', startkey=[domain], endkey=[domain, {}], group=True, # stale=stale )] subs.sort(key=lambda sub: (sub['userID'], sub['end'])) # Try and help identify lost devices latest_start = defaultdict(lambda: None) for sub in subs: latest_start[sub['userID']] = max(sub['start'], latest_start[sub['userID']]) for sub in subs: if sub['end'] < latest_start[sub['userID']]: sub['old'] = True else: sub['old'] = False # show the number of cases made by these xforms # for sub in subs: # cases = _get_cases(_get_submissions(domain, [sub])) # sub['cases'] = len([None for case in cases if not case.closed]) open_cases = CommCareCase.view('hqcase/open_cases', startkey=[domain], endkey=[domain, {}], reduce=False, include_docs=True).all() xform_ids = [case.xform_ids[0] for case in open_cases]
def get_case_by_domain_hq_user_id(domain, user_id, include_docs=False): """ Get the 'user case' for user_id. User cases are part of the call center feature. """ return CommCareCase.view('hqcase/by_domain_hq_user_id', key=[domain, user_id], reduce=False, include_docs=include_docs).one()
def get_one_case_in_domain_by_external_id(domain, external_id): return CommCareCase.view( 'hqcase/by_domain_external_id', key=[domain, external_id], reduce=False, include_docs=True, # limit for efficiency, 2 instead of 1 so it raises if multiple found limit=2, ).one()
def run(): print "starting out" pact_cases = CommCareCase.view('case/by_owner_lite', key=[PACT_HP_GROUP_ID, True], include_docs=True, reduce=False).all() for c in pact_cases: print "#### Case %s" % c._id for action in c.actions: if getattr(action, 'server_date', None) is None: print "\taction is none!" print "\t%s" % simplejson.dumps(action.to_json(), indent=4)
def get_callcenter_case_mapping(domain, user_ids): """ Get the mapping from user_id to 'user case id' for each user in user_ids. """ keys = [[domain, user_id] for user_id in user_ids] rows = CommCareCase.view('hqcase/by_domain_hq_user_id', keys=keys, reduce=False, include_docs=False) return {r['key'][1]: r['id'] for r in rows}
def get_reverse_indexed_cases(domain, case_ids, relationship=None): """ Gets all reverse indexed cases of a case (including child cases and extensions). """ from casexml.apps.case.models import CommCareCase return CommCareCase.view( 'case_indices/related', keys=_get_keys_for_reverse_index_view(domain, case_ids, relationship), reduce=False, include_docs=True, )
def get_case_by_domain_hq_user_id(domain, user_id, case_type): """ Get the 'user case' for user_id. User cases are part of the call center feature. """ cases = CommCareCase.view('hqcase/by_domain_hq_user_id', key=[domain, user_id], reduce=False, include_docs=True).all() for case in cases: if case.type == case_type: return case
def testCasesInRepeats(self): self.assertEqual( 0, len(CommCareCase.view("case/by_user", reduce=False).all())) file_path = os.path.join(os.path.dirname(__file__), "data", "multicase", "case_in_repeats.xml") with open(file_path, "rb") as f: xml_data = f.read() form = post_xform_to_couch(xml_data) process_cases(form) cases = self._get_cases() self.assertEqual(3, len(cases)) self._check_ids(form, cases)