This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
import os | |
import urllib | |
import pytz | |
from datetime import datetime, date | |
from django.db import models | |
from django.db.models import signals | |
from django.conf import settings | |
from stream_django.activity import Activity | |
from sorl.thumbnail import ImageField | |
from accounts.models import Seller | |
from categories.models import ( | |
Category, ProductFamily, FeatureCategory, | |
FeatureProductFamily, ProductType, FeatureProductType) | |
from core.mail import EmailMandrill | |
from apps.core.storage import AzureBlobStorage | |
from core.utils import sum_days | |
from publications.tuples.generic import PRODUCT_QUALITY, WEIGHT_RANGES | |
def get_path_image_ad(instance, filename): | |
return os.path.join( | |
'parent/%d/category/%d/images/' % ( | |
instance.category.parent_category.id, | |
instance.category.id), | |
filename) | |
class Ad(models.Model, Activity): | |
created = models.DateTimeField('Creado', editable=False, auto_now_add=True) | |
updated = models.DateTimeField( | |
'Actualizado', editable=False, auto_now=True) | |
seller = models.ForeignKey(Seller, verbose_name='Vendedor') | |
category = models.ForeignKey(Category) | |
product_family = models.ForeignKey(ProductFamily, blank=True, null=True) | |
product_type = models.ForeignKey(ProductType, blank=True, null=True) | |
title = models.CharField(max_length=80) | |
text = models.TextField() | |
description = models.TextField(blank=True, null=True) | |
sale_price = models.DecimalField( | |
'Precio de Venta', max_digits=7, decimal_places=2) | |
origin_price = models.DecimalField( | |
max_digits=7, decimal_places=2, blank=True, null=True) | |
quality = models.CharField( | |
'Calidad', max_length=3, choices=PRODUCT_QUALITY, default='N') | |
quantity = models.PositiveIntegerField( | |
'Disponibles', blank=True, null=True) | |
weight = models.PositiveIntegerField( | |
choices=WEIGHT_RANGES, blank=True, null=True) | |
relaunch_date = models.DateTimeField(blank=True, null=True) | |
image = ImageField( | |
upload_to=get_path_image_ad, | |
storage=AzureBlobStorage(), | |
blank=True, null=True) | |
sku = models.CharField(max_length=100, unique=True, blank=True, null=True) | |
product_reference = models.CharField(max_length=100, blank=True, null=True) | |
sold = models.BooleanField(default=False) # marcar como vendido | |
visitors = models.PositiveIntegerField('Visitantes', blank=True, null=True) | |
buyers = models.PositiveIntegerField('Compradores', blank=True, null=True) | |
features_cat = models.ManyToManyField(FeatureCategory, blank=True) | |
features_fam = models.ManyToManyField(FeatureProductFamily, blank=True) | |
features_pt = models.ManyToManyField(FeatureProductType, blank=True) | |
in_trash = models.BooleanField(default=False) | |
class Meta: | |
verbose_name = 'Producto | Anuncio' | |
verbose_name_plural = 'Productos | Anuncios' | |
def __unicode__(self): | |
return '%s | %s' % (self.sku, self.title) | |
@property | |
def brand(self): | |
if self.features_cat.filter( | |
parent_feature__name='Fabricante').exists(): | |
return self.features_cat.filter( | |
parent_feature__name='Fabricante')[0].name | |
elif self.features_cat.filter( | |
parent_feature__name='Autor').exists(): | |
return self.features_cat.filter( | |
parent_feature__name='Autor')[0].name | |
elif self.features_cat.filter( | |
parent_feature__name='Artista').exists(): | |
return self.features_cat.filter( | |
parent_feature__name='Artista')[0].name | |
elif self.features_cat.filter( | |
parent_feature__name='Realizador').exists(): | |
return self.features_cat.filter( | |
parent_feature__name='Realizador')[0].name | |
else: | |
return '' | |
@property | |
def activity_object_attr(self): | |
return self | |
@property | |
def activity_actor_attr(self): | |
return self.seller.user | |
@property | |
def activity_time(self): | |
return self.created | |
def tuple_str(self, tupla, field): | |
for x in tupla: | |
if x[0] == self.__getattribute__(field): | |
return x[1] | |
def expiry_date(self): | |
if self.relaunch_date: | |
published = self.relaunch_date | |
else: | |
published = self.created | |
return sum_days( | |
published, self.seller.expiration_days | |
).replace(tzinfo=pytz.utc) | |
def today(self): | |
return datetime.utcnow().replace(tzinfo=pytz.utc) | |
def is_favorite(self, user): | |
from favorites.models import Favorite | |
try: | |
Favorite.objects.get(item=self, user=user) | |
except Favorite.DoesNotExist: | |
return False | |
else: | |
return True | |
""" | |
Properties:: Accessible from template | |
""" | |
@property | |
def status(self): | |
return self.tuple_str(PRODUCT_QUALITY, 'quality') | |
@property | |
def is_lapsed(self): | |
if self.expiry_date() > self.today(): | |
return False | |
else: | |
return True | |
@property | |
def in_the_trash(self): | |
return self.sold or self.is_lapsed or self.in_trash | |
@property | |
def remaining_days(self): | |
if not self.is_lapsed: | |
return (self.expiry_date() - self.today()).days | |
""" | |
Social methods | |
""" | |
@property | |
def text_to_share(self): | |
""" | |
{Título} en ${Precio}, {Estado}. Descúbrelo en #Prixealo | |
""" | |
return ( | |
"{titulo} en ${precio}, {estado}. " | |
"Descúbrelo en #Prixealo.").format( | |
titulo=self.title, | |
precio=int(self.sale_price), | |
estado=self.status) | |
@property | |
def share_facebook(self): | |
""" | |
{Título} en ${Precio}, {Estado}. Descúbrelo en #Prixealo | |
Descúbrelo en #Prixealo - Compra y Vende Social | |
Nobre de Tienda | |
+ Link Detalle anuncio | |
""" | |
return 'https://www.facebook.com/dialog/feed?' + urllib.urlencode({ | |
'app_id': settings.SOCIAL_AUTH_FACEBOOK_KEY, | |
'display': 'popup', | |
'caption': self.seller.store, | |
'image': self.image.name, | |
'title': self.text_to_share, | |
'description': 'Descúbrelo en #Prixealo - Compra y Vende Social', | |
'redirect_uri': self.get_detail_full_url, | |
'link': self.get_detail_full_url | |
}, doseq=True) | |
@property | |
def share_twitter(self): | |
return 'https://twitter.com/intent/tweet/?' + urllib.urlencode({ | |
'text': self.text_to_share, | |
'url': self.short_url() | |
}) | |
@property | |
def share_pinterest(self): | |
""" | |
{Título} en ${Precio}, {Estado}. Descúbrelo en #Prixealo | |
+ Link Detalle anuncio + Foto de anuncio | |
""" | |
return 'https://pinterest.com/pin/create/button/?' + urllib.urlencode({ | |
'url': self.get_detail_full_url, | |
'media': self.image.name, | |
'description': self.text_to_share | |
}) | |
@property | |
def share_googleplus(self): | |
""" | |
{Título} en ${Precio}, {Estado}. Descúbrelo en #Prixealo | |
""" | |
return 'https://plus.google.com/share?url=%s' % ( | |
self.get_detail_full_url) | |
""" | |
Email notifications | |
""" | |
def notify_user_deletion(self, msg): | |
EmailMandrill( | |
'gracias-por-registrarte', | |
'Gracias por registraste', | |
[self.seller.user.email, ] | |
) | |
def notify_ad_deletion(self, msg): | |
EmailMandrill( | |
'gracias-por-registrarte', | |
'Gracias por registraste', | |
[self.seller.user.email, ] | |
) | |
""" | |
Links of object | |
""" | |
@models.permalink | |
def get_absolute_url(self): | |
return ( | |
'stores:detail-ad', (), | |
{'store': self.seller.slug, 'pk': self.pk}) | |
@models.permalink | |
def get_edit_url(self): | |
return ('dashboard:edit-ad', (), {'pk': self.pk}) | |
@property | |
def get_detail_full_url(self): | |
from django.contrib.sites.models import Site | |
site = Site.objects.get(pk=1) | |
return u'http://%s%s' % (site.domain, self.get_absolute_url()) | |
def short_url(self): | |
from django_bitly.models import Bittle | |
bittle = Bittle.objects.bitlify(self) | |
return bittle.shortUrl | |
""" Receivers """ | |
@classmethod | |
def generate_sku(cls, sender, instance, using, **kwargs): | |
if instance.sku is None: | |
"""year.month.day.id[-6:] (si < 6 rellenar con 0)""" | |
ceros = 6 - len(str(instance.id)) | |
if ceros <= 0: | |
pk = str(instance.id)[-6:] | |
else: | |
pk = str(instance.id) | |
code = '%s%s' % ('0' * ceros, pk) | |
instance.sku = '%s%s' % (date.today().strftime("%y%m%d"), code) | |
instance.save() | |
@classmethod | |
def post_tweet(cls, sender, instance, using, **kwargs): | |
if kwargs.get('created'): | |
from publications.tasks import post_tweet | |
post_tweet.delay(instance) | |
""" Signals """ | |
signals.post_save.connect(Ad.generate_sku, sender=Ad) | |
signals.post_save.connect(Ad.post_tweet, sender=Ad) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment