def rows(self): base_link_url = '{}?q={{id}}'.format(reverse('global_quick_find')) user_id = self.request.GET.get('individual') if not user_id: return [] # security check get_document_or_404(CommCareUser, self.domain, user_id) sync_log_ids = [row['id'] for row in SyncLog.view( "phone/sync_logs_by_user", startkey=[user_id, {}], endkey=[user_id], descending=True, reduce=False, limit=10 )] def _sync_log_to_row(sync_log): def _fmt_duration(duration): if isinstance(duration, int): return format_datatables_data( '<span class="{cls}">{text}</span>'.format( cls=_bootstrap_class(duration or 0, 60, 20), text=_('{} seconds').format(duration), ), duration ) else: return format_datatables_data( '<span class="label">{text}</span>'.format( text=_("Unknown"), ), -1, ) def _fmt_id(sync_log_id): href = base_link_url.format(id=sync_log_id) return '<a href="{href}" target="_blank">{id:.5}...</a>'.format( href=href, id=sync_log_id ) num_cases = len(sync_log.cases_on_phone) columns = [ _fmt_date(sync_log.date), format_datatables_data(num_cases, num_cases), _fmt_duration(sync_log.duration), ] if self.show_extra_columns: columns.append(_fmt_id(sync_log.get_id)) return columns return [ _sync_log_to_row(SyncLog.wrap(sync_log_json)) for sync_log_json in iter_docs(SyncLog.get_db(), sync_log_ids) ]
def get_last_synclog_for_user(user_id): results = synclog_view( "phone/sync_logs_by_user", startkey=[user_id, {}], endkey=[user_id], descending=True, limit=1, reduce=False, include_docs=True, ) if results: row, = results return SyncLog.wrap(row['doc']) else: return None
def rows(self): user_id = self.request.GET.get('individual') if not user_id: return [] # security check get_document_or_404(CommCareUser, self.domain, user_id) sync_log_ids = [row['id'] for row in SyncLog.view( "phone/sync_logs_by_user", startkey=[user_id, {}], endkey=[user_id], descending=True, reduce=False, )] def _sync_log_to_row(sync_log): def _fmt_duration(duration): if isinstance(duration, int): return format_datatables_data( '<span class="{cls}">{text}</span>'.format( cls=_bootstrap_class(duration or 0, 20, 60), text=_('{} seconds').format(duration), ), duration ) else: return format_datatables_data( '<span class="label">{text}</span>'.format( text=_("Unknown"), ), -1, ) num_cases = len(sync_log.cases_on_phone) return [ _fmt_date(sync_log.date), format_datatables_data(num_cases, num_cases), _fmt_duration(sync_log.duration), ] return [ _sync_log_to_row(SyncLog.wrap(sync_log_json)) for sync_log_json in iter_docs(SyncLog.get_db(), sync_log_ids) ]
roles = [ UserRole.wrap(role['doc']) for role in sourcedb.all_docs( keys=list(subset), include_docs=True, ) ] self.lenient_bulk_save(UserRole, roles) if options['include_sync_logs']: print('copying sync logs') for user_id in user_ids: log_ids = [ res['id'] for res in sourcedb.view("phone/sync_logs_by_user", startkey=[user_id, {}], endkey=[user_id], descending=True, reduce=False, include_docs=True) ] print('user: %s, logs: %s' % (user_id, len(log_ids))) for i, subset in enumerate(chunked(log_ids, CHUNK_SIZE)): print(i * CHUNK_SIZE) logs = [ SyncLog.wrap(log['doc']) for log in sourcedb.all_docs( keys=list(subset), include_docs=True, ) ] self.lenient_bulk_save(SyncLog, logs)
def handle(self, *args, **options): raise CommandError( 'copy_group_data is currently broken. ' 'Ask Danny or Ethan to fix it along the lines of ' 'https://github.com/dimagi/commcare-hq/pull/9180/files#diff-9d976dc051a36a028c6604581dfbce5dR95' ) if len(args) != 2: raise CommandError('Usage is copy_group_data %s' % self.args) sourcedb = Database(args[0]) group_id = args[1] exclude_user_owned = options["exclude_user_owned"] print 'getting group' group = Group.wrap(sourcedb.get(group_id)) group.save(force_update=True) print 'getting domain' domain = Domain.wrap( sourcedb.view('domain/domains', key=group.domain, include_docs=True, reduce=False, limit=1).one()['doc'] ) dt = DocumentTransform(domain._obj, sourcedb) save(dt, Domain.get_db()) owners = [group_id] if not exclude_user_owned: owners.extend(group.users) print 'getting case ids' with OverrideDB(CommCareCase, sourcedb): case_ids = get_case_ids_in_domain_by_owner( domain.name, owner_id__in=owners) xform_ids = set() print 'copying %s cases' % len(case_ids) for i, subset in enumerate(chunked(case_ids, CHUNK_SIZE)): print i * CHUNK_SIZE cases = [CommCareCase.wrap(case['doc']) for case in sourcedb.all_docs( keys=list(subset), include_docs=True, )] for case in cases: xform_ids.update(case.xform_ids) self.lenient_bulk_save(CommCareCase, cases) if not exclude_user_owned: # also grab submissions that may not have included any case data for user_id in group.users: xform_ids.update(res['id'] for res in sourcedb.view( 'all_forms/view', startkey=['submission user', domain.name, user_id], endkey=['submission user', domain.name, user_id, {}], reduce=False )) print 'copying %s xforms' % len(xform_ids) user_ids = set(group.users) def form_wrapper(row): doc = row['doc'] doc.pop('_attachments', None) doc.pop('external_blobs', None) return XFormInstance.wrap(doc) for i, subset in enumerate(chunked(xform_ids, CHUNK_SIZE)): print i * CHUNK_SIZE xforms = sourcedb.all_docs( keys=list(subset), include_docs=True, wrapper=form_wrapper, ).all() self.lenient_bulk_save(XFormInstance, xforms) for xform in xforms: user_id = xform.metadata.userID user_ids.add(user_id) print 'copying %s users' % len(user_ids) def wrap_user(row): try: doc = row['doc'] except KeyError: logging.exception('trouble with user result %r' % row) return None try: return CouchUser.wrap_correctly(doc) except Exception: logging.exception('trouble with user %s' % doc['_id']) return None users = sourcedb.all_docs( keys=list(user_ids), include_docs=True, wrapper=wrap_user, ).all() role_ids = set([]) for user in filter(lambda u: u is not None, users): # if we use bulk save, django user doesn't get sync'd domain_membership = user.get_domain_membership(domain.name) if domain_membership and domain_membership.role_id: role_ids.add(user.domain_membership.role_id) user.save(force_update=True) print 'copying %s roles' % len(role_ids) for i, subset in enumerate(chunked(role_ids, CHUNK_SIZE)): roles = [UserRole.wrap(role['doc']) for role in sourcedb.all_docs( keys=list(subset), include_docs=True, )] self.lenient_bulk_save(UserRole, roles) if options['include_sync_logs']: print 'copying sync logs' for user_id in user_ids: log_ids = [res['id'] for res in sourcedb.view("phone/sync_logs_by_user", startkey=[user_id, {}], endkey=[user_id], descending=True, reduce=False, include_docs=True )] print 'user: %s, logs: %s' % (user_id, len(log_ids)) for i, subset in enumerate(chunked(log_ids, CHUNK_SIZE)): print i * CHUNK_SIZE logs = [SyncLog.wrap(log['doc']) for log in sourcedb.all_docs( keys=list(subset), include_docs=True, )] self.lenient_bulk_save(SyncLog, logs)
def handle(self, *args, **options): if len(args) != 2: raise CommandError('Usage is copy_group_data %s' % self.args) sourcedb = Database(args[0]) group_id = args[1] exclude_user_owned = options["exclude_user_owned"] print 'getting group' group = Group.wrap(sourcedb.get(group_id)) group.save(force_update=True) print 'getting domain' domain = Domain.wrap( sourcedb.view('domain/domains', key=group.domain, include_docs=True, reduce=False, limit=1).one()['doc'] ) dt = DocumentTransform(domain._obj, sourcedb) save(dt, Domain.get_db()) owners = [group_id] if not exclude_user_owned: owners.extend(group.users) def keys_for_owner(domain, owner_id): return [ [domain, owner_id, False], [domain, owner_id, True], ] def get_case_ids(owners): keys = list(itertools.chain(*[keys_for_owner(domain.name, owner_id) for owner_id in owners])) results = sourcedb.view( 'hqcase/by_owner', keys=keys, reduce=False, include_docs=False, ) return [res['id'] for res in results] print 'getting case ids' case_ids = get_case_ids(owners) xform_ids = set() print 'copying %s cases' % len(case_ids) for i, subset in enumerate(chunked(case_ids, CHUNK_SIZE)): print i * CHUNK_SIZE cases = [CommCareCase.wrap(case['doc']) for case in sourcedb.all_docs( keys=list(subset), include_docs=True, )] for case in cases: xform_ids.update(case.xform_ids) self.lenient_bulk_save(CommCareCase, cases) if not exclude_user_owned: # also grab submissions that may not have included any case data for user_id in group.users: xform_ids.update(res['id'] for res in sourcedb.view( 'reports_forms/all_forms', startkey=['submission user', domain.name, user_id], endkey=['submission user', domain.name, user_id, {}], reduce=False )) print 'copying %s xforms' % len(xform_ids) user_ids = set(group.users) def form_wrapper(row): doc = row['doc'] doc.pop('_attachments', None) return XFormInstance.wrap(doc) for i, subset in enumerate(chunked(xform_ids, CHUNK_SIZE)): print i * CHUNK_SIZE xforms = sourcedb.all_docs( keys=list(subset), include_docs=True, wrapper=form_wrapper, ).all() self.lenient_bulk_save(XFormInstance, xforms) for xform in xforms: user_id = xform.metadata.userID user_ids.add(user_id) print 'copying %s users' % len(user_ids) def wrap_user(row): try: doc = row['doc'] except KeyError: logging.exception('trouble with user result %r' % row) return None try: return CouchUser.wrap_correctly(doc) except Exception: logging.exception('trouble with user %s' % doc['_id']) return None users = sourcedb.all_docs( keys=list(user_ids), include_docs=True, wrapper=wrap_user, ).all() role_ids = set([]) for user in filter(lambda u: u is not None, users): # if we use bulk save, django user doesn't get sync'd if user.get_domain_membership(domain.name).role_id: role_ids.add(user.domain_membership.role_id) user.save(force_update=True) print 'copying %s roles' % len(role_ids) for i, subset in enumerate(chunked(role_ids, CHUNK_SIZE)): roles = [UserRole.wrap(role['doc']) for role in sourcedb.all_docs( keys=list(subset), include_docs=True, )] self.lenient_bulk_save(UserRole, roles) if options['include_sync_logs']: print 'copying sync logs' for user_id in user_ids: log_ids = [res['id'] for res in sourcedb.view("phone/sync_logs_by_user", startkey=[user_id, {}], endkey=[user_id], descending=True, reduce=False, include_docs=True )] print 'user: %s, logs: %s' % (user_id, len(log_ids)) for i, subset in enumerate(chunked(log_ids, CHUNK_SIZE)): print i * CHUNK_SIZE logs = [SyncLog.wrap(log['doc']) for log in sourcedb.all_docs( keys=list(subset), include_docs=True, )] self.lenient_bulk_save(SyncLog, logs)