OpenSlides/openslides/motion/csv_import.py
Emanuel Schuetze a97cf4a680 Motion import improved:
- add semicolon support (use utils/csv_ext.py as participant import)
- show all warnings of each line in one warning message
- show success message with total counter (x of n motions imported).
- improved warning and error strings
2013-05-30 22:23:38 +02:00

131 lines
5.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
openslides.motion.csv_import
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Functions to import motions from a csv file.
:copyright: (c) 20112013 by the OpenSlides team, see AUTHORS.
:license: GNU GPL, see LICENSE for more details.
"""
# TODO: Rename the file to 'csv.py' when we drop python2 support. At the moment
# the name csv has a conflict with the core-module. See:
# http://docs.python.org/2/tutorial/modules.html#intra-package-references
import csv
from django.db import transaction
from django.utils.translation import ugettext as _, ugettext_noop
from openslides.utils import csv_ext
from openslides.utils.person.api import Persons
from openslides.utils.utils import html_strong
from .models import Motion, Category
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)