140 lines
3.9 KiB
Python
140 lines
3.9 KiB
Python
import os
|
|
from lxml import etree
|
|
|
|
import lxml.html
|
|
import settings
|
|
from sync import create_post
|
|
from sync.core import Sync
|
|
from sync.models.product import create_product
|
|
from utils.fn import lmap, iterate_iter_over_fns, combine
|
|
from utils.hash import hash_file, hash_str
|
|
from utils.text.transform import url_encode_text
|
|
|
|
|
|
def create_url(a, i, s, e):
|
|
return 'https://static.shlisselburg.org/art/images/product-{album}-{id}-{size}{ext}'.format(
|
|
album=a,
|
|
id=i,
|
|
size=s,
|
|
ext=e
|
|
)
|
|
|
|
|
|
def url_creator(aid, pid):
|
|
return lambda size, ext: create_url(aid, pid, size, ext.lower())
|
|
|
|
|
|
class SyncAlbum(Sync):
|
|
@staticmethod
|
|
def id_from_file(i):
|
|
return url_encode_text(
|
|
os.path.splitext(i)[0]
|
|
)
|
|
|
|
def __init__(self, collection, provider, image_creator, images_dir):
|
|
super().__init__()
|
|
self.collection = collection
|
|
self.provider = provider
|
|
self.image_creator = image_creator
|
|
self.skip_image_processing = False
|
|
self.images_dir = images_dir
|
|
|
|
def create_id(self, document):
|
|
if 'id' in document:
|
|
return document
|
|
|
|
y = str(document['date'].year)
|
|
document['id'] = url_encode_text('-'.join([y, document['title']]))
|
|
return document
|
|
|
|
def create_hash(self, document):
|
|
files = sorted(document['images'])
|
|
hashes = lmap(
|
|
self.provider.hash,
|
|
lmap(
|
|
lambda i: os.path.join(document['folder'], i),
|
|
files
|
|
)
|
|
)
|
|
|
|
document['hash'] = hash_str(
|
|
combine([hash_str(document)] + hashes)
|
|
)
|
|
|
|
return document
|
|
|
|
def create_image(self, file, url_fn):
|
|
ss = settings.album_image_sizes
|
|
od = self.images_dir
|
|
sp = self.skip_image_processing
|
|
|
|
return self.image_creator.create_image(file, ss, url_fn, od, skip_processing=sp)
|
|
|
|
def create_album(self, doc):
|
|
# url_base = 'https://static.shburg.org/art/image/product-{album}-{id}-{size}{ext}'
|
|
|
|
image_id = SyncAlbum.id_from_file
|
|
image_path = lambda i: os.path.join(doc['folder'], i)
|
|
|
|
if 'title' not in doc or not doc['title']:
|
|
return None
|
|
|
|
create_album_id = lambda date, title: '{date}-{title}'.format(
|
|
date=date.strftime('%Y'),
|
|
title=url_encode_text(title)
|
|
)
|
|
|
|
doc['id'] = doc['id'] if 'id' in doc else create_album_id(doc['date'], doc['title'])
|
|
|
|
if 'album' in doc:
|
|
doc['album'] = self.create_products(doc, image_path)
|
|
|
|
def process_post_image(src):
|
|
path = image_path(src)
|
|
|
|
if self.provider.exists(path):
|
|
url = url_creator(
|
|
doc['id'],
|
|
image_id(src)
|
|
)
|
|
|
|
image = self.create_image(path, url)
|
|
if image:
|
|
images.append(image)
|
|
return image['data']['big']['url']
|
|
return None
|
|
|
|
images = []
|
|
post_html = create_post(doc['post'], process_post_image)
|
|
|
|
if 'preview' in doc:
|
|
preview = os.path.join(doc['folder'], doc['preview'])
|
|
doc['preview'] = self.create_image(preview, url_creator(
|
|
doc['id'],
|
|
image_id(doc['preview'])
|
|
))
|
|
|
|
doc['post'] = post_html
|
|
doc['images'] = images
|
|
return doc
|
|
|
|
def create_products(self, doc, image_file_fn):
|
|
image_id = SyncAlbum.id_from_file
|
|
iter_album = iterate_iter_over_fns([
|
|
lambda product: {
|
|
**product,
|
|
'image': self.create_image(
|
|
image_file_fn(product['file']),
|
|
url_creator(
|
|
doc['id'],
|
|
image_id(product['file'])
|
|
)
|
|
)
|
|
}
|
|
])
|
|
|
|
return lmap(
|
|
create_product,
|
|
iter_album(doc['album'])
|
|
)
|