Beispiel #1
0
    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)
Beispiel #2
0
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)
Beispiel #3
0
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)
Beispiel #4
0
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)))
Beispiel #5
0
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)))
Beispiel #6
0
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)
Beispiel #7
0
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)
Beispiel #8
0
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)
Beispiel #9
0
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)