Esempio n. 1
0
def import_users(csv_file):
    error_messages = []
    count_success = 0
    try:
        # check for valid encoding (will raise UnicodeDecodeError if not)
        csv_file.read().decode('utf-8')
        csv_file.seek(0)

        with transaction.commit_on_success():
            dialect = csv.Sniffer().sniff(csv_file.readline())
            dialect = csv_ext.patchup(dialect)
            csv_file.seek(0)

            for (line_no, line) in enumerate(csv.reader(csv_file,
                                                        dialect=dialect)):
                if line_no:
                    try:
                        (title, first_name, last_name, gender, email, groups,
                         structure_level, committee, about_me, comment, is_active) = line[:11]
                    except ValueError:
                        error_messages.append(_('Ignoring malformed line %d in import file.') % (line_no + 1))
                        continue
                    user = User()
                    user.title = title
                    user.last_name = last_name
                    user.first_name = first_name
                    user.username = gen_username(first_name, last_name)
                    user.gender = gender
                    user.email = email
                    user.structure_level = structure_level
                    user.committee = committee
                    user.about_me = about_me
                    user.comment = comment
                    if is_active == '1':
                        user.is_active = True
                    else:
                        user.is_active = False
                    user.default_password = gen_password()
                    user.save()
                    for groupid in groups:
                        try:
                            if groupid != ",":
                                Group.objects.get(pk=groupid).user_set.add(user)
                        except ValueError:
                            error_messages.append(_('Ignoring malformed group id in line %d.') % (line_no + 1))
                            continue
                        except Group.DoesNotExist:
                            error_messages.append(_('Group id %(id)s does not exists (line %(line)d).') % {'id': groupid, 'line': line_no + 1})
                            continue
                    user.reset_password()
                    count_success += 1
    except csv.Error:
        error_messages.append(_('Import aborted because of severe errors in the input file.'))
    except UnicodeDecodeError:
        error_messages.append(_('Import file has wrong character encoding, only UTF-8 is supported!'))
    return (count_success, error_messages)
Esempio n. 2
0
def import_agenda_items(csvfile):
    """
    Performs the import of agenda items form a csv file.
    """
    # Check encoding
    try:
        csvfile.read().decode('utf8')
    except UnicodeDecodeError:
        return_value = '', '', _(
            'Import file has wrong character encoding, only UTF-8 is supported!'
        )
    else:
        csvfile.seek(0)
        # Check dialect
        dialect = csv.Sniffer().sniff(csvfile.readline().decode('utf8'))
        dialect = csv_ext.patchup(dialect)
        csvfile.seek(0)
        # Parse CSV file
        with transaction.atomic():
            success_lines = []
            error_lines = []
            for (line_no, line) in enumerate(
                    csv.reader(
                        (line.decode('utf8') for line in csvfile.readlines()),
                        dialect=dialect)):
                if line_no == 0:
                    # Do not read the header line
                    continue
                # Check format
                try:
                    title, text, duration = line[:3]
                except ValueError:
                    error_lines.append(line_no + 1)
                    continue
                if duration and re.match('^(?:[0-9]{1,2}:[0-5][0-9]|[0-9]+)$',
                                         duration) is None:
                    error_lines.append(line_no + 1)
                    continue
                Item.objects.create(title=title, text=text, duration=duration)
                success_lines.append(line_no + 1)
            success = _('%d items successfully imported.') % len(success_lines)
            if error_lines:
                error = _('Error in the following lines: %s.') % ', '.join(
                    str(number) for number in error_lines)
            else:
                error = ''
            return_value = success, '', error
    return return_value
Esempio n. 3
0
def import_users(csv_file):
    error_messages = []
    count_success = 0
    try:
        # check for valid encoding (will raise UnicodeDecodeError if not)
        csv_file.read().decode('utf-8')
        csv_file.seek(0)

        with transaction.commit_on_success():
            dialect = csv.Sniffer().sniff(csv_file.readline())
            dialect = csv_ext.patchup(dialect)
            csv_file.seek(0)

            for (line_no,
                 line) in enumerate(csv.reader(csv_file, dialect=dialect)):
                if line_no:
                    try:
                        (first_name, last_name, gender, structure_level, type,
                         committee, comment) = line[:7]
                    except ValueError:
                        error_messages.append(
                            _('Ignoring malformed line %d in import file.') %
                            line_no + 1)
                        continue
                    user = User()
                    user.last_name = last_name
                    user.first_name = first_name
                    user.username = gen_username(first_name, last_name)
                    user.gender = gender
                    user.structure_level = structure_level
                    user.type = type
                    user.committee = committee
                    user.comment = comment
                    user.default_password = gen_password()
                    user.save()
                    user.reset_password()
                    count_success += 1
    except csv.Error:
        error_messages.appen(
            _('Import aborted because of severe errors in the input file.'))
    except UnicodeDecodeError:
        error_messages.appen(
            _('Import file has wrong character encoding, only UTF-8 is supported!'
              ))
    return (count_success, error_messages)
Esempio n. 4
0
def import_categories_and_topics(csvfile):
    """
    Performs the import of categories and topics from a csv file.
    """
    # Check encoding
    try:
        csvfile.read().decode("utf8")
    except UnicodeDecodeError:
        return_value = "", "", _("Import file has wrong character encoding, only UTF-8 is supported!")
    else:
        csvfile.seek(0)
        # Check dialect
        dialect = csv.Sniffer().sniff(csvfile.readline())
        dialect = csv_ext.patchup(dialect)
        csvfile.seek(0)
        # Parse CSV file
        topics = 0
        categories = 0
        for (line_no, line) in enumerate(csv.reader(csvfile, dialect=dialect)):
            if line_no == 0 or len(line) == 0:
                # Do not read the header line
                continue
            # Check and repair format
            if len(line) < 3:
                line.extend(["", ""])
            # Extract data
            title, submitter, category = line[:3]
            if not title:
                continue
            if category:
                category_object, created = Category.objects.get_or_create(name=category)
                if created:
                    categories += 1
            else:
                category_object = None
            Topic.objects.create(title=title, submitter=submitter, category=category_object)
            topics += 1
        success = _("%(categories)d categories and %(topics)d topics successfully imported.") % {
            "categories": categories,
            "topics": topics,
        }
        return_value = success, "", ""
    return return_value
Esempio n. 5
0
def import_agenda_items(csvfile):
    """
    Performs the import of agenda items form a csv file.
    """
    # Check encoding
    try:
        csvfile.read().decode('utf8')
    except UnicodeDecodeError:
        return_value = '', '', _('Import file has wrong character encoding, only UTF-8 is supported!')
    else:
        csvfile.seek(0)
        # Check dialect
        dialect = csv.Sniffer().sniff(csvfile.readline().decode('utf8'))
        dialect = csv_ext.patchup(dialect)
        csvfile.seek(0)
        # Parse CSV file
        with transaction.commit_on_success():
            success_lines = []
            error_lines = []
            for (line_no, line) in enumerate(csv.reader(
                    (line.decode('utf8') for line in csvfile.readlines()), dialect=dialect)):
                if line_no == 0:
                    # Do not read the header line
                    continue
                # Check format
                try:
                    title, text, duration = line[:3]
                except ValueError:
                    error_lines.append(line_no + 1)
                    continue
                if duration and re.match('^(?:[0-9]{1,2}:[0-5][0-9]|[0-9]+)$', duration) is None:
                    error_lines.append(line_no + 1)
                    continue
                Item.objects.create(title=title, text=text, duration=duration)
                success_lines.append(line_no + 1)
            success = _('%d items successfully imported.') % len(success_lines)
            if error_lines:
                error = _('Error in the following lines: %s.') % ', '.join(str(number) for number in error_lines)
            else:
                error = ''
            return_value = success, '', error
    return return_value
Esempio n. 6
0
def import_users(csv_file):
    error_messages = []
    count_success = 0
    try:
        # check for valid encoding (will raise UnicodeDecodeError if not)
        csv_file.read().decode('utf-8')
        csv_file.seek(0)

        with transaction.commit_on_success():
            dialect = csv.Sniffer().sniff(csv_file.readline())
            dialect = csv_ext.patchup(dialect)
            csv_file.seek(0)

            for (line_no, line) in enumerate(csv.reader(csv_file,
                                                        dialect=dialect)):
                if line_no:
                    try:
                        (first_name, last_name, gender, structure_level, type, committee, comment) = line[:7]
                    except ValueError:
                        error_messages.append(_('Ignoring malformed line %d in import file.') % line_no + 1)
                        continue
                    user = User()
                    user.last_name = last_name
                    user.first_name = first_name
                    user.username = gen_username(first_name, last_name)
                    user.gender = gender
                    user.structure_level = structure_level
                    user.type = type
                    user.committee = committee
                    user.comment = comment
                    user.default_password = gen_password()
                    user.save()
                    user.reset_password()
                    count_success += 1
    except csv.Error:
        error_messages.appen(_('Import aborted because of severe errors in the input file.'))
    except UnicodeDecodeError:
        error_messages.appen(_('Import file has wrong character encoding, only UTF-8 is supported!'))
    return (count_success, error_messages)
Esempio n. 7
0
def import_users(csvfile):
    error_messages = []
    count_success = 0
    try:
        # check for valid encoding (will raise UnicodeDecodeError if not)
        csvfile.read().decode('utf-8')
        csvfile.seek(0)

        with transaction.commit_on_success():
            dialect = csv.Sniffer().sniff(csvfile.readline().decode('utf-8'))
            dialect = csv_ext.patchup(dialect)
            csvfile.seek(0)

            for (line_no, line) in enumerate(
                    csv.reader(
                        (line.decode('utf8') for line in csvfile.readlines()),
                        dialect=dialect)):
                if line_no:
                    try:
                        (title, first_name, last_name, gender, email, groups,
                         structure_level, committee, about_me, comment,
                         is_active) = line[:11]
                    except ValueError:
                        error_messages.append(
                            _('Ignoring malformed line %d in import file.') %
                            (line_no + 1))
                        continue
                    if not first_name and not last_name:
                        error_messages.append(
                            _("In line %d you have to provide either 'first_name' or 'last_name'."
                              ) % (line_no + 1))
                        continue
                    user = User()
                    user.title = title
                    user.last_name = last_name
                    user.first_name = first_name
                    user.username = gen_username(first_name, last_name)
                    user.gender = gender
                    user.email = email
                    user.structure_level = structure_level
                    user.committee = committee
                    user.about_me = about_me
                    user.comment = comment
                    if is_active == '1':
                        user.is_active = True
                    else:
                        user.is_active = False
                    user.default_password = gen_password()
                    user.save()
                    for groupid in groups.split(','):
                        try:
                            if groupid and int(groupid):
                                Group.objects.get(
                                    pk=groupid).user_set.add(user)
                        except (Group.DoesNotExist, ValueError):
                            error_messages.append(
                                _('Ignoring group id "%(id)s" in line %(line)d which does not exist.'
                                  ) % {
                                      'id': groupid,
                                      'line': line_no + 1
                                  })
                            continue
                    user.reset_password()
                    user.save()
                    count_success += 1
    except csv.Error:
        error_messages.append(
            _('Import aborted because of severe errors in the input file.'))
    except UnicodeDecodeError:
        error_messages.append(
            _('Import file has wrong character encoding, only UTF-8 is supported!'
              ))

    # Build final success message
    if count_success:
        success_message = _(
            '%d new users were successfully imported.') % count_success
    else:
        success_message = ''

    # Build final error message with all error items (one bullet point for each csv line)
    full_error_message = ''
    if error_messages:
        full_error_message = "%s <ul>" % html_strong(_("Errors"))
        for error in error_messages:
            full_error_message += "<li>%s</li>" % error
        full_error_message += "</ul>"

    return success_message, '', full_error_message
Esempio n. 8
0
def import_users(csvfile):
    error_messages = []
    count_success = 0
    try:
        # check for valid encoding (will raise UnicodeDecodeError if not)
        csvfile.read().decode('utf-8')
        csvfile.seek(0)

        with transaction.commit_on_success():
            dialect = csv.Sniffer().sniff(csvfile.readline().decode('utf-8'))
            dialect = csv_ext.patchup(dialect)
            csvfile.seek(0)

            for (line_no, line) in enumerate(csv.reader(
                    (line.decode('utf8') for line in csvfile.readlines()),                                                        dialect=dialect)):
                if line_no:
                    try:
                        (title, first_name, last_name, gender, email, groups,
                         structure_level, committee, about_me, comment, is_active) = line[:11]
                    except ValueError:
                        error_messages.append(_('Ignoring malformed line %d in import file.') % (line_no + 1))
                        continue
                    if not first_name and not last_name:
                        error_messages.append(_("In line %d you have to provide either 'first_name' or 'last_name'.") % (line_no + 1))
                        continue
                    user = User()
                    user.title = title
                    user.last_name = last_name
                    user.first_name = first_name
                    user.username = gen_username(first_name, last_name)
                    user.gender = gender
                    user.email = email
                    user.structure_level = structure_level
                    user.committee = committee
                    user.about_me = about_me
                    user.comment = comment
                    if is_active == '1':
                        user.is_active = True
                    else:
                        user.is_active = False
                    user.default_password = gen_password()
                    user.save()
                    for groupid in groups:
                        try:
                            if groupid != ",":
                                Group.objects.get(pk=groupid).user_set.add(user)
                        except ValueError:
                            error_messages.append(_('Ignoring malformed group id in line %d.') % (line_no + 1))
                            continue
                        except Group.DoesNotExist:
                            error_messages.append(_('Group id %(id)s does not exists (line %(line)d).') % {'id': groupid, 'line': line_no + 1})
                            continue
                    user.reset_password()
                    count_success += 1
    except csv.Error:
        error_messages.append(_('Import aborted because of severe errors in the input file.'))
    except UnicodeDecodeError:
        error_messages.append(_('Import file has wrong character encoding, only UTF-8 is supported!'))

    # Build final success message
    if count_success:
        success_message = _('%d new participants were successfully imported.') % count_success
    else:
        success_message = ''

    # Build final error message with all error items (one bullet point for each csv line)
    full_error_message = ''
    if error_messages:
        full_error_message = "%s <ul>" % html_strong(_("Errors"))
        for error in error_messages:
            full_error_message += "<li>%s</li>" % error
        full_error_message += "</ul>"

    return success_message, '', full_error_message
Esempio n. 9
0
def import_motions(csvfile, default_submitter, override, importing_person=None):
    """
    Imports motions from a csv file.

    The file must be encoded in utf8. The first line (header) is ignored.
    If no or multiple submitters found, the default submitter is used. If
    a motion with a given identifier already exists, the motion is overridden,
    when the flag 'override' is True. If no or multiple categories found,
    the category is set to None.
    """
    count_success = 0
    count_lines = 0

    # Check encoding
    try:
        csvfile.read().decode('utf8')
    except UnicodeDecodeError:
        return '', '', _('Import file has wrong character encoding, only UTF-8 is supported!')
    csvfile.seek(0)

    with transaction.commit_on_success():
        dialect = csv.Sniffer().sniff(csvfile.readline())
        dialect = csv_ext.patchup(dialect)
        csvfile.seek(0)
        all_error_messages = []
        all_warning_messages = []
        for (line_no, line) in enumerate(csv.reader(csvfile, dialect=dialect)):
            warning = []
            if line_no < 1:
                # Do not read the header line
                continue
            importline = html_strong(_('Line %d:') % (line_no + 1))
            count_lines += 1
            # Check format
            try:
                (identifier, title, text, reason, submitter, category) = line[:6]
            except ValueError:
                msg = _('Line is malformed. Motion not imported. Please check the required values.')
                all_error_messages.append("%s %s" % (importline, msg))
                continue

            # Check existing motions according to the identifier
            if identifier:
                try:
                    motion = Motion.objects.get(identifier=identifier)
                except Motion.DoesNotExist:
                    motion = Motion(identifier=identifier)
                else:
                    if not override:
                        msg = _('Identifier already exists. Motion not imported.')
                        all_error_messages.append("%s %s" % (importline, msg))
                        continue
            else:
                motion = Motion()

            # Insert data
            motion.title = title
            motion.text = text
            motion.reason = reason
            if category:
                try:
                    motion.category = Category.objects.get(name=category)
                except Category.DoesNotExist:
                    warning.append(_('Category unknown. No category is used.'))
                except Category.MultipleObjectsReturned:
                    warning.append(_('Several suitable categories found. No category is used.'))
            motion.save()

            # Add submitter
            person_found = False
            if submitter:
                for person in Persons():
                    if person.clean_name == submitter.decode('utf8'):
                        if person_found:
                            warning.append(_('Several suitable submitters found.'))
                            person_found = False
                            break
                        else:
                            new_submitter = person
                            person_found = True
            if not person_found:
                warning.append(_('Submitter unknown. Default submitter is used.'))
                new_submitter = default_submitter

            # add all warnings of each csv line to one warning message
            if warning:
                warning_message_string = "%s " % importline
                warning_message_string += " ".join(warning)
                all_warning_messages.append(warning_message_string)

            motion.clear_submitters()
            motion.add_submitter(new_submitter)

            motion.write_log(message_list=[ugettext_noop('Motion imported')],
                             person=importing_person)
            count_success += 1

        # Build final error message with all error items (one bullet point for each csv line)
        full_error_message = ''
        if all_error_messages:
            full_error_message = "%s <ul>" % html_strong(_("Errors"))
            for error in all_error_messages:
                full_error_message += "<li>%s</li>" % error
            full_error_message += "</ul>"

        # Build final warning message with all warning items (one bullet point for each csv line)
        full_warning_message = ''
        if all_warning_messages:
            full_warning_message = "%s <ul>" % html_strong(_("Warnings"))
            for warning in all_warning_messages:
                full_warning_message += "<li>%s</li>" % warning
            full_warning_message += "</ul>"

        # Build final success message
        if count_success:
            success_message = '<strong>%s</strong><br>%s' % (
                _('Summary'),
                _('%(counts)d of %(total)d motions successfully imported.')
                % {'counts': count_success, 'total': count_lines})
        else:
            success_message = ''

    return success_message, full_warning_message, full_error_message
Esempio n. 10
0
def motion_import(request):
    if request.method == 'POST':
        form = MotionImportForm(request.POST, request.FILES)
        if form.is_valid():
            import_permitted = form.cleaned_data['import_permitted']
            try:
                # check for valid encoding (will raise UnicodeDecodeError if not)
                request.FILES['csvfile'].read().decode('utf-8')
                request.FILES['csvfile'].seek(0)

                users_generated = 0
                motions_generated = 0
                motions_modified = 0
                groups_assigned = 0
                groups_generated = 0
                with transaction.commit_on_success():
                    dialect = csv.Sniffer().sniff(request.FILES['csvfile'].readline())
                    dialect = csv_ext.patchup(dialect)
                    request.FILES['csvfile'].seek(0)
                    for (lno, line) in enumerate(csv.reader(request.FILES['csvfile'], dialect=dialect)):
                        # basic input verification
                        if lno < 1:
                            continue
                        try:
                            (number, title, text, reason, first_name, last_name, is_group) = line[:7]
                            if is_group.strip().lower() in ['y', 'j', 't', 'yes', 'ja', 'true', '1', 1]:
                                is_group = True
                            else:
                                is_group = False
                        except ValueError:
                            messages.error(request, _('Ignoring malformed line %d in import file.') % (lno + 1))
                            continue
                        form = MotionForm({'title': title, 'text': text, 'reason': reason})
                        if not form.is_valid():
                            messages.error(request, _('Ignoring malformed line %d in import file.') % (lno + 1))
                            continue
                        if number:
                            try:
                                number = abs(long(number))
                                if number < 1:
                                    messages.error(request, _('Ignoring malformed line %d in import file.') % (lno + 1))
                                    continue
                            except ValueError:
                                messages.error(request, _('Ignoring malformed line %d in import file.') % (lno + 1))
                                continue

                        if is_group:
                            # fetch existing groups or issue an error message
                            try:
                                user = Group.objects.get(name=last_name)
                                if user.group_as_person == False:
                                    messages.error(request, _('Ignoring line %d because the assigned group may not act as a person.') % (lno + 1))
                                    continue
                                else:
                                    user = get_person(user.person_id)

                                groups_assigned += 1
                            except Group.DoesNotExist:
                                group = Group()
                                group.group_as_person = True
                                group.description = _('Created by motion import.')
                                group.name = last_name
                                group.save()
                                groups_generated += 1

                                user = get_person(group.person_id)
                        else:
                            # fetch existing users or create new users as needed
                            try:
                                user = User.objects.get(first_name=first_name, last_name=last_name)
                            except User.DoesNotExist:
                                user = None
                            if user is None:
                                if not first_name or not last_name:
                                    messages.error(request, _('Ignoring line %d because it contains an incomplete first / last name pair.') % (lno + 1))
                                    continue

                                user = User()
                                user.last_name = last_name
                                user.first_name = first_name
                                user.username = gen_username(first_name, last_name)
                                user.structure_level = ''
                                user.committee = ''
                                user.gender = ''
                                user.type = ''
                                user.default_password = gen_password()
                                user.save()
                                user.reset_password()
                                users_generated += 1
                        # create / modify the motion
                        motion = None
                        if number:
                            try:
                                motion = Motion.objects.get(number=number)
                                motions_modified += 1
                            except Motion.DoesNotExist:
                                motion = None
                        if motion is None:
                            motion = Motion(submitter=user)
                            if number:
                                motion.number = number
                            motions_generated += 1

                        motion.title = form.cleaned_data['title']
                        motion.text = form.cleaned_data['text']
                        motion.reason = form.cleaned_data['reason']
                        if import_permitted:
                            motion.status = 'per'

                        motion.save(user, trivial_change=True)

                if motions_generated:
                    messages.success(request, ungettext('%d motion was successfully imported.',
                                                '%d motions were successfully imported.', motions_generated) % motions_generated)
                if motions_modified:
                    messages.success(request, ungettext('%d motion was successfully modified.',
                                                '%d motions were successfully modified.', motions_modified) % motions_modified)
                if users_generated:
                    messages.success(request, ungettext('%d new user was added.', '%d new users were added.', users_generated) % users_generated)

                if groups_generated:
                    messages.success(request, ungettext('%d new group was added.', '%d new groups were added.', groups_generated) % groups_generated)

                if groups_assigned:
                    messages.success(request, ungettext('%d group assigned to motions.', '%d groups assigned to motions.', groups_assigned) % groups_assigned)
                return redirect(reverse('motion_overview'))

            except csv.Error:
                messages.error(request, _('Import aborted because of severe errors in the input file.'))
            except UnicodeDecodeError:
                messages.error(request, _('Import file has wrong character encoding, only UTF-8 is supported!'))
        else:
            messages.error(request, _('Please check the form for errors.'))
    else:
        messages.warning(request, _("Attention: Existing motions will be modified if you import new motions with the same number."))
        messages.warning(request, _("Attention: Importing an motions without a number multiple times will create duplicates."))
        form = MotionImportForm()
    return {
        'form': form,
    }
Esempio n. 11
0
def import_motions(csv_file, default_submitter, override=False, importing_person=None):
    """
    Imports motions from a csv file.

    The file must be encoded in utf8. The first line (header) is ignored.
    If no or multiple submitters found, the default submitter is used. If
    a motion with a given identifier already exists, the motion is overridden,
    when the flag 'override' is true. If no or multiple categories found,
    the category is set to None.
    """
    error_messages = []
    warning_messages = []
    count_success = 0
    count_lines = 0

    # Check encoding
    try:
        csv_file.read().decode('utf8')
    except UnicodeDecodeError:
        return (0, [_('Import file has wrong character encoding, only UTF-8 is supported!')], [])
    csv_file.seek(0)

    with transaction.commit_on_success():
        dialect = csv.Sniffer().sniff(csv_file.readline())
        dialect = csv_ext.patchup(dialect)
        csv_file.seek(0)
        for (line_no, line) in enumerate(csv.reader(csv_file, dialect=dialect)):
            warnings = []
            if line_no < 1:
                # Do not read the header line
                continue

            count_lines += 1
            # Check format
            try:
                (identifier, title, text, reason, submitter, category) = line[:6]
            except ValueError:
                error_line = html_strong(_('Line %d of import file:') % (line_no + 1))
                msg = _('Line is malformed. Motion not imported. Please check the required values.')
                error_messages.append("%s<br>%s" % (error_line, msg))
                continue

            # Check existing motions according to the identifier
            if identifier:
                try:
                    motion = Motion.objects.get(identifier=identifier)
                except Motion.DoesNotExist:
                    motion = Motion(identifier=identifier)
                else:
                    if not override:
                        error_line = html_strong(_('Line %d of import file:') % (line_no + 1))
                        msg = _('Identifier already exists. Motion not imported.')
                        error_messages.append("%s<br>%s" % (error_line, msg))
                        continue
            else:
                motion = Motion()

            # Insert data
            motion.title = title
            motion.text = text
            motion.reason = reason
            if category:
                try:
                    motion.category = Category.objects.get(name=category)
                except Category.DoesNotExist:
                    warnings.append(_('Category unknown. No category is used.'))
                except Category.MultipleObjectsReturned:
                    warnings.append(_('Several suitable categories found. No category is used.'))
            motion.save()

            # Add submitter
            person_found = False
            if submitter:
                for person in Persons():
                    if person.clean_name == submitter.decode('utf8'):
                        if person_found:
                            warnings.append(_('Several suitable submitters found.'))
                            person_found = False
                            break
                        else:
                            new_submitter = person
                            person_found = True
            if not person_found:
                warnings.append(_('Submitter unknown. Default submitter is used.'))
                new_submitter = default_submitter

            # show summarized warning message for each import line
            if warnings:
                warning_line = _('Line %d of import file:') % (line_no + 1)
                warning_message_string = "%s<ul>" % html_strong(warning_line)
                for w in warnings:
                    warning_message_string += "<li>%s</li>" % w
                warning_message_string += "</ul>"
                warning_messages.append(warning_message_string)
            motion.clear_submitters()
            motion.add_submitter(new_submitter)

            motion.write_log(message_list=[ugettext_noop('Motion imported')],
                             person=importing_person)
            count_success += 1

    return (count_success, count_lines, error_messages, warning_messages)
Esempio n. 12
0
def import_motions(csv_file,
                   default_submitter,
                   override=False,
                   importing_person=None):
    """
    Imports motions from a csv file.

    The file must be encoded in utf8. The first line (header) is ignored.
    If no or multiple submitters found, the default submitter is used. If
    a motion with a given identifier already exists, the motion is overridden,
    when the flag 'override' is true. If no or multiple categories found,
    the category is set to None.
    """
    error_messages = []
    warning_messages = []
    count_success = 0
    count_lines = 0

    # Check encoding
    try:
        csv_file.read().decode('utf8')
    except UnicodeDecodeError:
        return (0, [
            _('Import file has wrong character encoding, only UTF-8 is supported!'
              )
        ], [])
    csv_file.seek(0)

    with transaction.commit_on_success():
        dialect = csv.Sniffer().sniff(csv_file.readline())
        dialect = csv_ext.patchup(dialect)
        csv_file.seek(0)
        for (line_no, line) in enumerate(csv.reader(csv_file,
                                                    dialect=dialect)):
            warnings = []
            if line_no < 1:
                # Do not read the header line
                continue

            count_lines += 1
            # Check format
            try:
                (identifier, title, text, reason, submitter,
                 category) = line[:6]
            except ValueError:
                error_line = html_strong(
                    _('Line %d of import file:') % (line_no + 1))
                msg = _(
                    'Line is malformed. Motion not imported. Please check the required values.'
                )
                error_messages.append("%s<br>%s" % (error_line, msg))
                continue

            # Check existing motions according to the identifier
            if identifier:
                try:
                    motion = Motion.objects.get(identifier=identifier)
                except Motion.DoesNotExist:
                    motion = Motion(identifier=identifier)
                else:
                    if not override:
                        error_line = html_strong(
                            _('Line %d of import file:') % (line_no + 1))
                        msg = _(
                            'Identifier already exists. Motion not imported.')
                        error_messages.append("%s<br>%s" % (error_line, msg))
                        continue
            else:
                motion = Motion()

            # Insert data
            motion.title = title
            motion.text = text
            motion.reason = reason
            if category:
                try:
                    motion.category = Category.objects.get(name=category)
                except Category.DoesNotExist:
                    warnings.append(
                        _('Category unknown. No category is used.'))
                except Category.MultipleObjectsReturned:
                    warnings.append(
                        _('Several suitable categories found. No category is used.'
                          ))
            motion.save()

            # Add submitter
            person_found = False
            if submitter:
                for person in Persons():
                    if person.clean_name == submitter.decode('utf8'):
                        if person_found:
                            warnings.append(
                                _('Several suitable submitters found.'))
                            person_found = False
                            break
                        else:
                            new_submitter = person
                            person_found = True
            if not person_found:
                warnings.append(
                    _('Submitter unknown. Default submitter is used.'))
                new_submitter = default_submitter

            # show summarized warning message for each import line
            if warnings:
                warning_line = _('Line %d of import file:') % (line_no + 1)
                warning_message_string = "%s<ul>" % html_strong(warning_line)
                for w in warnings:
                    warning_message_string += "<li>%s</li>" % w
                warning_message_string += "</ul>"
                warning_messages.append(warning_message_string)
            motion.clear_submitters()
            motion.add_submitter(new_submitter)

            motion.write_log(message_list=[ugettext_noop('Motion imported')],
                             person=importing_person)
            count_success += 1

    return (count_success, count_lines, error_messages, warning_messages)
Esempio n. 13
0
def motion_import(request):
    if request.method == 'POST':
        form = MotionImportForm(request.POST, request.FILES)
        if form.is_valid():
            import_permitted = form.cleaned_data['import_permitted']
            try:
                # check for valid encoding (will raise UnicodeDecodeError if not)
                request.FILES['csvfile'].read().decode('utf-8')
                request.FILES['csvfile'].seek(0)

                users_generated = 0
                motions_generated = 0
                motions_modified = 0
                groups_assigned = 0
                groups_generated = 0
                with transaction.commit_on_success():
                    dialect = csv.Sniffer().sniff(
                        request.FILES['csvfile'].readline())
                    dialect = csv_ext.patchup(dialect)
                    request.FILES['csvfile'].seek(0)
                    for (lno, line) in enumerate(
                            csv.reader(request.FILES['csvfile'],
                                       dialect=dialect)):
                        # basic input verification
                        if lno < 1:
                            continue
                        try:
                            (number, title, text, reason, first_name,
                             last_name, is_group) = line[:7]
                            if is_group.strip().lower() in [
                                    'y', 'j', 't', 'yes', 'ja', 'true', '1', 1
                            ]:
                                is_group = True
                            else:
                                is_group = False
                        except ValueError:
                            messages.error(
                                request,
                                _('Ignoring malformed line %d in import file.')
                                % (lno + 1))
                            continue
                        form = MotionForm({
                            'title': title,
                            'text': text,
                            'reason': reason
                        })
                        if not form.is_valid():
                            messages.error(
                                request,
                                _('Ignoring malformed line %d in import file.')
                                % (lno + 1))
                            continue
                        if number:
                            try:
                                number = abs(long(number))
                                if number < 1:
                                    messages.error(
                                        request,
                                        _('Ignoring malformed line %d in import file.'
                                          ) % (lno + 1))
                                    continue
                            except ValueError:
                                messages.error(
                                    request,
                                    _('Ignoring malformed line %d in import file.'
                                      ) % (lno + 1))
                                continue

                        if is_group:
                            # fetch existing groups or issue an error message
                            try:
                                user = Group.objects.get(name=last_name)
                                if user.group_as_person == False:
                                    messages.error(
                                        request,
                                        _('Ignoring line %d because the assigned group may not act as a person.'
                                          ) % (lno + 1))
                                    continue
                                else:
                                    user = get_person(user.person_id)

                                groups_assigned += 1
                            except Group.DoesNotExist:
                                group = Group()
                                group.group_as_person = True
                                group.description = _(
                                    'Created by motion import.')
                                group.name = last_name
                                group.save()
                                groups_generated += 1

                                user = get_person(group.person_id)
                        else:
                            # fetch existing users or create new users as needed
                            try:
                                user = User.objects.get(first_name=first_name,
                                                        last_name=last_name)
                            except User.DoesNotExist:
                                user = None
                            if user is None:
                                if not first_name or not last_name:
                                    messages.error(
                                        request,
                                        _('Ignoring line %d because it contains an incomplete first / last name pair.'
                                          ) % (lno + 1))
                                    continue

                                user = User()
                                user.last_name = last_name
                                user.first_name = first_name
                                user.username = gen_username(
                                    first_name, last_name)
                                user.structure_level = ''
                                user.committee = ''
                                user.gender = ''
                                user.type = ''
                                user.default_password = gen_password()
                                user.save()
                                user.reset_password()
                                users_generated += 1
                        # create / modify the motion
                        motion = None
                        if number:
                            try:
                                motion = Motion.objects.get(number=number)
                                motions_modified += 1
                            except Motion.DoesNotExist:
                                motion = None
                        if motion is None:
                            motion = Motion(submitter=user)
                            if number:
                                motion.number = number
                            motions_generated += 1

                        motion.title = form.cleaned_data['title']
                        motion.text = form.cleaned_data['text']
                        motion.reason = form.cleaned_data['reason']
                        if import_permitted:
                            motion.status = 'per'

                        motion.save(user, trivial_change=True)

                if motions_generated:
                    messages.success(
                        request,
                        ungettext('%d motion was successfully imported.',
                                  '%d motions were successfully imported.',
                                  motions_generated) % motions_generated)
                if motions_modified:
                    messages.success(
                        request,
                        ungettext('%d motion was successfully modified.',
                                  '%d motions were successfully modified.',
                                  motions_modified) % motions_modified)
                if users_generated:
                    messages.success(
                        request,
                        ungettext('%d new user was added.',
                                  '%d new users were added.', users_generated)
                        % users_generated)

                if groups_generated:
                    messages.success(
                        request,
                        ungettext('%d new group was added.',
                                  '%d new groups were added.',
                                  groups_generated) % groups_generated)

                if groups_assigned:
                    messages.success(
                        request,
                        ungettext('%d group assigned to motions.',
                                  '%d groups assigned to motions.',
                                  groups_assigned) % groups_assigned)
                return redirect(reverse('motion_overview'))

            except csv.Error:
                messages.error(
                    request,
                    _('Import aborted because of severe errors in the input file.'
                      ))
            except UnicodeDecodeError:
                messages.error(
                    request,
                    _('Import file has wrong character encoding, only UTF-8 is supported!'
                      ))
        else:
            messages.error(request, _('Please check the form for errors.'))
    else:
        messages.warning(
            request,
            _("Attention: Existing motions will be modified if you import new motions with the same number."
              ))
        messages.warning(
            request,
            _("Attention: Importing an motions without a number multiple times will create duplicates."
              ))
        form = MotionImportForm()
    return {
        'form': form,
    }
Esempio n. 14
0
def import_users(csv_file):
    error_messages = []
    count_success = 0
    try:
        # check for valid encoding (will raise UnicodeDecodeError if not)
        csv_file.read().decode('utf-8')
        csv_file.seek(0)

        with transaction.commit_on_success():
            dialect = csv.Sniffer().sniff(csv_file.readline())
            dialect = csv_ext.patchup(dialect)
            csv_file.seek(0)

            for (line_no,
                 line) in enumerate(csv.reader(csv_file, dialect=dialect)):
                if line_no:
                    try:
                        (title, first_name, last_name, gender, email, groups,
                         structure_level, committee, about_me, comment,
                         is_active) = line[:11]
                    except ValueError:
                        error_messages.append(
                            _('Ignoring malformed line %d in import file.') %
                            (line_no + 1))
                        continue
                    user = User()
                    user.title = title
                    user.last_name = last_name
                    user.first_name = first_name
                    user.username = gen_username(first_name, last_name)
                    user.gender = gender
                    user.email = email
                    user.structure_level = structure_level
                    user.committee = committee
                    user.about_me = about_me
                    user.comment = comment
                    if is_active == '1':
                        user.is_active = True
                    else:
                        user.is_active = False
                    user.default_password = gen_password()
                    user.save()
                    for groupid in groups:
                        try:
                            if groupid != ",":
                                Group.objects.get(
                                    pk=groupid).user_set.add(user)
                        except ValueError:
                            error_messages.append(
                                _('Ignoring malformed group id in line %d.') %
                                (line_no + 1))
                            continue
                        except Group.DoesNotExist:
                            error_messages.append(
                                _('Group id %(id)s does not exists (line %(line)d).'
                                  ) % {
                                      'id': groupid,
                                      'line': line_no + 1
                                  })
                            continue
                    user.reset_password()
                    count_success += 1
    except csv.Error:
        error_messages.append(
            _('Import aborted because of severe errors in the input file.'))
    except UnicodeDecodeError:
        error_messages.append(
            _('Import file has wrong character encoding, only UTF-8 is supported!'
              ))
    return (count_success, error_messages)