2014-05-04 17:26:43 +00:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
# vi:si:et:sw=4:sts=4:ts=4
|
2014-05-17 22:18:32 +00:00
|
|
|
from __future__ import division
|
2014-05-04 17:26:43 +00:00
|
|
|
|
2014-05-18 23:24:04 +00:00
|
|
|
import os
|
2014-05-04 17:26:43 +00:00
|
|
|
import Image
|
|
|
|
from StringIO import StringIO
|
|
|
|
import re
|
|
|
|
import stdnum.isbn
|
2014-05-17 22:18:32 +00:00
|
|
|
import socket
|
2014-05-18 23:24:04 +00:00
|
|
|
import cStringIO
|
|
|
|
import gzip
|
2014-05-04 17:26:43 +00:00
|
|
|
|
|
|
|
import ox
|
2014-05-17 22:18:32 +00:00
|
|
|
import ed25519
|
2014-05-04 17:26:43 +00:00
|
|
|
|
2014-05-16 08:06:11 +00:00
|
|
|
from meta.utils import normalize_isbn, find_isbns
|
2014-05-14 09:57:11 +00:00
|
|
|
|
2014-05-18 23:24:04 +00:00
|
|
|
import logging
|
|
|
|
logger = logging.getLogger('oml.utils')
|
2014-05-17 22:18:32 +00:00
|
|
|
|
|
|
|
ENCODING='base64'
|
|
|
|
|
2014-05-04 17:26:43 +00:00
|
|
|
def valid_olid(id):
|
|
|
|
return id.startswith('OL') and id.endswith('M')
|
|
|
|
|
|
|
|
def get_positions(ids, pos):
|
|
|
|
'''
|
|
|
|
>>> get_positions([1,2,3,4], [2,4])
|
|
|
|
{2: 1, 4: 3}
|
|
|
|
'''
|
|
|
|
positions = {}
|
|
|
|
for i in pos:
|
|
|
|
try:
|
|
|
|
positions[i] = ids.index(i)
|
|
|
|
except:
|
|
|
|
pass
|
|
|
|
return positions
|
|
|
|
|
|
|
|
def get_by_key(objects, key, value):
|
|
|
|
obj = filter(lambda o: o.get(key) == value, objects)
|
|
|
|
return obj and obj[0] or None
|
|
|
|
|
|
|
|
def get_by_id(objects, id):
|
|
|
|
return get_by_key(objects, 'id', id)
|
|
|
|
|
|
|
|
def resize_image(data, width=None, size=None):
|
2014-05-19 21:15:37 +00:00
|
|
|
source = Image.open(StringIO(data))
|
|
|
|
if source.mode == 'P':
|
|
|
|
source = source.convert('RGB')
|
2014-05-04 17:26:43 +00:00
|
|
|
source_width = source.size[0]
|
|
|
|
source_height = source.size[1]
|
|
|
|
if size:
|
|
|
|
if source_width > source_height:
|
|
|
|
width = size
|
|
|
|
height = int(width / (float(source_width) / source_height))
|
|
|
|
height = height - height % 2
|
|
|
|
else:
|
|
|
|
height = size
|
|
|
|
width = int(height * (float(source_width) / source_height))
|
|
|
|
width = width - width % 2
|
|
|
|
|
|
|
|
else:
|
|
|
|
height = int(width / (float(source_width) / source_height))
|
|
|
|
height = height - height % 2
|
|
|
|
|
|
|
|
width = max(width, 1)
|
|
|
|
height = max(height, 1)
|
|
|
|
|
|
|
|
if width < source_width:
|
|
|
|
resize_method = Image.ANTIALIAS
|
|
|
|
else:
|
|
|
|
resize_method = Image.BICUBIC
|
|
|
|
output = source.resize((width, height), resize_method)
|
|
|
|
o = StringIO()
|
|
|
|
output.save(o, format='jpeg')
|
|
|
|
data = o.getvalue()
|
|
|
|
o.close()
|
|
|
|
return data
|
|
|
|
|
|
|
|
def sort_title(title):
|
|
|
|
|
|
|
|
title = title.replace(u'Æ', 'Ae')
|
|
|
|
if isinstance(title, str):
|
|
|
|
title = unicode(title)
|
|
|
|
title = ox.sort_string(title)
|
|
|
|
|
|
|
|
#title
|
|
|
|
title = re.sub(u'[\'!¿¡,\.;\-"\:\*\[\]]', '', title)
|
|
|
|
return title.strip()
|
|
|
|
|
|
|
|
def get_position_by_id(list, key):
|
|
|
|
for i in range(0, len(list)):
|
|
|
|
if list[i]['id'] == key:
|
|
|
|
return i
|
|
|
|
return -1
|
|
|
|
|
2014-05-17 22:18:32 +00:00
|
|
|
def valid(key, value, sig):
|
|
|
|
'''
|
|
|
|
validate that value was signed by key
|
|
|
|
'''
|
|
|
|
vk = ed25519.VerifyingKey(str(key), encoding=ENCODING)
|
|
|
|
try:
|
|
|
|
vk.verify(str(sig), str(value), encoding=ENCODING)
|
|
|
|
#except ed25519.BadSignatureError:
|
|
|
|
except:
|
|
|
|
return False
|
|
|
|
return True
|
|
|
|
|
|
|
|
def get_public_ipv6():
|
2014-05-19 18:12:02 +00:00
|
|
|
try:
|
|
|
|
host = ('2a01:4f8:120:3201::3', 25519)
|
|
|
|
s = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
|
|
|
|
s.settimeout(1)
|
|
|
|
s.connect(host)
|
|
|
|
ip = s.getsockname()[0]
|
|
|
|
s.close()
|
|
|
|
except:
|
|
|
|
ip = None
|
2014-05-17 22:18:32 +00:00
|
|
|
return ip
|
|
|
|
|
2014-05-18 23:24:04 +00:00
|
|
|
def update_dict(root, data):
|
|
|
|
for key in data:
|
|
|
|
keys = map(lambda part: part.replace('\0', '\\.'), key.replace('\\.', '\0').split('.'))
|
|
|
|
value = data[key]
|
|
|
|
p = root
|
|
|
|
while len(keys)>1:
|
|
|
|
key = keys.pop(0)
|
|
|
|
if isinstance(p, list):
|
|
|
|
p = p[get_position_by_id(p, key)]
|
|
|
|
else:
|
|
|
|
if key not in p:
|
|
|
|
p[key] = {}
|
|
|
|
p = p[key]
|
|
|
|
if value == None and keys[0] in p:
|
|
|
|
del p[keys[0]]
|
|
|
|
else:
|
|
|
|
p[keys[0]] = value
|
|
|
|
|
|
|
|
def remove_empty_folders(prefix):
|
|
|
|
empty = []
|
|
|
|
for root, folders, files in os.walk(prefix):
|
|
|
|
if not folders and not files:
|
|
|
|
empty.append(root)
|
|
|
|
for folder in empty:
|
|
|
|
remove_empty_tree(folder)
|
|
|
|
|
|
|
|
def remove_empty_tree(leaf):
|
|
|
|
while leaf:
|
|
|
|
if not os.path.exists(leaf):
|
|
|
|
leaf = os.path.dirname(leaf)
|
|
|
|
elif os.path.isdir(leaf) and not os.listdir(leaf):
|
|
|
|
logger.debug('rmdir %s', leaf)
|
|
|
|
os.rmdir(leaf)
|
|
|
|
else:
|
|
|
|
break
|