Skip to content

Commit a652cda

Browse files
authored
Fea (ED-72): generate book md script and improve collection md (#76)
* Feat (ED-72): generate books test * Feat (ED-72): add generate_books.py script * Refactor (ED-72): prettier code formatter * Refactor (ED-72): prettier code formatter * Feat (ED-72): add script to generate book entries * Refactor (ED-72): prettier code formatter * Feat (ED-72): test delete temp folder * Refactor (ED-72): refactor script * Refactor (ED-72): refactor script * Refactor (ED-72): prettier code formatter * Refactor (ED-72): prettier code formatter * Refactor (ED-72): refactor collections script
1 parent f43f88f commit a652cda

16 files changed

Lines changed: 1802 additions & 114 deletions
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
---
2+
layout: book
3+
title: L'aportació de Ferrer Pastor a la lexicografia catalano-valenciana
4+
author: Emili Casanova
5+
isbn: 9788416473588
6+
pvp: 39.99
7+
year: 2022
8+
description: L'aportació de Ferrer Pastor a la lexicografia catalano-valenciana. Paraules del Diccionari General, 1985 absents del diccionari Fabra, 1986, 22ªED.
9+
description_long: En el present assaig, Emili Casanova analitza les aportacions a la llengua de l'obra de Ferrer Pastor.
10+
importance: 10
11+
category: poesia
12+
img: assets/img/collection_preview/collection_default.png
13+
---

_books/genesi-avl.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
---
2+
layout: book
3+
title: Gènesi de l'AVL. El Debat
4+
author: Manuel Sanchis-Guarner Cabanilles
5+
isbn: 9788416473632
6+
pvp: 12.00
7+
year: 2024
8+
description: Gènesi de l'AVL. El debat.
9+
description_long: Manuel Sanchis-Guarner Cabanilles, fill de l'il·lustre filòleg, narra de primera mà el procés de debat al sí del Consell Valencià de Cultura que donà origen al dictamen de creació de l'Acadèmia Valenciana de la Llengua.
10+
importance: 1
11+
category: bàsica
12+
img: assets/img/collection_preview/collection_default.png
13+
---

requirements.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
nbconvert
2+
3+
pytest~=8.3.1
4.73 KB
Binary file not shown.
-2 Bytes
Binary file not shown.

scripts/generate_books.py

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
import json
2+
import os
3+
4+
5+
def get_books_json_path():
6+
script_dir = os.path.dirname(os.path.abspath(__file__))
7+
resources_dir = os.path.join(script_dir, 'resources')
8+
return os.path.join(resources_dir, 'books.json')
9+
10+
11+
def file_exists(file_path):
12+
return os.path.exists(file_path)
13+
14+
15+
def load_json(file_path):
16+
try:
17+
with open(file_path, 'r', encoding='utf-8') as file:
18+
return json.load(file)
19+
except FileNotFoundError:
20+
print(f"Error: The file '{file_path}' was not found.")
21+
exit(1)
22+
except json.JSONDecodeError:
23+
print(f"Error: The file '{file_path}' is not a valid JSON file.")
24+
exit(1)
25+
26+
27+
required_fields = {
28+
"layout": str,
29+
"title": str,
30+
"author": str,
31+
"isbn": str,
32+
"pvp": str,
33+
"year": int,
34+
"description": str,
35+
"description_long": str,
36+
"importance": int,
37+
"category": str,
38+
"img": str,
39+
"filename": str
40+
}
41+
42+
43+
def validate_json_structure(data):
44+
for book in data:
45+
for field, field_type in required_fields.items():
46+
if field not in book:
47+
return False, f"Field {field} is missing in book {book}"
48+
if not isinstance(book[field], field_type):
49+
return False, f"Field {field} in book {book} should be of type {field_type.__name__}"
50+
return True, "All checks passed"
51+
52+
53+
def ensure_output_dir_exists(output_dir):
54+
if not os.path.exists(output_dir):
55+
os.makedirs(output_dir)
56+
57+
58+
def create_book_md_content(book):
59+
content = ["---"]
60+
for field, value in book.items():
61+
if field != "filename": # Exclude the filename field
62+
content.append(f"{field}: {value}")
63+
content.append("---")
64+
content.append("") # Add an extra blank line at the end
65+
return "\n".join(content)
66+
67+
68+
def write_markdown_file(filename, content):
69+
with open(filename, 'w', encoding='utf-8') as md_file:
70+
md_file.write(content)
71+
print(f"Created {filename}")
72+
73+
74+
def generate_book_markdown_files(books, output_dir):
75+
ensure_output_dir_exists(output_dir)
76+
created_files = []
77+
for book in books:
78+
file_name = f"{book['filename']}.md"
79+
file_path = os.path.join(output_dir, file_name)
80+
if not os.path.exists(file_path):
81+
content = create_book_md_content(book)
82+
write_markdown_file(file_path, content)
83+
created_files.append(file_path)
84+
else:
85+
print(f"Skipped {file_path} (already exists)")
86+
return created_files
87+
88+
89+
def main():
90+
books_json_path = get_books_json_path()
91+
books_output_dir = os.path.join('..', '_books')
92+
93+
print(f"Using JSON file for books: {books_json_path}")
94+
print(f"Output directory for books: {books_output_dir}")
95+
96+
books_data = load_json(books_json_path)
97+
generate_book_markdown_files(books_data, books_output_dir)
98+
99+
100+
if __name__ == "__main__":
101+
main()

scripts/generate_collections.py

Lines changed: 90 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -2,76 +2,101 @@
22
import os
33

44

5-
class CollectionMarkdownGenerator:
6-
def __init__(self, json_path, output_dir):
7-
self.json_path = json_path
8-
self.output_dir = output_dir
9-
10-
def load_collections(self):
11-
try:
12-
with open(self.json_path, 'r') as file:
13-
collections = json.load(file)
14-
return collections
15-
except FileNotFoundError:
16-
print(f"Error: The file '{self.json_path}' was not found.")
17-
exit(1)
18-
except json.JSONDecodeError:
19-
print(f"Error: The file '{self.json_path}' is not a valid JSON file.")
20-
exit(1)
21-
22-
@staticmethod
23-
def create_markdown_content(collection):
24-
return f"""---
25-
layout: {collection['layout']}
26-
title: {collection['title']}
27-
description: {collection['description']}
28-
img: {collection['img']}
29-
importance: {collection['importance']}
30-
category: {collection['category']}
31-
category_book: {collection['category_book']}
32-
related_publications: {str(collection['related_publications']).lower()}
33-
horizontal: {str(collection['horizontal']).lower()}
34-
---
35-
36-
{{% include books_display.liquid %}}
37-
"""
38-
39-
def ensure_output_dir_exists(self):
40-
if not os.path.exists(self.output_dir):
41-
os.makedirs(self.output_dir)
42-
43-
@staticmethod
44-
def write_markdown_file(filename, content):
45-
with open(filename, 'w') as md_file:
46-
md_file.write(content)
47-
print(f"Created {filename}")
48-
49-
def generate_markdown_files(self):
50-
self.ensure_output_dir_exists()
51-
collections = self.load_collections()
52-
53-
for collection in collections:
54-
filename = os.path.join(self.output_dir, collection['filename'])
55-
if not os.path.exists(filename):
56-
content = self.create_markdown_content(collection)
57-
self.write_markdown_file(filename, content)
58-
else:
59-
print(f"Skipped {filename} (already exists)")
5+
def get_collections_json_path():
6+
script_dir = os.path.dirname(os.path.abspath(__file__))
7+
resources_dir = os.path.join(script_dir, 'resources')
8+
return os.path.join(resources_dir, 'collections.json')
9+
10+
11+
def file_exists(file_path):
12+
return os.path.exists(file_path)
13+
14+
15+
def load_json(file_path):
16+
try:
17+
with open(file_path, 'r', encoding='utf-8') as file:
18+
return json.load(file)
19+
except FileNotFoundError:
20+
print(f"Error: The file '{file_path}' was not found.")
21+
exit(1)
22+
except json.JSONDecodeError:
23+
print(f"Error: The file '{file_path}' is not a valid JSON file.")
24+
exit(1)
25+
26+
27+
required_fields = {
28+
"layout": str,
29+
"title": str,
30+
"description": str,
31+
"img": str,
32+
"importance": int,
33+
"category": str,
34+
"category_book": str,
35+
"related_publications": bool,
36+
"horizontal": bool,
37+
"filename": str
38+
}
39+
40+
41+
def validate_json_structure(data):
42+
for collection in data:
43+
for field, field_type in required_fields.items():
44+
if field not in collection:
45+
return False, f"Field {field} is missing in collection {collection}"
46+
if not isinstance(collection[field], field_type):
47+
return False, f"Field {field} in collection {collection} should be of type {field_type.__name__}"
48+
return True, "All checks passed"
49+
50+
51+
def ensure_output_dir_exists(output_dir):
52+
if not os.path.exists(output_dir):
53+
os.makedirs(output_dir)
54+
55+
56+
def create_collection_md_content(collection):
57+
content = ["---"]
58+
for field, value in collection.items():
59+
if field != "filename": # Exclude the filename field
60+
if isinstance(value, bool):
61+
value = str(value).lower() # Convert boolean to lowercase string
62+
content.append(f"{field}: {value}")
63+
content.append("---")
64+
content.append("")
65+
content.append("{% include books_display.liquid %}")
66+
content.append("") # Add an extra blank line at the end
67+
return "\n".join(content)
68+
69+
70+
def write_markdown_file(filename, content):
71+
with open(filename, 'w', encoding='utf-8') as md_file:
72+
md_file.write(content)
73+
print(f"Created {filename}")
74+
75+
76+
def generate_collection_markdown_files(collections, output_dir):
77+
ensure_output_dir_exists(output_dir)
78+
created_files = []
79+
for collection in collections:
80+
file_name = f"{collection['filename']}.md"
81+
file_path = os.path.join(output_dir, file_name)
82+
if not os.path.exists(file_path):
83+
content = create_collection_md_content(collection)
84+
write_markdown_file(file_path, content)
85+
created_files.append(file_path)
86+
else:
87+
print(f"Skipped {file_path} (already exists)")
88+
return created_files
6089

6190

6291
def main():
63-
# Set the base path to the root of your project
64-
base_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
92+
collections_json_path = get_collections_json_path()
93+
collections_output_dir = os.path.join('..', '_collections')
6594

66-
# Use the base path to construct the absolute path for the JSON file
67-
json_path = os.path.join(base_path, 'assets', 'json', 'collections.json')
68-
output_dir = os.path.join(base_path, '_collections')
95+
print(f"Using JSON file for collections: {collections_json_path}")
96+
print(f"Output directory for collections: {collections_output_dir}")
6997

70-
print(f"Using JSON file: {json_path}")
71-
print(f"Output directory: {output_dir}")
72-
73-
generator = CollectionMarkdownGenerator(json_path, output_dir)
74-
generator.generate_markdown_files()
98+
collections_data = load_json(collections_json_path)
99+
generate_collection_markdown_files(collections_data, collections_output_dir)
75100

76101

77102
if __name__ == "__main__":

scripts/modify_json.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import json
2+
import os
3+
import random
4+
import string
5+
6+
7+
def load_json(file_path):
8+
with open(file_path, 'r', encoding='utf-8') as file:
9+
return json.load(file)
10+
11+
12+
def save_json(data, file_path):
13+
with open(file_path, 'w', encoding='utf-8') as file:
14+
json.dump(data, file, ensure_ascii=False, indent=4)
15+
16+
17+
def generate_random_string(length=8):
18+
letters = string.ascii_lowercase
19+
return ''.join(random.choice(letters) for i in range(length))
20+
21+
22+
def add_filename_field(data):
23+
for item in data:
24+
item['filename'] = generate_random_string()
25+
return data
26+
27+
28+
def main():
29+
# Use raw string (r) to avoid issues with backslashes
30+
input_file_path = r'C:\Users\dotae\PycharmProjects\CescFe.github.io\tests\resources\books\sample_books.json'
31+
output_file_path = r'C:\Users\dotae\PycharmProjects\CescFe.github.io\tests\resources\books\sample_books.json'
32+
33+
data = load_json(input_file_path)
34+
modified_data = add_filename_field(data)
35+
save_json(modified_data, output_file_path)
36+
print(f"Modified JSON has been saved to {output_file_path}")
37+
38+
39+
if __name__ == "__main__":
40+
main()

scripts/resources/books.json

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
[
2+
{
3+
"layout": "book",
4+
"title": "Gènesi de l'AVL. El Debat",
5+
"author": "Manuel Sanchis-Guarner Cabanilles",
6+
"isbn": "9788416473632",
7+
"pvp": "12.00",
8+
"year": 2024,
9+
"description": "Gènesi de l'AVL. El debat.",
10+
"description_long": "Manuel Sanchis-Guarner Cabanilles, fill de l'il·lustre filòleg, narra de primera mà el procés de debat al sí del Consell Valencià de Cultura que donà origen al dictamen de creació de l'Acadèmia Valenciana de la Llengua.",
11+
"importance": 1,
12+
"category": "bàsica",
13+
"img": "assets/img/collection_preview/collection_default.png",
14+
"filename": "genesi-avl"
15+
},
16+
{
17+
"layout": "book",
18+
"title": "L'aportació de Ferrer Pastor a la lexicografia catalano-valenciana",
19+
"author": "Emili Casanova",
20+
"isbn": "9788416473588",
21+
"pvp": "39.99",
22+
"year": 2022,
23+
"description": "L'aportació de Ferrer Pastor a la lexicografia catalano-valenciana. Paraules del Diccionari General, 1985 absents del diccionari Fabra, 1986, 22ªED.",
24+
"description_long": "En el present assaig, Emili Casanova analitza les aportacions a la llengua de l'obra de Ferrer Pastor.",
25+
"importance": 10,
26+
"category": "poesia",
27+
"img": "assets/img/collection_preview/collection_default.png",
28+
"filename": "aportacio-ferrer-pastor-a-la-lexicografia"
29+
}
30+
]
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"category_book": "poesia",
1010
"related_publications": false,
1111
"horizontal": true,
12-
"filename": "poesia.md"
12+
"filename": "poesia"
1313
},
1414
{
1515
"layout": "page",
@@ -21,7 +21,7 @@
2121
"category_book": "diccionari",
2222
"related_publications": false,
2323
"horizontal": true,
24-
"filename": "diccionaris.md"
24+
"filename": "diccionaris"
2525
},
2626
{
2727
"layout": "page",
@@ -33,6 +33,6 @@
3333
"category_book": "bàsica",
3434
"related_publications": false,
3535
"horizontal": true,
36-
"filename": "basica.md"
36+
"filename": "basica"
3737
}
3838
]

0 commit comments

Comments
 (0)