bgneal@535: """
bgneal@535: import_old_potd.py - For importing POTD's from SG101 1.0 as csv files.
bgneal@535: 
bgneal@535: """
bgneal@535: from __future__ import with_statement
bgneal@535: import csv
bgneal@535: import optparse
bgneal@535: import sys
bgneal@535: from datetime import datetime
bgneal@535: 
bgneal@535: from django.core.management.base import LabelCommand, CommandError
bgneal@535: from django.contrib.auth.models import User
bgneal@535: 
bgneal@535: from potd.models import Photo
bgneal@535: from legacy.phpbb import unescape
bgneal@535: import legacy.data
bgneal@535: 
bgneal@535: 
bgneal@535: ID_OFFSET = 100
bgneal@535: 
bgneal@535: 
bgneal@535: class PathError(Exception):
bgneal@535:     pass
bgneal@535: 
bgneal@535: def convert_path(old_path):
bgneal@535:     """
bgneal@535:     Converts the old POTD path to a new one.
bgneal@535: 
bgneal@535:     """
bgneal@535:     if old_path.startswith('images/potd/'):
bgneal@535:         return "potd/1.0/%s" % old_path[12:]
bgneal@535:     else:
bgneal@535:         raise PathError("Unknown path %s" % old_path)
bgneal@535: 
bgneal@535: 
bgneal@535: class Command(LabelCommand):
bgneal@535:     args = '<filename filename ...>'
bgneal@535:     help = "Imports POTD's from the old database in CSV format"
bgneal@535:     option_list = LabelCommand.option_list + (
bgneal@535:         optparse.make_option("-p", "--progress", action="store_true",
bgneal@535:             help="Output a . after every 20 items to show progress"),
bgneal@535:     )
bgneal@535: 
bgneal@535:     def handle_label(self, filename, **options):
bgneal@535:         """
bgneal@535:         Process each line in the CSV file given by filename by
bgneal@535:         creating a new Photo
bgneal@535: 
bgneal@535:         """
bgneal@535:         self.show_progress = options.get('progress')
bgneal@535:         self.users = {}
bgneal@535: 
bgneal@535:         try:
bgneal@535:             with open(filename, "rb") as f:
bgneal@535:                 self.reader = csv.DictReader(f)
bgneal@535:                 num_rows = 0
bgneal@535:                 try:
bgneal@535:                     for row in self.reader:
bgneal@535:                         self.process_row(row)
bgneal@535:                         num_rows += 1
bgneal@535:                         if self.show_progress and num_rows % 20 == 0:
bgneal@535:                             sys.stdout.write('.')
bgneal@535:                             sys.stdout.flush()
bgneal@535:                 except csv.Error, e:
bgneal@535:                     raise CommandError("CSV error: %s %s %s" % (
bgneal@535:                         filename, self.reader.line_num, e))
bgneal@535: 
bgneal@535:                 print
bgneal@535: 
bgneal@535:         except IOError:
bgneal@535:             raise CommandError("Could not open file: %s" % filename)
bgneal@535: 
bgneal@535:     def process_row(self, row):
bgneal@535:         """
bgneal@535:         Process one row from the CSV file: create a Photo object for
bgneal@535:         the row and save it in the database.
bgneal@535: 
bgneal@535:         """
bgneal@535:         try:
bgneal@535:             submitter = self._get_user(row['submitted_by'].decode('latin-1'))
bgneal@535:         except User.DoesNotExist:
bgneal@535:             print "Could not find user %s for potd %s; skipping." % (
bgneal@535:                     row['submitted_by'], row['pid'])
bgneal@535:             return
bgneal@535: 
bgneal@535:         desc = row['description'].decode('latin-1').replace('\n', '\n<br />')
bgneal@535: 
bgneal@535:         try:
bgneal@535:             photo = Photo(
bgneal@535:                 id=int(row['pid']) + ID_OFFSET,
bgneal@535:                 photo=convert_path(row['photo_path']),
bgneal@535:                 thumb=convert_path(row['thumb_path']),
bgneal@535:                 caption=unescape(row['title'].decode('latin-1')),
bgneal@535:                 description=desc,
bgneal@535:                 user=submitter,
bgneal@535:                 date_added=datetime.strptime(row['date_added'],
bgneal@535:                     "%Y-%m-%d %H:%M:%S"),
bgneal@535:                 potd_count=int(row['chosen_count']))
bgneal@535:         except PathError, ex:
bgneal@535:             self.stderr.write("\n%s, skipping\n" % ex)
bgneal@535:             return
bgneal@535: 
bgneal@535:         photo.save()
bgneal@535: 
bgneal@535:     def _get_user(self, username):
bgneal@535:         """
bgneal@535:         Returns the user object with the given username.
bgneal@535:         Throws User.DoesNotExist if not found.
bgneal@535: 
bgneal@535:         """
bgneal@535:         try:
bgneal@535:             return self.users[username]
bgneal@535:         except KeyError:
bgneal@535:             pass
bgneal@535: 
bgneal@535:         try:
bgneal@535:             user = User.objects.get(username=username)
bgneal@535:         except User.DoesNotExist:
bgneal@535:             old_name = username.lower()
bgneal@535:             try:
bgneal@535:                 user = User.objects.get(
bgneal@535:                         username=legacy.data.KNOWN_USERNAME_CHANGES[old_name])
bgneal@535:             except KeyError:
bgneal@535:                 raise User.DoesNotExist
bgneal@535: 
bgneal@535:         self.users[username] = user
bgneal@535:         return user