Files
hudozka/utils/Sync/read_gallery_1.py
T
2016-01-16 23:10:33 +03:00

163 lines
5.8 KiB
Python

import os
from datetime import datetime
import re
import lxml.html
from markdown import markdown
import time
import img
from Album import Album
import lxml_utils
import settings
from Product import Product
__author__ = 'Roman Timashev'
artist_name_exp = re.compile('([ %s]+)(\s\(\d+ лет\))?$' % (settings.CYR_LOWER + settings.CYR_UPPER))
# artist_name_exp = re.compile('(.+)(\s\(\d+ лет\))?$')
artist_age_exp = re.compile('.+\((\d+) лет\)$')
class GalleryReader:
def __init__(self, dir, path):
super().__init__()
self.html = None
self.description_path = path
self.dir_path = dir
self.image_sizes = settings.image_sizes
self.image_ext = settings.image_ext
self.image_base_url = settings.image_base_url
def read(self):
with open(self.description_path, 'r', encoding='utf-8') as dfile:
data = dfile.read()
md = markdown(data)
self.html = lxml.html.fromstring(md)
# ALBUM
try:
album_title = self.html.xpath('.//h1/a/text()')[0]
album_uri = self.html.xpath('.//h1/a/@href')[0]
except:
raise Exception('Cannot read album title/uri')
# COURSE
try:
course_title = self.html.xpath('.//p/a/text()')[0]
course_uri = self.html.xpath('.//p/a/@href')[0]
except:
raise Exception('Cannot read course title/uri')
# TEACHER
teacher = lxml_utils.get_text_following_by_tag(self.html, 'em', "Преподаватель")
teacher = re.sub(r'\s', '', teacher)
if teacher not in settings.teachers_names:
raise Exception('Teacher %s is not found' % teacher)
teacher_name = settings.teachers_names[teacher]
# DATE
date = self.get_date()
if date is None:
raise Exception('Date field is empty')
# PRODUCT
content = self.get_drawings()
a = Album(type='1', title=album_title, uri=album_uri, course=course_title, course_uri=course_uri, date=date,
teacher=teacher_name, comment=None)
for p in content:
author_name, author_age, filename, product_title = p
product = self.create_product(a, author_name, author_age, filename, product_title)
product.image_original_path = os.path.join(self.dir_path, filename)
a.add_product(product)
return a
def get_drawings(self):
drawings = []
h3_list = self.html.xpath('.//h3')
for h3 in h3_list:
artist_name_age = h3.xpath('./a')
if len(artist_name_age) == 0:
raise Exception('Artist name should be a link')
artist_name_age = artist_name_age[0].text
# ARTIST NAME [required]
if artist_name_age is None:
raise Exception('Artist name section is empty')
exp = artist_name_exp.search(artist_name_age)
if exp is None:
raise Exception('Artist name is not specified')
artist_name = exp.group(1).strip()
# ARTIST AGE [optional]
exp = artist_age_exp.search(artist_name_age)
if exp is not None and len(exp.groups()) > 0:
artist_age = int(exp.group(1))
else:
artist_age = None
image_filename = h3.xpath('./a/@href')[0]
# PRODUCT TITLE [optional]
drawing_data = lxml_utils.get_following_tags(h3, 'h3')
if len(drawing_data) == 0:
product_title = None
# raise Exception('Product title not specified')
else:
product_title = drawing_data[0].text[1:-1]
drawings.append((artist_name, artist_age, image_filename, product_title))
return drawings
def create_product(self, album, author_name, author_age, filename, product_title):
tr = {ord(a): ord(b) for a, b in zip(*settings.translit_table)}
author_name_encoded = re.sub(r'[\s()]', '', author_name).lower().translate(tr)
image_id = '%s-%s-%s-%s' % (
album.date.year,
re.sub(r'[/]', '', album.uri),
author_name_encoded,
os.path.splitext(filename)[0]
)
image = self.create_image(image_id, filename, self.image_sizes, self.image_ext, self.image_base_url)
return Product(author_name, author_age, image, product_title)
def create_image(self, name, filename, sizes, ext, base_url):
thumbs = {}
for size, width, height in sizes:
source_image = img.read_image(filename)
sw, sh = source_image.size
if sw < sh:
width, height = height, width
width = width if width else sw
height = height if height else sh
out_filename = '{name}-{w}x{h}{ext}'.format(name=name, w=width, h=height, ext=ext)
out_url = os.path.join(base_url, out_filename)
thumbs[size] = {
'url': out_url,
'size': size,
'width': width,
'height': height
}
return thumbs
def get_date(self):
string = lxml_utils.get_text_following_by_tag(self.html, 'em', "Дата")
if string is None:
return None
for f in settings.date_formats:
try:
date = time.strptime(string, f)
return datetime.fromtimestamp(time.mktime(date))
except ValueError:
continue
return None