You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. import os
  2. from PIL import Image as PImage
  3. from django.core.files import File
  4. from django.core.exceptions import FieldError
  5. from oscar.core.loading import import_module
  6. import_module('image.exceptions', ['ImageImportException', 'IdenticalImageException'], locals())
  7. import_module('product.models', ['Item'], locals())
  8. import_module('image.models', ['Image'], locals())
  9. class Importer(object):
  10. allowed_extensions = ['.jpeg','.jpg','.gif','.png']
  11. def __init__(self, logger, field):
  12. self.logger = logger
  13. self._field = field
  14. def handle(self, dirname):
  15. stats = {
  16. 'num_processed': 0,
  17. 'num_skipped': 0,
  18. 'num_invalid': 0
  19. }
  20. for filename in self._get_image_files(dirname):
  21. try:
  22. lookup_value = self._get_lookup_value_from_filename(filename)
  23. self._process_image(dirname, filename, lookup_value)
  24. stats['num_processed'] += 1
  25. except Item.MultipleObjectsReturned:
  26. self.logger.warning("Multiple products matching %s='%s', skipping" % (self._field, lookup_value))
  27. stats['num_skipped'] += 1
  28. except Item.DoesNotExist:
  29. self.logger.warning("No item matching %s='%s'" % (self._field, lookup_value))
  30. stats['num_skipped'] += 1
  31. except IdenticalImageException:
  32. self.logger.warning(" - Identical image already exists for %s='%s', skipping" % (self._field, lookup_value))
  33. stats['num_skipped'] += 1
  34. except IOError:
  35. raise ImageImportException('%s is not a valid image' % filename)
  36. stats['num_invalid'] += 1
  37. except FieldError, e:
  38. raise ImageImportException(e)
  39. self._process_image(dirname, filename)
  40. self.logger.info("Finished image import: %(num_processed)d imported, %(num_skipped)d skipped" % stats)
  41. def _get_image_files(self, dirname):
  42. filenames = []
  43. for filename in os.listdir(dirname):
  44. ext = os.path.splitext(filename)[1]
  45. if os.path.isfile(os.path.join(dirname, filename)) and ext in self.allowed_extensions:
  46. filenames.append(filename)
  47. return filenames
  48. def _process_image(self, dirname, filename, lookup_value):
  49. file_path = os.path.join(dirname, filename)
  50. trial_image = PImage.open(file_path)
  51. trial_image.verify()
  52. kwargs = {self._field: lookup_value}
  53. item = Item._default_manager.get(**kwargs)
  54. new_data = open(file_path).read()
  55. next_index = 0
  56. for existing in item.images.all():
  57. next_index = existing.display_order + 1
  58. if new_data == existing.original.read():
  59. raise IdenticalImageException()
  60. new_file = File(open(file_path))
  61. im = Image(product=item, display_order=next_index)
  62. im.original.save(filename, new_file, save=False)
  63. im.save()
  64. self.logger.info(' - Image added to "%s"' % item)
  65. def _fetch_item(self, filename):
  66. kwargs = {self._field: self._get_lookup_value_from_filename(filename)}
  67. return Item._default_manager.get(**kwargs)
  68. def _get_lookup_value_from_filename(self, filename):
  69. return os.path.splitext(filename)[0]