def cuts(prefix): fname = os.path.join(prefix, 'cuts.json') if not os.path.exists(fname): return [] with open(fname) as f: cuts = json.load(f) return cuts
def get_data(isbn): data = {} ol = find(isbn) if ol['docs']: d = ol['docs'][0] data['title'] = d['title'] data['author'] = authors_ol(d['authors']) data['work'] = d['key'] data['edition'] = d['edition_key'][0] url = 'https://openlibrary.org/books/%s.json' % data['edition'] info = json.load(read_url(url)) data['pages'] = info['number_of_pages'] if 'dewey_decimal_class' in info: data['classification'] = info['dewey_decimal_class'][0] return data
def read_json(file, verbose=False): if verbose: print 'reading', file with open(file) as fd: data = json.load(fd) return data
def update_static(): oxjs_build = os.path.join(settings.STATIC_ROOT, 'oxjs/tools/build/build.py') if os.path.exists(oxjs_build): print 'update oxjs' if os.path.exists( os.path.join(settings.STATIC_ROOT, 'oxjs/build/Ox.Geo/json/Ox.Geo.json')): geo = '-nogeo' else: geo = '' os.system('%s %s >/dev/null' % (oxjs_build, geo)) data = '' js = [] pandora_js = os.path.join(settings.STATIC_ROOT, 'js/pandora.min.js') pandora_json = os.path.join(settings.STATIC_ROOT, 'json/pandora.json') for root, folders, files in os.walk( os.path.join(settings.STATIC_ROOT, 'js')): for f in files: if not f in ('pandora.js', 'pandora.min.js') and f.endswith('.js') and len( f.split('.')) == 2: f = os.path.join(root, f) #ignore old embed js file if 'js/embed/' in f: continue fsite = f.replace('.js', '.%s.js' % settings.CONFIG['site']['id']) if os.path.exists(fsite): f = fsite js.append(f[len(settings.STATIC_ROOT) + 1:]) with open(f) as j: data += j.read() + '\n' js += [ 'png/icon.png', ] print 'write', pandora_js with open(pandora_js, 'w') as f: data = ox.js.minify(data) f.write(data) print 'write', pandora_json with open(pandora_json, 'w') as f: json.dump(sorted(js), f, indent=2) for f in (pandora_js, pandora_json): os.system('gzip -9 -c "%s" > "%s.gz"' % (f, f)) for root, folders, files in os.walk( os.path.join(settings.STATIC_ROOT, 'oxjs/build')): for f in files: if os.path.splitext(f)[-1] in ('.js', '.json'): f = os.path.join(root, f) os.system('gzip -9 -c "%s" > "%s.gz"' % (f, f)) for name in ('logo', 'icon'): site = os.path.join( settings.STATIC_ROOT, 'png/%s.%s.png' % (name, settings.CONFIG['site']['id'])) pandora = os.path.join(settings.STATIC_ROOT, 'png/%s.pandora.png' % name) image = os.path.join(settings.STATIC_ROOT, 'png/%s.png' % name) if not os.path.exists(image): if os.path.exists(site): shutil.copyfile(site, image) else: shutil.copyfile(pandora, image) #locale for f in sorted( glob( os.path.join(settings.STATIC_ROOT, 'json/locale.pandora.*.json'))): with open(f) as fd: locale = json.load(fd) site_locale = f.replace('locale.pandora', 'locale.' + settings.CONFIG['site']['id']) locale_file = f.replace('locale.pandora', 'locale') print 'write', locale_file print ' adding', f if os.path.exists(site_locale): with open(site_locale) as fdl: print ' adding', site_locale locale.update(json.load(fdl)) with open(locale_file, 'w') as fd: json.dump(locale, fd) os.system('gzip -9 -c "%s" > "%s.gz"' % (locale_file, locale_file)) #download geo data update_geoip() #scripts for script in (settings.ITEM_POSTER, settings.ITEM_ICON, settings.LIST_ICON): if not os.path.exists(script): site_script = script.replace( '.py', '.%s.py' % settings.CONFIG['site']['id']) default_script = script.replace('.py', '.pandora.py') if os.path.exists(site_script): os.symlink(site_script, script) else: os.symlink(default_script, script)
def update_static(): oxjs_build = os.path.join(settings.STATIC_ROOT, 'oxjs/tools/build/build.py') if os.path.exists(oxjs_build): print 'update oxjs' if os.path.exists(os.path.join(settings.STATIC_ROOT, 'oxjs/build/Ox.Geo/json/Ox.Geo.json')): geo = '-nogeo' else: geo = '' os.system('%s %s >/dev/null' % (oxjs_build, geo)) data = '' js = [] pandora_js = os.path.join(settings.STATIC_ROOT, 'js/pandora.min.js') pandora_json = os.path.join(settings.STATIC_ROOT, 'json/pandora.json') for root, folders, files in os.walk(os.path.join(settings.STATIC_ROOT, 'js')): for f in files: if not f in ( 'pandora.js', 'pandora.min.js' ) and f.endswith('.js') and len(f.split('.')) == 2: f = os.path.join(root, f) #ignore old embed js file if 'js/embed/' in f: continue fsite = f.replace('.js', '.%s.js' % settings.CONFIG['site']['id']) if os.path.exists(fsite): f = fsite js.append(f[len(settings.STATIC_ROOT)+1:]) with open(f) as j: data += j.read() + '\n' js += [ 'png/icon.png', ] print 'write', pandora_js with open(pandora_js, 'w') as f: data = ox.js.minify(data) f.write(data) print 'write', pandora_json with open(pandora_json, 'w') as f: json.dump(sorted(js), f, indent=2) for f in (pandora_js, pandora_json): os.system('gzip -9 -c "%s" > "%s.gz"' % (f, f)) for root, folders, files in os.walk(os.path.join(settings.STATIC_ROOT, 'oxjs/build')): for f in files: if os.path.splitext(f)[-1] in ('.js', '.json'): f = os.path.join(root, f) os.system('gzip -9 -c "%s" > "%s.gz"' % (f, f)) for name in ('logo', 'icon'): site = os.path.join(settings.STATIC_ROOT, 'png/%s.%s.png'%(name, settings.CONFIG['site']['id'])) pandora = os.path.join(settings.STATIC_ROOT, 'png/%s.pandora.png'%name) image = os.path.join(settings.STATIC_ROOT, 'png/%s.png'%name) if not os.path.exists(image): if os.path.exists(site): shutil.copyfile(site, image) else: shutil.copyfile(pandora, image) #locale for f in sorted(glob(os.path.join(settings.STATIC_ROOT, 'json/locale.pandora.*.json'))): with open(f) as fd: locale = json.load(fd) site_locale = f.replace('locale.pandora', 'locale.' + settings.CONFIG['site']['id']) locale_file = f.replace('locale.pandora', 'locale') print 'write', locale_file print ' adding', f if os.path.exists(site_locale): with open(site_locale) as fdl: print ' adding', site_locale locale.update(json.load(fdl)) with open(locale_file, 'w') as fd: json.dump(locale, fd) os.system('gzip -9 -c "%s" > "%s.gz"' % (locale_file, locale_file)) #download geo data update_geoip() #scripts for script in (settings.ITEM_POSTER, settings.ITEM_ICON, settings.LIST_ICON): if not os.path.exists(script): site_script = script.replace('.py', '.%s.py' % settings.CONFIG['site']['id']) default_script = script.replace('.py', '.pandora.py') if os.path.exists(site_script): os.symlink(site_script, script) else: os.symlink(default_script, script)
def join_tiles(source_paths, target_path): ''' This is an implementation of a join_tiles function for new-style timelines. Timelines of files will be read from source_paths, the timeline of the item will be written to target_path. ''' def divide(num, by): # divide(100, 3) -> [33, 33, 34] arr = [] div = int(num / by) mod = num % by for i in range(int(by)): arr.append(div + (i > by - 1 - mod)) return arr def get_file_info(file_name): for mode in modes: if re.match('^timeline' + mode + '64p\d+\.jpg', file_name): return { 'file': file_name, 'mode': mode, 'index': int(file_name[11 + len(mode):-4]) } return None def save_and_open(data): # whenever a large tile is done or needed, # this function saves the previous large tile # (if any) and opens the next one (if any). # in between, whenever required, small tiles # are opened, rendered and saved, and the # large full tile is being generated. # 'keyframes' are only rendered in large size, # 'keyframeswide' only resized to small size. image_mode = 'L' if mode == 'audio' else 'RGB' small_mode = 'keyframes' if mode == 'keyframeswide' else mode large_tile_i = int(target_w / large_tile_w) # save previous large tile if large_tile_i > 0: large_tile_i -= 1 if mode != 'keyframeswide': image_file = '%stimeline%s%dp%d.jpg' % ( target_path, mode, large_tile_h, large_tile_i ) data['target_images']['large'].save(image_file) #print image_file if mode != 'keyframes': # open small tile small_tile_i = int(large_tile_i / 60) small_tile_x = (large_tile_i % 60) * 60 if small_tile_x == 0: if small_tile_i < small_tile_n - 1: w = small_tile_w else: w = small_tile_last_w data['target_images']['small'] = Image.new(image_mode, (w, small_tile_h)) # paste large tile into small tile w = 60 if large_tile_i < large_tile_n - 1 else small_tile_last_w % 60 data['target_images']['large'] = data['target_images']['large'].resize( (w, small_tile_h), Image.ANTIALIAS ) data['target_images']['small'].paste( data['target_images']['large'], (small_tile_x, 0) ) # save small tile if small_tile_x == small_tile_w - 60 or large_tile_i == large_tile_n - 1: image_file = '%stimeline%s%dp%d.jpg' % ( target_path, small_mode, small_tile_h, small_tile_i ) data['target_images']['small'].save(image_file) #print image_file if mode == 'antialias': # render full tile resized = data['target_images']['large'].resize(( data['full_tile_widths'][0], large_tile_h ), Image.ANTIALIAS) data['target_images']['full'].paste(resized, (data['full_tile_offset'], 0)) data['full_tile_offset'] += data['full_tile_widths'][0] data['full_tile_widths'] = data['full_tile_widths'][1:] large_tile_i += 1 # open next large tile if large_tile_i < large_tile_n: w = large_tile_w if large_tile_i < large_tile_n - 1 else large_tile_last_w data['target_images']['large'] = Image.new(image_mode, (w, large_tile_h)) data = {} fps = 25 large_tile_w, large_tile_h = 1500, 64 small_tile_w, small_tile_h = 3600, 16 full_tile_w = 1920 modes = ['antialias', 'slitscan', 'keyframes', 'keyframeswide', 'audio'] source_files = {} for mode in modes: source_files[mode] = [] # read files durations = [0] * len(source_paths) frame_n = 0 for i, path in enumerate(source_paths): file_info = map(get_file_info, os.listdir(path)) file_info = filter(lambda x: x != None, file_info) for info in sorted(file_info, key=lambda x: x['index']): mode = info['mode'] source_files[mode].append(path + info['file']) if mode == modes[0]: width = Image.open(source_files[mode][-1]).size[0] durations[i] += width / fps frame_n += width large_tile_n = int(math.ceil(frame_n / large_tile_w)) large_tile_last_w = frame_n % large_tile_w or 60 small_tile_n = int(math.ceil(frame_n / fps / small_tile_w)) small_tile_last_w = int(math.ceil(frame_n / fps)) % small_tile_w or small_tile_w # open full timeline if large_tile_n == 1: data['full_tile_widths'] = [large_tile_last_w] else: w = full_tile_w n = large_tile_n if large_tile_last_w < large_tile_w: factor = full_tile_w / frame_n last_w = int(round(large_tile_last_w * factor)) w -= last_w n -= 1 data['full_tile_widths'] = divide(w, n) if large_tile_last_w < large_tile_w: data['full_tile_widths'].append(last_w) data['full_tile_offset'] = 0 full_tile_image = Image.new('RGB', (full_tile_w, large_tile_h)) # main loop data['target_images'] = {'large': None, 'small': None, 'full': full_tile_image} for mode in modes: target_w = 0 for source_file in source_files[mode]: source_image = Image.open(source_file) source_w = source_image.size[0] target_x = target_w % large_tile_w if target_x == 0: save_and_open(data) data['target_images']['large'].paste(source_image, (target_x, 0)) target_w += source_w if target_x + source_w > large_tile_w: # target tile overflows into next source tile save_and_open(data) target_x -= large_tile_w data['target_images']['large'].paste(source_image, (target_x, 0)) # save_and_open saves previous tile and opens tile at target_w # increase target_w to be in next tile target_w += large_tile_w save_and_open(data) # save full timelines image_file = '%stimelineantialias%dp.jpg' % (target_path, large_tile_h) data['target_images']['full'].save(image_file) #print image_file image_file = '%stimelineantialias%dp.jpg' % (target_path, small_tile_h) data['target_images']['full'].resize( (full_tile_w, small_tile_h), Image.ANTIALIAS ).save(image_file) #print image_file # join cuts cuts = [] offset = 0 for i, path in enumerate(source_paths): p = os.path.join(path, 'cuts.json') if os.path.exists(p): with open(p, 'r') as f: path_cuts = json.load(f) else: print p, 'missing' path_cuts = [] if i > 0: cuts.append(offset) for cut in path_cuts: cuts.append(offset + cut) offset += durations[i] with open(os.path.join(target_path, 'cuts.json'), 'w') as f: # avoid float rounding artefacts f.write('[' + ', '.join(map(lambda x: '%.2f' % x, cuts)) + ']')