Compare commits
No commits in common. "cc64d3012a33240665182661e0070753ec37d60e" and "683d15249118cdcb2e6a1c7983fd5b7e85e219be" have entirely different histories.
cc64d3012a
...
683d152491
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,3 +1,2 @@
|
|||||||
venv
|
venv
|
||||||
*.pyc
|
*.pyc
|
||||||
output
|
|
28
README.md
28
README.md
@ -4,17 +4,23 @@ Just a simple python program to generate static site
|
|||||||
|
|
||||||
## File
|
## File
|
||||||
|
|
||||||
- RAW: (optionnal)
|
- .nef: **(MANDATORY)**
|
||||||
- EDIT_DATA: (optionnal)
|
- .pp3: (optionnal)
|
||||||
- LARGE: high resolution format (optionnal: can be generated by the RAW)
|
- .png: high resolution format (optionnal: can be generated by the .nef)
|
||||||
- SMALL: low resolution format (optionnal: can be generated by the LARGE)
|
- .jpeg: low resolution format (optionnal: can be generated by the .png)
|
||||||
- DESQ: description markdown file (optionnal)
|
- desc.md: description markdown file (optionnal)
|
||||||
|
|
||||||
### Format supported
|
### File structure
|
||||||
```
|
```
|
||||||
RAW: .NEF
|
img1/
|
||||||
LARGE: .png
|
├─ img1.nef
|
||||||
SMALL: jpeg
|
img2/
|
||||||
EDIT_DATA: .pp3
|
├─ img2.pp3
|
||||||
DESQ: .md
|
├─ img2.png
|
||||||
|
├─ img2.jpeg
|
||||||
|
├─ img2.nef
|
||||||
|
img3.nef
|
||||||
|
img4.png
|
||||||
|
img4.jpeg
|
||||||
|
img4.nef
|
||||||
```
|
```
|
@ -1,9 +0,0 @@
|
|||||||
{
|
|
||||||
"file_type_extensions": {
|
|
||||||
"raw": [".NEF"],
|
|
||||||
"large": [".png"],
|
|
||||||
"small": [".jpeg"],
|
|
||||||
"edits": [".pp3"],
|
|
||||||
"desq": [".md"]
|
|
||||||
}
|
|
||||||
}
|
|
55
example/img1/test.html
Normal file
55
example/img1/test.html
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="fr">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Dropdown Button</title>
|
||||||
|
<style>
|
||||||
|
/* Style du bouton */
|
||||||
|
.dropdown-btn {
|
||||||
|
padding: 10px 20px;
|
||||||
|
background-color: #4CAF50;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 16px;
|
||||||
|
border-radius: 5px;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Cacher le radio (pour qu'il ne soit pas visible) */
|
||||||
|
.dropdown-radio {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Style du texte qui apparaît lorsque la case est cochée */
|
||||||
|
.dropdown-text {
|
||||||
|
display: none;
|
||||||
|
margin-top: 10px;
|
||||||
|
padding: 10px;
|
||||||
|
background-color: #f1f1f1;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Quand le radio est sélectionné, afficher le texte */
|
||||||
|
.dropdown-radio:checked + .dropdown-btn + .dropdown-text {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<!-- Radio caché qui contrôle l'affichage du texte -->
|
||||||
|
<input type="radio" id="dropdown" class="dropdown-radio" name="dropdown-group">
|
||||||
|
|
||||||
|
<!-- Bouton -->
|
||||||
|
<label for="dropdown" class="dropdown-btn">Afficher le texte</label>
|
||||||
|
|
||||||
|
<!-- Texte qui se déploie -->
|
||||||
|
<div class="dropdown-text">
|
||||||
|
Voici le texte qui se déploie quand on clique sur le bouton.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -1,5 +0,0 @@
|
|||||||
LARGE = "*.png"
|
|
||||||
SMALL = "*.jpeg"
|
|
||||||
RAW = "*.nef"
|
|
||||||
EDIT = "*.pp3"
|
|
||||||
DESC = "*.md"
|
|
97
src/main.py
97
src/main.py
@ -1,103 +1,14 @@
|
|||||||
import sys
|
import sys
|
||||||
import help
|
import help
|
||||||
import rawpy
|
import PIL
|
||||||
import imageio
|
|
||||||
import os
|
|
||||||
import shutil
|
|
||||||
import json
|
|
||||||
from PIL import Image
|
|
||||||
from jinja2 import Environment, FileSystemLoader
|
|
||||||
import subprocess
|
|
||||||
|
|
||||||
with open('config.json', 'r') as file:
|
|
||||||
config: dict = json.load(file)
|
|
||||||
|
|
||||||
# Initialiser l'environnement avec un dossier de templates
|
|
||||||
env = Environment(loader=FileSystemLoader('src/templates'))
|
|
||||||
|
|
||||||
template = env.get_template('index.html')
|
|
||||||
|
|
||||||
def get_files_recursive(directory):
|
|
||||||
file_paths = []
|
|
||||||
for root, dirs, files in os.walk(directory):
|
|
||||||
for file in files:
|
|
||||||
file_paths.append(os.path.join(root, file))
|
|
||||||
return file_paths
|
|
||||||
|
|
||||||
|
|
||||||
def move_files(files: list[str], input_path, output_path):
|
|
||||||
for key, type_file_extensions in config["file_type_extensions"].items():
|
|
||||||
for file in files:
|
|
||||||
for type_file_extension in type_file_extensions:
|
|
||||||
if file.endswith(type_file_extension):
|
|
||||||
path = file.replace(input_path, output_path)[:-len(type_file_extension)]
|
|
||||||
if not os.path.exists(path):
|
|
||||||
if (key not in ["raw", "large", "small"]):
|
|
||||||
continue
|
|
||||||
os.makedirs(path)
|
|
||||||
shutil.copy2(file, path)
|
|
||||||
|
|
||||||
def nef_to_jpeg(path:str):
|
|
||||||
with rawpy.imread(path) as raw:
|
|
||||||
rgb = raw.postprocess()
|
|
||||||
imageio.imwrite(path.replace('.NEF', '.jpeg'), rgb)
|
|
||||||
|
|
||||||
def png_to_jpeg(path: str):
|
|
||||||
im = Image.open(path)
|
|
||||||
rgb_im = im.convert('RGB')
|
|
||||||
rgb_im.save(path.replace('.nef', '.jpeg'))
|
|
||||||
|
|
||||||
|
|
||||||
def generate_missing_images(raws: list[str], large: list[str], small: list[str]):
|
|
||||||
if len(small) == 0:
|
|
||||||
if (len(large) == 0):
|
|
||||||
nef_to_jpeg(raws[0])
|
|
||||||
return
|
|
||||||
png_to_jpeg(large[0])
|
|
||||||
return
|
|
||||||
|
|
||||||
def get_exif(raws: list[str]):
|
|
||||||
if (len(raws) == 0):
|
|
||||||
return None
|
|
||||||
return str(subprocess.check_output(["exiftool", f"{raws[0]}"])).replace("\\n", "\n")
|
|
||||||
|
|
||||||
|
|
||||||
def generate_page(output_path: str):
|
|
||||||
for folder in os.listdir(output_path):
|
|
||||||
path = os.path.join(output_path, folder)
|
|
||||||
if (os.path.isdir(path)):
|
|
||||||
files: list[str] = [os.path.join(path, file) for file in os.listdir(path) if os.path.isfile(os.path.join(path, file))]
|
|
||||||
|
|
||||||
raws = [file for ext in config["file_type_extensions"]["raw"] for file in files if file.endswith(ext)]
|
|
||||||
larges = [file for ext in config["file_type_extensions"]["large"] for file in files if file.endswith(ext)]
|
|
||||||
smalls = [file for ext in config["file_type_extensions"]["small"] for file in files if file.endswith(ext)]
|
|
||||||
|
|
||||||
generate_missing_images(raws, larges, smalls)
|
|
||||||
|
|
||||||
exif = get_exif(raws)
|
|
||||||
raw = os.path.basename(raws[0]) if len(raws) > 0 else None
|
|
||||||
large = os.path.basename(larges[0]) if len(larges) > 0 else None
|
|
||||||
small = os.path.basename(smalls[0]) if len(smalls) > 0 else None
|
|
||||||
|
|
||||||
html_rendered = template.render(exif=exif, raw=raw, large=large, small=small)
|
|
||||||
|
|
||||||
with open(os.path.join(path, f"{folder}.html"), "w") as f:
|
|
||||||
f.write(html_rendered)
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
||||||
if len(sys.argv) < 2:
|
if len(sys.argv) != 2:
|
||||||
help.display(sys.argv[0])
|
help.display(sys.argv[0])
|
||||||
return
|
return
|
||||||
|
|
||||||
input_path = sys.argv[1]
|
|
||||||
output_path = "output/" if (len(sys.argv) == 2) else sys.argv[2] + "/"
|
|
||||||
|
|
||||||
files: list[str] = get_files_recursive(input_path)
|
|
||||||
|
|
||||||
move_files(files, input_path, output_path)
|
|
||||||
|
|
||||||
generate_page(output_path)
|
|
||||||
|
|
||||||
if (__name__ == "__main__"):
|
if (__name__ == "__main__"):
|
||||||
main()
|
main()
|
9
src/template/index.html
Normal file
9
src/template/index.html
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<img src="./img1.je">
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -1,46 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<link rel="stylesheet" href="img1.css">
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<img id="small" src="{{ small }}">\
|
|
||||||
{% if large or raw %}
|
|
||||||
<div id="download">
|
|
||||||
{% if large %}
|
|
||||||
<a id="large" href="{{ large }}">
|
|
||||||
<img src="../icons/file.png">
|
|
||||||
<p>large</p>
|
|
||||||
</a>
|
|
||||||
{% endif %}
|
|
||||||
{% if raw %}
|
|
||||||
<a id="raw" href="{{ raw }}">
|
|
||||||
<img src="../icons/file.png">
|
|
||||||
<p>raw</p>
|
|
||||||
</a>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
{% if desc %}
|
|
||||||
<div id="description">
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
{% if exif %}
|
|
||||||
<div id="exif">
|
|
||||||
<!-- Checkbox cachée qui contrôle l'affichage du texte -->
|
|
||||||
<input type="checkbox" id="dropdown" class="dropdown-checkbox">
|
|
||||||
|
|
||||||
<!-- Bouton -->
|
|
||||||
<label for="dropdown" class="dropdown-btn">Display exif data</label>
|
|
||||||
<div class="dropdown-text">
|
|
||||||
<pre>
|
|
||||||
<code>
|
|
||||||
{{exif}}
|
|
||||||
</code>
|
|
||||||
</pre>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
</body>
|
|
||||||
</html>
|
|
Loading…
Reference in New Issue
Block a user