Keine Beschreibung

import_from_excel.py 3.5KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. from django.core.management.base import BaseCommand, CommandError
  2. import xlrd
  3. from ... import models
  4. from pick import pick
  5. class SheetWrapper(object):
  6. def __init__(self, sheet):
  7. self.sheet = sheet
  8. def __str__(self):
  9. return self.sheet.name
  10. def import_sheet(sheet, category):
  11. start_row = None
  12. start_col = None
  13. for row in range(sheet.nrows):
  14. for col in range(sheet.ncols):
  15. cell = sheet.cell(row, col)
  16. if cell.ctype == xlrd.XL_CELL_TEXT:
  17. if cell.value.strip().lower() == 'day':
  18. start_row = row + 1
  19. start_col = col
  20. break
  21. if start_row is None:
  22. raise RuntimeError("No 'Day' column found in sheet %s" % sheet.name)
  23. if start_row >= sheet.nrows:
  24. raise RuntimeError("'Day' column in sheet %s contains no data" % sheet.name)
  25. if start_col >= sheet.ncols:
  26. raise RuntimeError("No columns found to the right of the 'Day' column in sheet %s" % sheet.name)
  27. expected_day = 1
  28. end_row = None
  29. feed_items = []
  30. for row in range(start_row, sheet.nrows):
  31. cell = sheet.cell(row, start_col)
  32. if cell.ctype != xlrd.XL_CELL_NUMBER:
  33. break
  34. day = int(cell.value)
  35. if day != expected_day:
  36. raise RuntimeError("'Day' column in sheet %s contains an unexpected value: %s (expecting %s)" % (sheet.name, day, expected_day))
  37. cell = sheet.cell(row, start_col + 1)
  38. if cell.ctype != xlrd.XL_CELL_TEXT:
  39. raise RuntimeError("No text found for day %s in sheet %s" % (day, sheet.name))
  40. feed_items.append({'day': day, 'message_text': cell.value})
  41. expected_day += 1
  42. end_row = row
  43. if end_row + 1 < sheet.nrows:
  44. cell = sheet.cell(end_row + 1, start_col)
  45. if cell.ctype != xlrd.XL_CELL_EMPTY:
  46. raise RuntimeError("'Day' column in sheet %s contains a non-numerical value: %s" % (sheet.name, cell.value))
  47. option, index = pick(['No', 'Yes'], title='You are about to import days %s to %s\nfrom sheet %s\ninto category %s.\nContinue?' % (feed_items[0]['day'], feed_items[-1]['day'], sheet.name, category.name))
  48. if index == 0:
  49. return
  50. models.FeedItem.objects.filter(feed_category=category).delete()
  51. for feed_item in feed_items:
  52. models.FeedItem.objects.create(
  53. feed_category=category,
  54. day_number=feed_item['day'],
  55. message_text=feed_item['message_text']
  56. )
  57. class Command(BaseCommand):
  58. help = 'Imports feed items from an Excel spreedsheet.'
  59. def add_arguments(self, parser):
  60. parser.add_argument('file_name')
  61. def handle(self, *args, **options):
  62. file_name = options['file_name']
  63. category_choices = ['>> Quit']
  64. for category in models.FeedCategory.objects.order_by('name'):
  65. category_choices.append(category)
  66. book = xlrd.open_workbook(file_name)
  67. sheet_choices = ['>> Quit']
  68. for sheet in book.sheets():
  69. sheet_choices.append(SheetWrapper(sheet))
  70. while True:
  71. option, index = pick(sheet_choices, title='Select the worksheet to be imported:')
  72. if index == 0:
  73. break
  74. sheet = sheet_choices[index].sheet
  75. option, index = pick(category_choices, title='Select the destination category:')
  76. if index == 0:
  77. break
  78. category = category_choices[index]
  79. import_sheet(sheet, category)