# -*- coding: utf-8 -*-
# This file is part of Shuup.
#
# Copyright (c) 2012-2017, Shoop Commerce Ltd. All rights reserved.
#
# This source code is licensed under the OSL-3.0 license found in the
# LICENSE file in the root directory of this source tree.
from __future__ import with_statement
from django.db import models
from django.utils.encoding import python_2_unicode_compatible
from django.utils.translation import ugettext_lazy as _
from easy_thumbnails.exceptions import InvalidImageFormatError
from easy_thumbnails.files import get_thumbnailer
from enumfields import Enum, EnumIntegerField
from filer.fields.file import FilerFileField
from parler.models import TranslatableModel, TranslatedFields
from shuup.core.fields import InternalIdentifierField
from shuup.utils.analog import define_log_model
class ProductMediaKind(Enum):
GENERIC_FILE = 1
IMAGE = 2
DOCUMENTATION = 3
SAMPLE = 4
class Labels:
GENERIC_FILE = _('file')
IMAGE = _('image')
DOCUMENTATION = _('documentation')
SAMPLE = _('sample')
@python_2_unicode_compatible
class ProductMedia(TranslatableModel):
identifier = InternalIdentifierField(unique=True)
product = models.ForeignKey("Product", related_name="media", on_delete=models.CASCADE, verbose_name=_('product'))
shops = models.ManyToManyField("Shop", related_name="product_media", verbose_name=_('shops'), help_text=_(
"Select which shops you would like the product media to be visible in."
)
)
kind = EnumIntegerField(
ProductMediaKind, db_index=True, default=ProductMediaKind.GENERIC_FILE, verbose_name=_('kind'), help_text=_(
"Select what type the media is. It can either be a normal file, part of the documentation, or a sample."
)
)
file = FilerFileField(blank=True, null=True, verbose_name=_('file'), on_delete=models.CASCADE)
external_url = models.URLField(
blank=True, null=True, verbose_name=_('URL'),
help_text=_("Enter URL to external file. If this field is filled, the selected media doesn't apply.")
)
ordering = models.IntegerField(default=0, verbose_name=_('ordering'), help_text=_(
"You enter the numerical order that your image will be displayed on your product page."
)
)
# Status
enabled = models.BooleanField(db_index=True, default=True, verbose_name=_("enabled"))
public = models.BooleanField(
default=True, blank=True, verbose_name=_('public (shown on product page)'), help_text=_(
"Check this if you would like the image shown on your product page. Checked by default."
)
)
purchased = models.BooleanField(
default=False, blank=True, verbose_name=_('purchased (shown for finished purchases)'), help_text=_(
"Select this if you would like the product media shown for completed purchases."
)
)
translations = TranslatedFields(
title=models.CharField(blank=True, max_length=128, verbose_name=_('title'), help_text=_(
"Choose a title for your product media. This will help it be found in your store and on the web."
)
),
description=models.TextField(blank=True, verbose_name=_('description'), help_text=_(
"Write a description for your product media. This will help it be found in your store and on the web."
)
),
)
class Meta:
verbose_name = _('product attachment')
verbose_name_plural = _('product attachments')
ordering = ["ordering", ]
def __str__(self): # pragma: no cover
return self.effective_title
@property
def effective_title(self):
title = self.safe_translation_getter("title")
if title:
return title
if self.file_id:
return self.file.label
if self.external_url:
return self.external_url
return _('attachment')
@property
def url(self):
if self.external_url:
return self.external_url
if self.file:
return self.file.url
return ""
@property
def easy_thumbnails_thumbnailer(self):
"""
Get `Thumbnailer` instance.
Will return `None` if file cannot be thumbnailed.
:rtype:easy_thumbnails.files.Thumbnailer|None
"""
if not self.file_id:
return None
if self.kind != ProductMediaKind.IMAGE:
return None
return get_thumbnailer(self.file)
ProductMediaLogEntry = define_log_model(ProductMedia)