def import_contacts(self, user_api, options): file_path = options['contacts-csv'] try: _, parser = ContactFileParser.get_parser(file_path) # No Django silliness, please. parser.get_real_path = lambda path: path has_header, _, row = parser.guess_headers_and_row(file_path) fields = [(h, '') for h in row] contact_dicts = parser.parse_file(file_path, fields, has_header) written_contacts = [] self.stdout.write("Importing contacts:\n") try: for contact_dict in contact_dicts: contact_dict['groups'] = options['groups'] c = user_api.contact_store.new_contact(**contact_dict) written_contacts.append(c) self.stdout.write('.') except: for contact in written_contacts: contact.delete() raise self.stdout.write('\nDone.\n') except Exception, e: raise CommandError(e)
def dispatch_import_task(import_task, request, group): file_name, file_path = utils.get_file_hints_from_session(request) file_type, parser = ContactFileParser.get_parser(file_name) has_header, _, sample_row = parser.guess_headers_and_row(file_path) # Grab the selected field names from the submitted form # by looping over the expect n number of `column-n` keys being # posted field_names = [request.POST.get('column-%s' % i) for i in range(len(sample_row))] normalizers = [request.POST.get('normalize-%s' % i, '') for i in range(len(sample_row))] fields = zip(field_names, normalizers) import_task.delay( request.user_api.user_account_key, group.key, file_name, file_path, fields, has_header) utils.clear_file_hints_from_session(request)
def dispatch_import_task(import_task, request, group): file_name, file_path = utils.get_file_hints_from_session(request) file_type, parser = ContactFileParser.get_parser(file_name) has_header, _, sample_row = parser.guess_headers_and_row(file_path) # Grab the selected field names from the submitted form # by looping over the expect n number of `column-n` keys being # posted field_names = [ request.POST.get('column-%s' % i) for i in range(len(sample_row)) ] normalizers = [ request.POST.get('normalize-%s' % i, '') for i in range(len(sample_row)) ] fields = zip(field_names, normalizers) import_task.delay(request.user_api.user_account_key, group.key, file_name, file_path, fields, has_header) utils.clear_file_hints_from_session(request)
def import_and_update_contacts(contact_mangler, account_key, group_key, file_name, file_path, fields, has_header): api = VumiUserApi.from_config_sync(account_key, settings.VUMI_API_CONFIG) contact_store = api.contact_store group = contact_store.get_group(group_key) user_profile = UserProfile.objects.get(user_account=account_key) extension, parser = ContactFileParser.get_parser(file_name) contact_dictionaries = parser.parse_file(file_path, fields, has_header) errors = [] counter = 0 for contact_dictionary in contact_dictionaries: try: key = contact_dictionary.pop('key') contact = contact_store.get_contact_by_key(key) contact_dictionary = contact_mangler(contact, contact_dictionary) contact_store.update_contact(key, **contact_dictionary) counter += 1 except KeyError, e: errors.append((key, 'No key provided')) except ContactNotFoundError, e: errors.append((key, str(e)))
def import_new_contacts_file(account_key, group_key, file_name, file_path, fields, has_header): api = VumiUserApi.from_config_sync(account_key, settings.VUMI_API_CONFIG) contact_store = api.contact_store group = contact_store.get_group(group_key) # Get the profile for this user so we can email them when the import # has been completed. user_profile = UserProfile.objects.get(user_account=account_key) written_contacts = [] try: extension, parser = ContactFileParser.get_parser(file_name) contact_dictionaries = parser.parse_file(file_path, fields, has_header) for counter, contact_dictionary in enumerate(contact_dictionaries): # Make sure we set this group they're being uploaded in to contact_dictionary['groups'] = [group.key] contact = contact_store.new_contact(**contact_dictionary) written_contacts.append(contact) send_mail( 'Contact import completed successfully.', render_to_string('contacts/import_completed_mail.txt', { 'count': counter, 'group': group, 'user': user_profile.user, }), settings.DEFAULT_FROM_EMAIL, [user_profile.user.email], fail_silently=False) except Exception: # Clean up if something went wrong, either everything is written # or nothing is written for contact in written_contacts: contact.delete() exc_type, exc_value, exc_traceback = sys.exc_info() send_mail( 'Something went wrong while importing the contacts.', render_to_string('contacts/import_failed_mail.txt', { 'user': user_profile.user, 'group_key': group_key, 'account_key': account_key, 'file_name': file_name, 'file_path': file_path, 'fields': fields, 'has_header': has_header, 'exception_type': exc_type, 'exception_value': mark_safe(exc_value), 'exception_traceback': mark_safe( traceback.format_tb(exc_traceback)), }), settings.DEFAULT_FROM_EMAIL, [ user_profile.user.email, '*****@*****.**', ], fail_silently=False) finally: default_storage.delete(file_path)
def import_new_contacts_file(account_key, group_key, file_name, file_path, fields, has_header): api = VumiUserApi.from_config_sync(account_key, settings.VUMI_API_CONFIG) contact_store = api.contact_store group = contact_store.get_group(group_key) # Get the profile for this user so we can email them when the import # has been completed. user_profile = UserProfile.objects.get(user_account=account_key) written_contacts = [] try: extension, parser = ContactFileParser.get_parser(file_name) contact_dictionaries = parser.parse_file(file_path, fields, has_header) for counter, contact_dictionary in enumerate(contact_dictionaries): # Make sure we set this group they're being uploaded in to contact_dictionary['groups'] = [group.key] contact = contact_store.new_contact(**contact_dictionary) written_contacts.append(contact) send_mail('Contact import completed successfully.', render_to_string( 'contacts/import_completed_mail.txt', { 'count': counter, 'group': group, 'user': user_profile.user, }), settings.DEFAULT_FROM_EMAIL, [user_profile.user.email], fail_silently=False) except Exception: # Clean up if something went wrong, either everything is written # or nothing is written for contact in written_contacts: contact.delete() exc_type, exc_value, exc_traceback = sys.exc_info() send_mail('Something went wrong while importing the contacts.', render_to_string( 'contacts/import_failed_mail.txt', { 'user': user_profile.user, 'group_key': group_key, 'account_key': account_key, 'file_name': file_name, 'file_path': file_path, 'fields': fields, 'has_header': has_header, 'exception_type': exc_type, 'exception_value': mark_safe(exc_value), 'exception_traceback': mark_safe(traceback.format_tb(exc_traceback)), }), settings.DEFAULT_FROM_EMAIL, [ user_profile.user.email, '*****@*****.**', ], fail_silently=False) finally: default_storage.delete(file_path)
def _static_group(request, contact_store, group): if group is None: raise Http404 if request.method == 'POST': group_form = ContactGroupForm(request.POST) if '_save_group' in request.POST: if group_form.is_valid(): group.name = group_form.cleaned_data['name'] group.save() messages.info(request, 'The group name has been updated') return redirect(_group_url(group.key)) elif '_export' in request.POST: tasks.export_group_contacts.delay( request.user_api.user_account_key, group.key) messages.info(request, 'The export is scheduled and should ' 'complete within a few minutes.') return redirect(_group_url(group.key)) elif '_remove' in request.POST: contacts = request.POST.getlist('contact') for person_key in contacts: contact = contact_store.get_contact_by_key(person_key) contact.groups.remove(group) contact.save() messages.info( request, '%d Contacts removed from group' % len(contacts)) return redirect(_group_url(group.key)) elif '_delete_group_contacts' in request.POST: tasks.delete_group_contacts.delay( request.user_api.user_account_key, group.key) messages.info(request, "The group's contacts will be deleted shortly.") return redirect(_group_url(group.key)) elif '_delete_group' in request.POST: tasks.delete_group.delay(request.user_api.user_account_key, group.key) messages.info(request, 'The group will be deleted shortly.') return redirect(reverse('contacts:index')) elif '_complete_contact_upload' in request.POST: try: import_rule = request.POST.get('import_rule') import_handler = { 'existing_is_truth': handle_import_existing_is_truth, 'upload_is_truth': handle_import_upload_is_truth, }.get(import_rule, handle_import_new_contacts) import_handler(request, group) messages.info( request, 'The contacts are being imported. ' 'We will notify you via email when the import ' 'has been completed') except (ContactParserException,): messages.error(request, 'Something is wrong with the file') _, file_path = utils.get_file_hints_from_session(request) default_storage.delete(file_path) return redirect(_group_url(group.key)) else: upload_contacts_form = UploadContactsForm(request.POST, request.FILES) if upload_contacts_form.is_valid(): file_object = upload_contacts_form.cleaned_data['file'] file_name, file_path = utils.store_temporarily(file_object) utils.store_file_hints_in_session( request, file_name, file_path) return redirect(_group_url(group.key)) else: # We didn't get any useful POST variables, so just redirect # back to the group page without doing anything. return redirect(_group_url(group.key)) else: group_form = ContactGroupForm({ 'name': group.name, }) context = { 'group': group, 'group_form': group_form, } if 'clear-upload' in request.GET: # FIXME this is a debug statement utils.clear_file_hints_from_session(request) if utils.has_uncompleted_contact_import(request): try: file_name, file_path = utils.get_file_hints_from_session(request) file_type, parser = ContactFileParser.get_parser(file_name) has_header, headers, row = parser.guess_headers_and_row(file_path) context.update({ 'contact_data_headers': headers, 'field_normalizer': FieldNormalizer(), 'contact_data_row': row, # NOTE: Only if we have a key (contact UUID) value in the # row we can look at updating contacts instead of # only writing new ones. 'can_update_contacts': 'key' in row, }) except (ValueError, ContactParserException): messages.error(request, 'Something is wrong with the file') utils.clear_file_hints_from_session(request) default_storage.delete(file_path) query = request.GET.get('q', '') if query: if not ':' in query: query = 'name:%s' % (query,) keys = contact_store.contacts.raw_search(query).get_keys() else: keys = contact_store.get_contacts_for_group(group) limit = min(int(request.GET.get('limit', 100)), len(keys)) if keys: messages.info( request, "Showing %s of the group's %s contact(s)" % (limit, len(keys))) contacts = utils.contacts_by_key(contact_store, *keys[:limit]) context.update({ 'query': request.GET.get('q'), 'selected_contacts': contacts, 'member_count': contact_store.count_contacts_for_group(group), }) return render(request, 'contacts/static_group_detail.html', context)
def _static_group(request, contact_store, group): if group is None: raise Http404 if request.method == 'POST': group_form = ContactGroupForm(request.POST) if '_save_group' in request.POST: if group_form.is_valid(): group.name = group_form.cleaned_data['name'] group.save() messages.info(request, 'The group name has been updated') return redirect(_group_url(group.key)) elif '_export' in request.POST: tasks.export_group_contacts.delay( request.user_api.user_account_key, group.key) messages.info( request, 'The export is scheduled and should ' 'complete within a few minutes.') return redirect(_group_url(group.key)) elif '_remove' in request.POST: contacts = request.POST.getlist('contact') for person_key in contacts: contact = contact_store.get_contact_by_key(person_key) contact.groups.remove(group) contact.save() messages.info(request, '%d Contacts removed from group' % len(contacts)) return redirect(_group_url(group.key)) elif '_delete_group_contacts' in request.POST: tasks.delete_group_contacts.delay( request.user_api.user_account_key, group.key) messages.info(request, "The group's contacts will be deleted shortly.") return redirect(_group_url(group.key)) elif '_delete_group' in request.POST: tasks.delete_group.delay(request.user_api.user_account_key, group.key) messages.info(request, 'The group will be deleted shortly.') return redirect(reverse('contacts:index')) elif '_complete_contact_upload' in request.POST: try: import_rule = request.POST.get('import_rule') import_handler = { 'existing_is_truth': handle_import_existing_is_truth, 'upload_is_truth': handle_import_upload_is_truth, }.get(import_rule, handle_import_new_contacts) import_handler(request, group) messages.info( request, 'The contacts are being imported. ' 'We will notify you via email when the import ' 'has been completed') except (ContactParserException, ): messages.error(request, 'Something is wrong with the file') _, file_path = utils.get_file_hints_from_session(request) default_storage.delete(file_path) return redirect(_group_url(group.key)) else: upload_contacts_form = UploadContactsForm(request.POST, request.FILES) if upload_contacts_form.is_valid(): file_object = upload_contacts_form.cleaned_data['file'] file_name, file_path = utils.store_temporarily(file_object) utils.store_file_hints_in_session(request, file_name, file_path) return redirect(_group_url(group.key)) else: # We didn't get any useful POST variables, so just redirect # back to the group page without doing anything. return redirect(_group_url(group.key)) else: group_form = ContactGroupForm({ 'name': group.name, }) context = { 'group': group, 'group_form': group_form, } if 'clear-upload' in request.GET: # FIXME this is a debug statement utils.clear_file_hints_from_session(request) if utils.has_uncompleted_contact_import(request): try: file_name, file_path = utils.get_file_hints_from_session(request) file_type, parser = ContactFileParser.get_parser(file_name) has_header, headers, row = parser.guess_headers_and_row(file_path) context.update({ 'contact_data_headers': headers, 'field_normalizer': FieldNormalizer(), 'contact_data_row': row, # NOTE: Only if we have a key (contact UUID) value in the # row we can look at updating contacts instead of # only writing new ones. 'can_update_contacts': 'key' in row, }) except (ValueError, ContactParserException): messages.error(request, 'Something is wrong with the file') utils.clear_file_hints_from_session(request) default_storage.delete(file_path) query = request.GET.get('q', '') if query: if not ':' in query: query = 'name:%s' % (query, ) keys = contact_store.contacts.raw_search(query).get_keys() else: keys = contact_store.get_contacts_for_group(group) limit = min(int(request.GET.get('limit', 100)), len(keys)) if keys: messages.info( request, "Showing %s of the group's %s contact(s)" % (limit, len(keys))) contacts = utils.contacts_by_key(contact_store, *keys[:limit]) context.update({ 'query': request.GET.get('q'), 'selected_contacts': contacts, 'member_count': contact_store.count_contacts_for_group(group), }) return render(request, 'contacts/static_group_detail.html', context)