zi
3 years ago
commit
f3c53283f8
9 changed files with 725 additions and 0 deletions
@ -0,0 +1,383 @@ |
|||
<!doctype html> |
|||
<html> |
|||
<head> |
|||
<link href="../icon.png" rel="shortcut icon"/> |
|||
<meta charset="utf-8"/> |
|||
<style> |
|||
a { |
|||
color: rgb(224,220,220); |
|||
text-decoration: none; |
|||
} |
|||
a:hover { |
|||
text-decoration: underline; |
|||
} |
|||
body { |
|||
font-family: Arial, Helvetica, sans-serif; |
|||
font-size: 18px; |
|||
letter-spacing: 2px; |
|||
line-height: 12px; |
|||
text-transform: uppercase; |
|||
} |
|||
div#bottom { |
|||
background-color: rgba(198, 192, 192, 0.6); |
|||
bottom: 0; |
|||
color: black; |
|||
height: auto; |
|||
left: 0; |
|||
line-height: 18px; |
|||
padding: 8px 32px; |
|||
position: absolute; |
|||
right: 0; |
|||
text-align: center; |
|||
text-transform: none; } |
|||
div#main { |
|||
/* background-color: rgb(112, 107, 107); */ |
|||
background-color: rgb(0, 0, 0); |
|||
background-position: 0 0, 16px 16px; |
|||
background-size: 32px 32px; |
|||
bottom: 0; |
|||
left: 0; |
|||
position: fixed; |
|||
right: 0; |
|||
top: calc(60px - 1vw); |
|||
} |
|||
div#top_center { |
|||
background-color: rgb(104, 100, 100); |
|||
color: rgb(224,220,220); |
|||
height: calc(60px - 1vw); |
|||
left: 25%; |
|||
font-size: calc(36px - 1vw); |
|||
line-height: 32px; |
|||
padding: 8px 32px; |
|||
position: absolute; |
|||
text-align: center; |
|||
top: 0; |
|||
right: 25%; |
|||
} |
|||
div#top_left { |
|||
background-color: rgb(104, 100, 100); |
|||
color: rgb(224,220,220); |
|||
height: calc(60px - 1vw); |
|||
left: 0; |
|||
line-height: 32px; |
|||
padding: 8px 32px; |
|||
position: absolute; |
|||
text-align: left; |
|||
top: 0; |
|||
width: 25%; |
|||
} |
|||
div#top_right { |
|||
background-color: rgb(104, 100, 100); |
|||
color: rgb(224,220,220); |
|||
height: calc(60px - 1vw); |
|||
line-height: 32px; |
|||
padding: 8px 32px; |
|||
position: absolute; |
|||
top: 0; |
|||
right: 0; |
|||
text-align: right; |
|||
width: 25%; |
|||
} |
|||
|
|||
span { |
|||
cursor: pointer; |
|||
} |
|||
span:hover { |
|||
text-decoration: underline; |
|||
} |
|||
|
|||
span:active { |
|||
color: rgb(178, 56, 50); |
|||
} |
|||
|
|||
span.disabled { |
|||
cursor: default; |
|||
text-decoration: underline; |
|||
} |
|||
</style> |
|||
</head> |
|||
<body> |
|||
<div id="top_left"> |
|||
<span id="back">back</span> |
|||
</div> |
|||
<div id="top_center"> |
|||
<span id="previous">previous</span> | <span id="play">play</span> | <span id="next">next</span> |
|||
</div> |
|||
<div id="top_right"> |
|||
<span id="small">1080p</span> | <span id="large">original</span> |
|||
</div> |
|||
<div id="main"></div> |
|||
<div id="bottom">loading...</div> |
|||
</body> |
|||
<script type="text/javascript" src="../js/jquery-3.3.1.min.js"></script> |
|||
<script type="text/javascript" src="../js/hammer.min.js"></script> |
|||
|
|||
<script> |
|||
var path |
|||
var current, previous, next |
|||
var img |
|||
var imageWidth, imageHeight, imageRatio |
|||
var timeout |
|||
var back = document.getElementById('back') |
|||
var previous = document.getElementById('previous') |
|||
var playPause = document.getElementById('play') |
|||
var next = document.getElementById('next') |
|||
var small = document.getElementById('small') |
|||
var large = document.getElementById('large') |
|||
var main = document.getElementById('main') |
|||
var bottom = document.getElementById('bottom') |
|||
var elements = { |
|||
27: back, |
|||
32: playPause, |
|||
37: previous, |
|||
39: next, |
|||
187: large, |
|||
189: small |
|||
} |
|||
var captions |
|||
$.getJSON("../js/captions.json", function(data) { |
|||
captions = data; |
|||
}) |
|||
var hammertime = new Hammer(main) |
|||
hammertime.get('swipe').set({velocity: 3.0}) |
|||
function hammerIt(elm) { |
|||
hammertime = new Hammer(elm, {}); |
|||
hammertime.get('pinch').set({ |
|||
enable: true |
|||
}); |
|||
var posX = 0, |
|||
posY = 0, |
|||
scale = 1, |
|||
last_scale = 1, |
|||
last_posX = 0, |
|||
last_posY = 0, |
|||
max_pos_x = 0, |
|||
max_pos_y = 0, |
|||
transform = "", |
|||
el = elm; |
|||
|
|||
hammertime.on('pan pinch panend pinchend', function(ev) { |
|||
|
|||
//pan |
|||
if (scale != 1) { |
|||
posX = last_posX + ev.deltaX; |
|||
posY = last_posY + ev.deltaY; |
|||
max_pos_x = Math.ceil((scale - 1) * el.clientWidth / 2); |
|||
max_pos_y = Math.ceil((scale - 1) * el.clientHeight / 2); |
|||
if (posX > max_pos_x) { |
|||
posX = max_pos_x; |
|||
} |
|||
if (posX < -max_pos_x) { |
|||
posX = -max_pos_x; |
|||
} |
|||
if (posY > max_pos_y) { |
|||
posY = max_pos_y; |
|||
} |
|||
if (posY < -max_pos_y) { |
|||
posY = -max_pos_y; |
|||
} |
|||
} |
|||
|
|||
|
|||
//pinch |
|||
if (ev.type == "pinch") { |
|||
scale = Math.max(.999, Math.min(last_scale * (ev.scale), 4)); |
|||
} |
|||
if(ev.type == "pinchend"){last_scale = scale;} |
|||
|
|||
//panend |
|||
if(ev.type == "panend"){ |
|||
last_posX = posX < max_pos_x ? posX : max_pos_x; |
|||
last_posY = posY < max_pos_y ? posY : max_pos_y; |
|||
} |
|||
|
|||
if (scale != 1) { |
|||
transform = |
|||
"translate3d(" + posX + "px," + posY + "px, 0) " + |
|||
"scale3d(" + scale + ", " + scale + ", 1)"; |
|||
} |
|||
|
|||
if (transform) { |
|||
el.style.webkitTransform = transform; |
|||
} |
|||
}); |
|||
} |
|||
|
|||
|
|||
function get(url, callback) { |
|||
var request = new XMLHttpRequest() |
|||
request.open('GET', url, true) |
|||
request.onreadystatechange = function() { |
|||
if (request.readyState == 4) { |
|||
if (request.status == 200) { |
|||
callback(request.responseText, null) |
|||
} else { |
|||
callback(null, { |
|||
code: request.status, |
|||
text: request.statusText |
|||
}) |
|||
} |
|||
} |
|||
}; |
|||
request.send() |
|||
} |
|||
function loadImage() { |
|||
if (!['small', 'large'].includes(localStorage['pix.size'])) { |
|||
localStorage['pix.size'] = 'small' |
|||
} |
|||
small.className = localStorage['pix.size'] == 'small' |
|||
? 'disabled' : '' |
|||
large.className = localStorage['pix.size'] == 'large' |
|||
? 'disabled' : '' |
|||
bottom.style.display = 'block' |
|||
img = document.createElement('img') |
|||
img.style.position = 'absolute' |
|||
img.onload = function() { |
|||
imageWidth = img.width |
|||
imageHeight = img.height |
|||
imageRatio = imageWidth / imageHeight |
|||
onResize() |
|||
document.title = path.split('/').pop().toUpperCase() |
|||
// uncomment below for no captions |
|||
// bottom.style.display = 'none' |
|||
main.innerHTML = '' |
|||
main.appendChild(img) |
|||
//var img_alt = captions[current.split('/').pop()] |
|||
var img_alt = captions[current.split('/').slice(-2).join('/')] |
|||
if (img_alt != "") { |
|||
img.setAttribute('alt', img_alt) |
|||
bottom.innerHTML = img_alt |
|||
} else { |
|||
bottom.style.display = 'none' |
|||
} |
|||
} |
|||
img.setAttribute('src', '../' + ( |
|||
localStorage['pix.size'] == 'small' |
|||
? current.replace('/', '/1080/') : current |
|||
)) |
|||
hammerIt(img) |
|||
} |
|||
function mod(a, b) { |
|||
return (a % b + b) % b |
|||
} |
|||
function onHashchange() { |
|||
bottom.innerHTML = 'loading...' |
|||
current = null |
|||
previous = null |
|||
next = null |
|||
var hash = document.location.hash.slice(1) |
|||
if (!hash) return |
|||
var parts = hash.split('/') |
|||
var name = parts.pop().replace(/%20/g, ' ') |
|||
path = parts.join('/') |
|||
get('../' + path + '/index.html', function(html, error) { |
|||
if (error) return |
|||
var matches = html.match(/src="(.*?)"/g).map(function(match) { |
|||
return match.slice(5, -1).replace(/^256\//g, '') |
|||
}) |
|||
var index = matches.indexOf(name) |
|||
if (index == -1) return |
|||
current = path + '/' + name |
|||
previous = path + '/' + matches[mod(index - 1, matches.length)] |
|||
next = path + '/' + matches[mod(index + 1, matches.length)] |
|||
loadImage() |
|||
}) |
|||
} |
|||
function onKeydown(e) { |
|||
elements[e.keyCode] && elements[e.keyCode].onclick() |
|||
} |
|||
function onResize() { |
|||
var screenWidth = window.innerWidth |
|||
var screenHeight = window.innerHeight - 32 |
|||
var screenRatio = screenWidth / screenHeight |
|||
var isSmaller = imageWidth < screenWidth |
|||
&& imageHeight < screenHeight |
|||
var isWider = imageRatio > screenRatio |
|||
img.style.width = ( |
|||
isSmaller ? imageWidth |
|||
: isWider ? screenWidth |
|||
: screenHeight * imageRatio |
|||
) + 'px' |
|||
img.style.height = ( |
|||
isSmaller ? imageHeight |
|||
: isWider ? screenWidth / imageRatio |
|||
: screenHeight |
|||
) + 'px' |
|||
img.style.left = ( |
|||
isSmaller ? (screenWidth - imageWidth) / 2 |
|||
: isWider ? 0 |
|||
: (screenWidth - screenHeight * imageRatio) / 2 |
|||
) + 'px' |
|||
img.style.top = ( |
|||
isSmaller ? (screenHeight - imageHeight) / 2 |
|||
: isWider ? (screenHeight - screenWidth / imageRatio) / 2 |
|||
: 0 |
|||
) + 'px' |
|||
} |
|||
function pause() { |
|||
timeout && clearTimeout(timeout) |
|||
timeout = null |
|||
} |
|||
function play() { |
|||
pause() |
|||
timeout = setTimeout(playing, 5000) |
|||
function playing() { |
|||
document.location.hash = next.replace(/ /g, '%20') |
|||
timeout = setTimeout(playing, 5000) |
|||
} |
|||
} |
|||
back.onclick = function() { |
|||
document.location = '../' + path |
|||
} |
|||
previous.onclick = function() { |
|||
document.location.hash = previous.replace(/ /g, '%20') |
|||
timeout && play() |
|||
} |
|||
playPause.onclick = function() { |
|||
if (playPause.innerHTML == 'play') { |
|||
playPause.innerHTML = 'pause' |
|||
play() |
|||
} else { |
|||
playPause.innerHTML = 'play' |
|||
pause() |
|||
} |
|||
} |
|||
next.onclick = function() { |
|||
document.location.hash = next.replace(/ /g, '%20') |
|||
timeout && play() |
|||
} |
|||
small.onclick = function() { |
|||
localStorage['pix.size'] = 'small' |
|||
loadImage() |
|||
} |
|||
large.onclick = function() { |
|||
localStorage['pix.size'] = 'large' |
|||
loadImage() |
|||
} |
|||
hammertime.on("swiperight", function(ev) { |
|||
document.location.hash = previous.replace(/ /g, '%20') |
|||
timeout && play() |
|||
}) |
|||
hammertime.on("swipeleft", function(ev) { |
|||
document.location.hash = next.replace(/ /g, '%20') |
|||
timeout && play() |
|||
}) |
|||
hammertime.on("tap", function(ev) { |
|||
var screenWidth = window.innerWidth |
|||
var clickX = ev.center.x |
|||
console.log(screenWidth) |
|||
if (clickX > screenWidth/2) { |
|||
document.location.hash = next.replace(/ /g, '%20') |
|||
timeout && play() |
|||
} else { |
|||
document.location.hash = previous.replace(/ /g, '%20') |
|||
timeout && play() |
|||
} |
|||
}) |
|||
|
|||
window.onhashchange = onHashchange |
|||
window.onkeydown = onKeydown |
|||
window.onresize = onResize |
|||
onHashchange() |
|||
</script> |
|||
</html> |
@ -0,0 +1,30 @@ |
|||
Some changes to a minimal photo gallery (pix) |
|||
* works with jpg (ignores png/other) |
|||
|
|||
+ tap for previous/next |
|||
+ photos can have user defined captions |
|||
+ album titles |
|||
|
|||
_____ |
|||
Create folders ("albums") here, copy images into these folders. |
|||
|
|||
To generate images (1080, 256), create HTML, run |
|||
python3 pix.py |
|||
|
|||
pix.py to be run again if edit album.html and index.html, change the CSS, enable/disable captions, etc. or if photos are added/delete/renamed. |
|||
____ |
|||
Captions -> to create json template using album and file names, run |
|||
python3 write_captionsJSON.py |
|||
|
|||
-> generates captions.json in js folder {album/image.ext: "enter-caption-here", ...} |
|||
-> open captions.json in txt editor to edit / enter captions |
|||
* write_CaptionsJSON.py can be run again in case files are added/deleted |
|||
____ |
|||
The image viewer supports the following keyboard shortcuts: |
|||
|
|||
Escape Back |
|||
Left Previous |
|||
Space Play/Pause |
|||
Right Next |
|||
Minus 1080p |
|||
Plus Original |
@ -0,0 +1,97 @@ |
|||
<!doctype html> |
|||
<html> |
|||
<head> |
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|||
<title>{title}</title> |
|||
<link href="../icon.png" rel="shortcut icon"/> |
|||
<meta charset="utf-8"/> |
|||
<style> |
|||
a { |
|||
color: rgb(128, 128, 128); |
|||
text-decoration: none; |
|||
} |
|||
a:hover { |
|||
text-decoration: underline; |
|||
} |
|||
body { |
|||
background-color: rgb(192, 192, 192); |
|||
color: white; |
|||
font-family: Arial, Helvetica, sans-serif; |
|||
font-size: 18px; |
|||
letter-spacing: 1.5px; |
|||
line-height: 18px; |
|||
text-transform: capitalize; |
|||
} |
|||
div#main { |
|||
background-color: rgb(162, 155, 152); |
|||
background-position: 0 0, 16px 16px; |
|||
background-size: 32px 32px; |
|||
bottom: 0; |
|||
left: 0; |
|||
overflow-y: auto; |
|||
padding: 16px; |
|||
position: absolute; |
|||
right: 0; |
|||
top: 96px; |
|||
} |
|||
div#main > div { |
|||
display: inline-block; |
|||
height: 128px; |
|||
margin: 4px; |
|||
overflow: hidden; |
|||
text-align: center; |
|||
width: 128px; |
|||
} |
|||
div#main > div:after { |
|||
content: ""; |
|||
display: inline-block; |
|||
vertical-align: middle; |
|||
height: 100%; |
|||
} |
|||
div#top { |
|||
background-color: rgb(104, 100, 100); |
|||
color: #cc4039; |
|||
height: 32px; |
|||
left: 0; |
|||
line-height: 32px; |
|||
padding: 8px 16px; |
|||
position: absolute; |
|||
right: 0; |
|||
top: 0; |
|||
} |
|||
div#top > a { |
|||
color: rgb(224,220,220); |
|||
} |
|||
div#top_title { |
|||
background-color: rgba(153, 147, 144, 1); |
|||
color: black; |
|||
height: 32px; |
|||
left: 0; |
|||
line-height: 32px; |
|||
padding: 8px 32px; |
|||
position: absolute; |
|||
right: 0; |
|||
top: 48px; |
|||
} |
|||
img.landscape { |
|||
height: 128px; |
|||
margin-left: -32px; |
|||
} |
|||
img.portrait { |
|||
width: 128px; |
|||
} |
|||
</style> |
|||
</head> |
|||
<body> |
|||
<div id="top"> |
|||
<a href="../"><< all images</a> |
|||
</div> |
|||
<div id="top_title"> |
|||
{title} |
|||
</div> |
|||
<div id="main"> |
|||
<!--# You can edit this file, but only above this line. #--> |
|||
<!--# You can edit this file, but only below this line. #--> |
|||
</div> |
|||
</body> |
|||
</html> |
After Width: | Height: | Size: 3.3 KiB |
@ -0,0 +1,72 @@ |
|||
<!doctype html> |
|||
<html> |
|||
<head> |
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|||
<title>Albums</title> |
|||
<link href="pix.png" rel="shortcut icon"/> |
|||
<meta charset="utf-8"> |
|||
<style> |
|||
a { |
|||
/* color: rgb(128, 128, 128); */ |
|||
color: rgb(196, 65, 50); |
|||
text-decoration: none; |
|||
} |
|||
a:hover { |
|||
text-decoration: underline; |
|||
} |
|||
body { |
|||
background-color: rgb(215, 214, 214); |
|||
color: black; |
|||
font-family: Arial, Helvetica, sans-serif; |
|||
font-size: 18px; |
|||
letter-spacing: 2px; |
|||
line-height: 18px; |
|||
/* text-transform: uppercase; */ |
|||
} |
|||
div#main { |
|||
background-color: rgb(215, 214, 214); |
|||
bottom: 0; |
|||
left: 0; |
|||
position: absolute; |
|||
right: 0; |
|||
top: 48px; |
|||
background-position: 0 0, 16px 16px; |
|||
background-size: 32px 32px; |
|||
} |
|||
div#top { |
|||
background-color: rgb(210, 207, 207); |
|||
color: #b23832; |
|||
height: 32px; |
|||
left: 0; |
|||
line-height: 32px; |
|||
padding: 8px 32px; |
|||
position: absolute; |
|||
right: 0; |
|||
top: 0; |
|||
} |
|||
div#top > a { |
|||
color: #b23832; |
|||
} |
|||
li { |
|||
color: rgb(192, 192, 192); |
|||
margin-bottom: 12px; |
|||
} |
|||
ul { |
|||
list-style-type: none; |
|||
margin: 32px; |
|||
padding: 0; |
|||
text-align: left; |
|||
} |
|||
|
|||
</style> |
|||
</head> |
|||
<body> |
|||
<div id="top"> |
|||
<a href="../../"><< back</a> |
|||
</div> |
|||
<div id="main"> |
|||
<!--# You can edit this file, but only above this line. #--> |
|||
<!--# You can edit this file, but only below this line. #--> |
|||
</div> |
|||
</body> |
|||
</html> |
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1,104 @@ |
|||
import codecs |
|||
import os |
|||
import re |
|||
from PIL import Image, ExifTags |
|||
''' |
|||
# You can edit the following line with login details |
|||
#REMOTE_PATH = 'user@server:path-to-galleryAlbums/' |
|||
if not REMOTE_PATH.endswith('/'): |
|||
REMOTE_PATH += '/' |
|||
''' |
|||
# Size of thumbnails |
|||
SIZE_THUMBNAIL = 256 |
|||
# Size of low-resolution images |
|||
SIZE_SMALL = 1080 |
|||
|
|||
def create_directory(path): |
|||
dirname = os.path.dirname(path) |
|||
if not os.path.exists(dirname): |
|||
os.mkdir(dirname) |
|||
|
|||
def write_html(source, target, html, title=''): |
|||
with codecs.open(source, 'r', encoding='utf-8') as f: |
|||
html_original = f.read() |
|||
html_original = re.sub('\{title\}', title.title(), html_original) |
|||
indent = html_original.split('<!--#')[0].split('\n')[-1] |
|||
html = re.sub('\n', '\n{}'.format(indent), '\n{}\n'.format(html)) |
|||
with codecs.open(target, 'w', encoding='utf-8') as f: |
|||
f.write(re.sub( |
|||
'(?<=#-->).*?(?=<!--#)', html, html_original, flags=re.DOTALL |
|||
)) |
|||
|
|||
html_index = '<ul>' |
|||
# For each album |
|||
for path in [f for f in sorted(os.listdir('./')) if os.path.isdir(f) and f != '!' and f.lower() != 'videos' and f.lower() != 'js']: |
|||
html_index += ('\n <li><a href="{0}">{0}</a></li>'.format(path)) |
|||
html_album = '' |
|||
# For each image |
|||
for name in [f for f in sorted(os.listdir(path)) if f.lower().endswith('.jpg')]: |
|||
path_large = os.path.join(path, name) |
|||
path_small = os.path.join(path, str(SIZE_SMALL), name) |
|||
path_thumbnail = os.path.join(path, str(SIZE_THUMBNAIL), name) |
|||
print(path_large) |
|||
image = Image.open(path_large) |
|||
# Fix orientation |
|||
exif = { |
|||
ExifTags.TAGS[k]: v |
|||
for k, v in (image._getexif() or {}).items() |
|||
if k in ExifTags.TAGS |
|||
} |
|||
orientation = exif.get('Orientation', 1) |
|||
if orientation == 6: |
|||
image = image.rotate(-90, expand=True) |
|||
elif orientation == 8: |
|||
image = image.rotate(90, expand=True) |
|||
if orientation != 1: |
|||
image.save(path_large) |
|||
ratio = image.size[0] / image.size[1] |
|||
# Create low-resolution image |
|||
if not os.path.exists(path_small): |
|||
create_directory(path_small) |
|||
image.resize( |
|||
(int(round(SIZE_SMALL * ratio)), SIZE_SMALL) |
|||
if ratio > 1 else |
|||
(SIZE_SMALL, int(round(SIZE_SMALL / ratio))), |
|||
Image.ANTIALIAS |
|||
).save(path_small) |
|||
# Create thumbnail |
|||
if not os.path.exists(path_thumbnail): |
|||
create_directory(path_thumbnail) |
|||
image.resize( |
|||
(SIZE_THUMBNAIL, int(round(SIZE_THUMBNAIL / ratio))) |
|||
if ratio > 1 else |
|||
(int(round(SIZE_THUMBNAIL * ratio)), SIZE_THUMBNAIL), |
|||
Image.ANTIALIAS |
|||
).save(path_thumbnail) |
|||
# Create HTML |
|||
html_album += ( |
|||
'{0}<div><a href="../!/#{1}/{2}">' |
|||
'<img class="{3}" src="{4}/{2}"/></a></div>' |
|||
).format( |
|||
'' if not html_album else '\n', path, name, |
|||
'landscape' if ratio > 1 else 'portrait', SIZE_THUMBNAIL |
|||
) |
|||
# Cleanup |
|||
for p in [ |
|||
os.path.join(path, str(SIZE_SMALL)), |
|||
os.path.join(path, str(SIZE_THUMBNAIL)) |
|||
]: |
|||
for n in [f for f in os.listdir(p) if f.lower().endswith('.jpg')]: |
|||
if not os.path.exists(os.path.join(path, n)): |
|||
os.remove(os.path.join(p, n)) |
|||
# Write album HTML |
|||
write_html( |
|||
'album.html', os.path.join(path, 'index.html'), html_album, path |
|||
) |
|||
html_index += '\n</ul>' |
|||
# Write index HTML |
|||
write_html('index.html', 'index.html', html_index) |
|||
|
|||
# Alternatively, you can comment this out and use FTP / run rsync separately |
|||
''' |
|||
print("Syncing albums...") |
|||
os.system('rsync -av --ignore-existing ./ "{}"'.format(REMOTE_PATH)) |
|||
''' |
@ -0,0 +1,30 @@ |
|||
#!/usr/bin/python3 |
|||
import os |
|||
import json |
|||
import subprocess |
|||
from collections import OrderedDict |
|||
|
|||
#usage: python3 write_captionsJSON.py |
|||
|
|||
# do not overwrite existing captions |
|||
if not os.path.exists("js/captions.json"): |
|||
captions = {} |
|||
else: |
|||
captions = json.load(open("js/captions.json")) |
|||
subprocess.call(['cp', 'js/captions.json', 'js/captions.json.back']) |
|||
# CleanUp needed for renamed files (?how) |
|||
# cleanup deleted images |
|||
captions = { k : v for k,v in captions.items() if os.path.exists(k)} |
|||
|
|||
# For each album |
|||
for path in [f for f in os.listdir('./') if os.path.isdir(f) and f != '!' and not 'videos' in f and f != 'js']: |
|||
# For each image |
|||
for name in [f for f in sorted(os.listdir(path)) if f.lower().endswith('.jpg')]: |
|||
path_name = path + "/" + name |
|||
if path_name not in captions.keys(): |
|||
captions[path_name] = "" |
|||
|
|||
# write 'sorted dict' to file |
|||
with open("js/captions.json","w") as j: |
|||
json.dump(OrderedDict(sorted(captions.items())), j, indent=2) |
|||
|
Loading…
Reference in new issue