Turning folders into web pages with Python: Difference between revisions
No edit summary |
No edit summary |
||
| Line 73: | Line 73: | ||
===Timestamps=== | ===Timestamps=== | ||
<syntaxhighlight lang="python"> | |||
# Sort by timestamp | |||
assets = sorted(assets, key=os.path.getmtime) | |||
# You can reverse the sort by passing reverse=True to the sorted function | |||
assets = sorted(assets, key=os.path.getmtime, reverse=True) | |||
</syntaxhighlight> | |||
===Uploader=== | ===Uploader=== | ||
| Line 79: | Line 87: | ||
===File size=== | ===File size=== | ||
<syntaxhighlight lang="python"> | |||
# Sort by size | |||
assets = sorted(assets, key=os.path.getsize) | |||
</syntaxhighlight> | |||
===Anecdotes=== | ===Anecdotes=== | ||
<code> | How about setting up a small gossip system for our gallery? | ||
Choose a file to annotate, and create a file with the extension <code>.anecdote</code> | |||
$ touch photo_1_2026-02-02_11-56-09.jpg.anecdote | |||
Open the anecdote with a text editor and write your gossips there! | |||
$ nano photo_1_2026-02-02_11-56-09.jpg.anecdote | |||
Then in our python code we check for anecdotes: | |||
<syntaxhighlight lang="python"> | |||
[...] | |||
assets_or_anecdotes = [] | |||
for asset in assets: | |||
# Every asset has a file... | |||
file_maybe_anecdote = { | |||
"file": asset | |||
} | |||
# But some also have an anecdote | |||
if asset.endswith('.anecdote'): | |||
# If it is we read its content into the file_maybe_anecdote dictionary | |||
with open(asset, 'r') as a: | |||
file_maybe_anecdote['anecdote'] = a.read() | |||
# Append it to the list of assets | |||
assets_or_anecdotes.append(file_maybe_anecdote) | |||
[...] | |||
output = jinja_template.render(assets=assets_or_anecdotes) | |||
</syntaxhighlight> | |||
In the template, we use conditionals to check if an asset is an anecdote or not, and we render it accordingly. | |||
<syntaxhighlight lang="html"> | |||
<ol> | |||
{% for asset in assets %} | |||
{% if asset.anecdote %} | |||
<p>{{ asset.anecdote }}</p> | |||
{% else %} | |||
<li><img src="{{asset.file}}"/></li> | |||
{% endif %} | |||
{% endfor %} | |||
</ol> | |||
</syntaxhighlight> | |||
(to try out: how to make more anecdotes for the same file?) | |||
===Alt text=== | ===Alt text=== | ||
How to repurpose the anecdotes system to write alt captions for the images? | |||
===Hyperlinks=== | ===Hyperlinks=== | ||
===Structured Metadata=== | |||
<syntaxhighlight lang="python"> | |||
# Add some metadata to the assets list | |||
import os | |||
import pwd | |||
from datetime import datetime | |||
#[...] | |||
assets_with_meta = [] | |||
for asset in assets: | |||
# Load and parse stats about a file | |||
# https://docs.python.org/3/library/stat.html | |||
stat = os.stat(asset) | |||
size = stat.st_size | |||
# Work with datetime | |||
# https://www.programiz.com/python-programming/datetime/strftime | |||
last_modified = datetime | |||
.fromtimestamp(stat.st_mtime) | |||
.strftime("%m/%d/%Y, %H:%M:%S") | |||
# Get username from user id | |||
# https://stackoverflow.com/questions/842059#comment3162593_2899055 | |||
user = pwd.getpwuid(stat.st_uid).pw_name | |||
# Create a dictionary with all the info | |||
asset_with_meta = { | |||
"file": asset, | |||
"user": user, | |||
"last_modified": last_modified, | |||
"size": size | |||
} | |||
# Append it to the list of assets | |||
assets_with_meta.append(asset_with_meta) | |||
</syntaxhighlight> | |||
Then you can pass your assets_with_meta list to the template... | |||
<syntaxhighlight lang="python"> | |||
output = jinja_template.render(assets=assets_with_meta) | |||
</syntaxhighlight> | |||
And play around with it in the template.html file | |||
<syntaxhighlight lang="html"> | |||
<ol> | |||
{% for asset in assets %} | |||
<li> | |||
<img src="{{asset.file}}"/> | |||
{{asset.user}} - {{asset.last_modified}} - {{asset.size}} | |||
</li> | |||
{% endfor %} | |||
</ol> | |||
</syntaxhighlight> | |||
===etc!!!=== | ===etc!!!=== | ||
Hopefully this triggers ideas for more extension points. | Hopefully this triggers ideas for more extension points. | ||
Revision as of 17:11, 5 February 2026
For the prototyping class on 10 February 2026 in the context of SI29.
Gallery example
1. Install uv
(if you don't have uv already)
https://docs.astral.sh/uv/getting-started/installation/
$ curl -LsSf https://astral.sh/uv/install.sh | sh
2. Initialize project
$ uv init gallery
3. Prepare an assets folder
$ mkdir assets
4. Put some files in the assets folder
Just copy and paste!
5. Work on main.py
from glob import glob
from jinja2 import Template
def main():
assets = glob('assets/*')
with open('template.html','r') as f:
html_template = f.read()
jinja_template = Template(html_template)
output = jinja_template.render(assets=assets)
with open('index.html', 'w') as f:
f.write(output)
if __name__ == "__main__":
main()
6. Work on your template.html
<style>
img {
max-width: 200px;
object-fit: contain;
}
</style>
<ol>
{% for asset in assets %}
<li><img src="{{asset}}"/></li>
{% endfor %}
</ol>
7. Run the script
$ uv run main.py
8. See the result
Open the index.html file in your browser.
Possible extension points
Timestamps
# Sort by timestamp
assets = sorted(assets, key=os.path.getmtime)
# You can reverse the sort by passing reverse=True to the sorted function
assets = sorted(assets, key=os.path.getmtime, reverse=True)
Uploader
Media type
File size
# Sort by size
assets = sorted(assets, key=os.path.getsize)
Anecdotes
How about setting up a small gossip system for our gallery?
Choose a file to annotate, and create a file with the extension .anecdote
$ touch photo_1_2026-02-02_11-56-09.jpg.anecdote
Open the anecdote with a text editor and write your gossips there!
$ nano photo_1_2026-02-02_11-56-09.jpg.anecdote
Then in our python code we check for anecdotes:
[...]
assets_or_anecdotes = []
for asset in assets:
# Every asset has a file...
file_maybe_anecdote = {
"file": asset
}
# But some also have an anecdote
if asset.endswith('.anecdote'):
# If it is we read its content into the file_maybe_anecdote dictionary
with open(asset, 'r') as a:
file_maybe_anecdote['anecdote'] = a.read()
# Append it to the list of assets
assets_or_anecdotes.append(file_maybe_anecdote)
[...]
output = jinja_template.render(assets=assets_or_anecdotes)
In the template, we use conditionals to check if an asset is an anecdote or not, and we render it accordingly.
<ol>
{% for asset in assets %}
{% if asset.anecdote %}
<p>{{ asset.anecdote }}</p>
{% else %}
<li><img src="{{asset.file}}"/></li>
{% endif %}
{% endfor %}
</ol>
(to try out: how to make more anecdotes for the same file?)
Alt text
How to repurpose the anecdotes system to write alt captions for the images?
Hyperlinks
Structured Metadata
# Add some metadata to the assets list
import os
import pwd
from datetime import datetime
#[...]
assets_with_meta = []
for asset in assets:
# Load and parse stats about a file
# https://docs.python.org/3/library/stat.html
stat = os.stat(asset)
size = stat.st_size
# Work with datetime
# https://www.programiz.com/python-programming/datetime/strftime
last_modified = datetime
.fromtimestamp(stat.st_mtime)
.strftime("%m/%d/%Y, %H:%M:%S")
# Get username from user id
# https://stackoverflow.com/questions/842059#comment3162593_2899055
user = pwd.getpwuid(stat.st_uid).pw_name
# Create a dictionary with all the info
asset_with_meta = {
"file": asset,
"user": user,
"last_modified": last_modified,
"size": size
}
# Append it to the list of assets
assets_with_meta.append(asset_with_meta)
Then you can pass your assets_with_meta list to the template...
output = jinja_template.render(assets=assets_with_meta)
And play around with it in the template.html file
<ol>
{% for asset in assets %}
<li>
<img src="{{asset.file}}"/>
{{asset.user}} - {{asset.last_modified}} - {{asset.size}}
</li>
{% endfor %}
</ol>
etc!!!
Hopefully this triggers ideas for more extension points.