181 lines
5.5 KiB
Python
181 lines
5.5 KiB
Python
import datetime
|
|
import json
|
|
import logging
|
|
import os.path
|
|
import re
|
|
|
|
from django.conf import settings
|
|
from django.contrib.postgres.fields import JSONField
|
|
from django.db import models
|
|
|
|
from products.models import Product
|
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
|
|
class Season(models.Model):
|
|
id = models.CharField(max_length=30, primary_key=True)
|
|
name = models.CharField(max_length=100)
|
|
ordering = models.PositiveIntegerField(unique=True, default=1000)
|
|
|
|
def serialize(self):
|
|
return {
|
|
'id': self.id,
|
|
'name': self.name,
|
|
'ordering': self.ordering,
|
|
}
|
|
|
|
|
|
class Region(models.Model):
|
|
id = models.CharField(max_length=30, primary_key=True)
|
|
name = models.CharField(max_length=100)
|
|
ordering = models.PositiveIntegerField(unique=True, default=1000)
|
|
|
|
def serialize(self):
|
|
return {
|
|
'id': self.id,
|
|
'name': self.name,
|
|
'ordering': self.ordering,
|
|
}
|
|
|
|
|
|
def pretty_datetime(date):
|
|
# Oct 16 2018 10:58 am
|
|
return "{:%b %-d %Y, %-I:%M %p}".format(date)
|
|
|
|
|
|
def unix_datetime(date):
|
|
return date.timestamp()
|
|
|
|
|
|
class Catalog(models.Model):
|
|
PDF_DIR = 'catalogs'
|
|
PDF_URL = 'export/catalogs'
|
|
owner = models.ForeignKey(settings.AUTH_USER_MODEL,
|
|
on_delete=models.CASCADE)
|
|
season = models.ForeignKey(Season, on_delete=models.PROTECT)
|
|
region = models.ForeignKey(Region, on_delete=models.PROTECT)
|
|
created = models.DateTimeField(auto_now_add=True)
|
|
updated = models.DateTimeField(auto_now=True, db_index=True)
|
|
name = models.CharField(max_length=300)
|
|
public = models.BooleanField(default=False, db_index=True)
|
|
pages = models.PositiveIntegerField(default=0)
|
|
sections = models.PositiveIntegerField(default=0)
|
|
materials = models.PositiveIntegerField(default=0)
|
|
data = JSONField(null=True)
|
|
master = models.BooleanField(default=False)
|
|
show_prices = models.BooleanField(default=False)
|
|
build_progress = models.PositiveIntegerField(default=0)
|
|
|
|
# JSONField docs:
|
|
# https://docs.djangoproject.com/en/2.2/ref/contrib/postgres/fields/#jsonfield
|
|
|
|
|
|
def pdf_name(self):
|
|
pdf = "{}-{}-{}".format(self.season.id, self.name, self.id)
|
|
pdf = re.sub(r'\s+', r'_', pdf)
|
|
pdf = re.sub(r'[^\w\-]', r'', pdf)
|
|
pdf += '.pdf'
|
|
return pdf
|
|
|
|
|
|
def pdf_url(self):
|
|
return "http://{}/{}/{}/{}".format(settings.PUBLIC_WEB_HOST,
|
|
self.PDF_URL,
|
|
self.season.id,
|
|
self.pdf_name())
|
|
|
|
|
|
def pdf_file(self):
|
|
return os.path.join(settings.ASSET_DIR,
|
|
self.PDF_DIR,
|
|
self.season.id,
|
|
self.pdf_name())
|
|
|
|
|
|
def pdf_exists(self):
|
|
return os.path.isfile(self.pdf_file())
|
|
|
|
|
|
def summary(self):
|
|
return {
|
|
'id': self.id,
|
|
'seasonCode': self.season.id,
|
|
'regionCode': self.region.id,
|
|
'name': self.name,
|
|
'ownerName': self.owner.get_full_name(),
|
|
'public': self.public,
|
|
'updated': unix_datetime(self.updated),
|
|
'updatedPretty': pretty_datetime(self.updated),
|
|
'created': unix_datetime(self.created),
|
|
'createdPretty': pretty_datetime(self.created),
|
|
'pages': self.pages,
|
|
'sections': self.sections,
|
|
'materials': self.materials,
|
|
'master': self.master,
|
|
'show_prices': self.show_prices,
|
|
'build_progress': self.build_progress,
|
|
'pdf': self.pdf_url(),
|
|
}
|
|
|
|
|
|
def update_metadata(self):
|
|
"""Update meta properties from what's in 'data'"""
|
|
if not self.data or len(self.data) < 1:
|
|
log.warning('no data in update_metadata()')
|
|
return
|
|
|
|
data = self.data
|
|
|
|
self.name = data.get('name', '(No name)')
|
|
|
|
self.season = Season.objects.get(id=data.get('season'))
|
|
self.region = Region.objects.get(id=data.get('region'))
|
|
|
|
self.public = data.get('public', False)
|
|
self.master = data.get('master', False)
|
|
self.show_prices = data.get('show_prices', False)
|
|
|
|
# NOTE 'is_utility' in the json data is not exposed to the
|
|
# django model or placed in a separate postgres column.
|
|
|
|
# reset until pdf is made
|
|
self.build_progress = 0
|
|
|
|
# calculate some properties
|
|
sections = 0
|
|
pages = 0
|
|
materials = 0
|
|
for section in data.get('sections', []):
|
|
sections += 1
|
|
for page in section.get('pages', []):
|
|
pages += 1
|
|
for block in page:
|
|
materials += len(block.get('ids', []))
|
|
|
|
self.sections = sections
|
|
self.pages = pages
|
|
self.materials = materials
|
|
|
|
|
|
def products(self):
|
|
"""Return an unordered list of all products in the catalog."""
|
|
ids = self.product_ids()
|
|
log.info("ids: %s", ids)
|
|
# TODO filter on catalog region and season when we
|
|
# have that data
|
|
return Product.objects.filter(sap__in=ids).distinct('sap')
|
|
|
|
|
|
def product_ids(self):
|
|
"""Return an unordered list of all product ids in the catalog."""
|
|
materials = set()
|
|
|
|
if self.data and len(self.data) > 0:
|
|
for section in self.data.get('sections', []):
|
|
for page in section.get('pages', []):
|
|
for block in page:
|
|
materials = materials.union(set(block.get('ids', [])))
|
|
|
|
return materials
|