+import re
+from django.db import DatabaseError, transaction
+
+from quotes.models import QuoteTag, Quote, Work, Author
+
+def get_or_create_author(authorname, resultcontext):
+ authorname = authorname.strip()
+ try:
+ return Author.objects.get(name=authorname)
+ except Author.DoesNotExist:
+ a = Author.objects.create(name=authorname,
+ pvt_notes="<p>Created during mass import</p>")
+ resultcontext["created_authors"] += [a]
+ return a
+
+def get_or_create_work(workname, author, resultcontext):
+ workname = workname.strip()
+ try:
+ return Work.objects.get(name=workname, author=author)
+ except Work.DoesNotExist:
+ w = Work.objects.create(name=workname,
+ author=author,
+ pvt_notes="<p>Created during mass import</p>")
+ resultcontext["created_works"] += [w]
+ return w
+
+def get_or_create_tag(tagname, resultcontext):
+ try:
+ return QuoteTag.objects.get(tag=tagname)
+ except QuoteTag.DoesNotExist:
+ t = QuoteTag.objects.create(tag=tagname)
+ resultcontext["created_tags"] += [t]
+ return t
+
+def add_tags_on_quote(quote, tagline, resultcontext):
+ for tagname in tagline.split(","):
+ tagname = tagname.strip()
+ if not tagname:
+ continue
+ tag = get_or_create_tag(tagname, resultcontext)
+ quote.tags.add(tag)
+
+def paragraphize(text):
+ paragraph = ""
+ for line in text.splitlines():
+ line = line.strip()
+ if not line: continue
+ paragraph += "<p>%s</p>" % line
+ # rest of the HTML will be bleach.clean()'d
+ return paragraph
+
+def create_quote(quotetext, authorname, workname, tagline, resultcontext):
+ author = get_or_create_author(authorname, resultcontext)
+ work = get_or_create_work(workname, author, resultcontext)
+ quotetext = paragraphize(quotetext)
+ quote = Quote.objects.create(text=quotetext, work=work)
+ add_tags_on_quote(quote, tagline, resultcontext)
+ resultcontext["created_quotes"] += [quote]
+
+def create_all_quotes(allquotes, resultcontext):
+ quotesep = re.compile(r'^\s*===+.*$', re.MULTILINE)
+ elemsep = re.compile(r'^\s*---+.*$', re.MULTILINE)
+
+ for fullquote in quotesep.split(allquotes):
+ if not fullquote: continue
+
+ elements = elemsep.split(fullquote)
+ if len(elements) not in [3, 4]:
+ resultcontext["rejected"] += [fullquote]
+ continue
+ quotetext, authorname, workname = elements[0:3]
+ if len(elements) == 4:
+ tagline = elements[3]
+ else:
+ tagline = ''
+ create_quote(quotetext, authorname, workname, tagline,
+ resultcontext)
+
+def domassimport(allquotes):
+ resultcontext = {}
+ resultcontext["created_quotes"] = []
+ resultcontext["created_tags"] = []
+ resultcontext["created_works"] = []
+ resultcontext["created_authors"] = []
+ resultcontext["rejected"] = []
+ resultcontext["fatal_error"] = False
+
+ try:
+ with transaction.atomic():
+ create_all_quotes(allquotes, resultcontext)
+ except DatabaseError as e:
+ resultcontext["fatal_error"] = True
+ resultcontext["fatal_error_message"] = e.__cause__
+
+ return resultcontext