-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbuild.py
executable file
·123 lines (97 loc) · 3.96 KB
/
build.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#!/usr/bin/env python3
from glob import glob
from PIL import Image, ExifTags
from collections import defaultdict
MONTHS = {
1: "Jan",
2: "Feb",
3: "Mar",
4: "Apr",
5: "May",
6: "Jun",
7: "Jul",
8: "Aug",
9: "Sep",
10: "Oct",
11: "Nov",
12: "Dec",
}
TEMPLATE = """
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang=en-US>
<head>
<title>underexposed</title>
<meta name="description" content="I'm Nicola, a PhD student from UC Santa Barbara. I recently picked up the hobby of photography. This page is a place to collect my latest photos.">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" type="text/css" href="css/main.css">
<!-- favicons -->
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
<link rel="manifest" href="/site.webmanifest">
</head>
<body>
{containers}
</body>
</html>
"""
NAV_ITEM_TEMPLATE = """
<a href="#{year}" id="nav-{year}"><h2 class="{_class}"><span>{year}</span></h2></a>"""
CONTAINER_TEMPLATE = """
<div id="{year}" class="container {_class}">
<div class="column right">
<h1>UNDEREXPOSED</h1><br>
<p>Hi there! I'm Nicola, a PhD student from UC Santa Barbara. <br><br>I recently picked up the hobby of photography. This page is a place to collect my latest photos.</p><br><br>
<nav>
{nav_items}
</nav>
<!-- END DIV COLUMN RIGHT -->
</div>
<div class="column left">
<div class="container-spacing"></div>
{photos}
<!-- END DIV COLUMN LEFT -->
</div>
<!-- END CONTAINER {year} -->
</div>
"""
PHOTO_TEMPLATE = """
<div class="image-container">
<img src="./{path}" width="2048" height="1365" loading="lazy" alt="{date}. {dof}mm f/{f} {shutter}s ISO {iso}">
<p class="image-label">{date}. {dof}mm f/{f} {shutter}s ISO {iso}.</p><br><br>
</div>
"""
all_photos = glob("archive/**/**.jpg", recursive=True)
containers = defaultdict(list)
for path in all_photos:
if path.split("/")[-1].startswith("_"):
print(f"ERROR: Found a filename starting with an \"_\". Please fix that: {path}")
exit(1)
exif = {
ExifTags.TAGS[k]: v
for k, v in Image.open(path)._getexif().items()
if k in ExifTags.TAGS
}
year, month, day = exif["DateTimeOriginal"].split()[0].split(":")
date = f"{MONTHS[int(month)]} {day}, {year}"
dof = int(round(exif["FocalLength"]))
f = exif["FNumber"]
if exif['ExposureTime'] < 1:
shutter = f"1/{1/exif['ExposureTime']}"
else:
shutter = int(round(exif["ExposureTime"]))
iso = exif["ISOSpeedRatings"]
photo_html = PHOTO_TEMPLATE.format(path=path, date=date, dof=dof, f=f, shutter=shutter, iso=iso)
containers[int(year)].append((exif["DateTimeOriginal"], photo_html))
containers_html = ""
for year in sorted(containers, reverse=True):
containers[year] = [s[1] for s in sorted(containers[year], key=lambda e: e[0], reverse=True)]
navs_html = "".join([NAV_ITEM_TEMPLATE.format(year=y, _class="active" if y==year else "") for y in sorted(containers, reverse=True)])
containers_html += CONTAINER_TEMPLATE.format(year=year, _class="", nav_items=navs_html, photos=''.join(containers[year]))
# duplicate most recent year as fallback (shown by default on page load)
fallback_year = max(containers)
navs_html = "".join([NAV_ITEM_TEMPLATE.format(year=y, _class="active" if y==fallback_year else "") for y in sorted(containers, reverse=True)])
containers_html += CONTAINER_TEMPLATE.format(year=fallback_year, _class="fallback", nav_items=navs_html, photos=''.join(containers[fallback_year]))
template = TEMPLATE.format(containers=containers_html)
with open("./index.html", "w") as f:
f.write(template)