Skip to content

Commit 48423f1

Browse files
committed
Optimize GitHub handlers, enhance error handling, and simplify tree creation logic.
1 parent 278504c commit 48423f1

7 files changed

Lines changed: 59 additions & 57 deletions

File tree

sutta_publisher/src/sutta_publisher/edition_parsers/base.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from typing import Callable, cast
1010

1111
import jinja2
12-
import requests
12+
import requests # type: ignore[import-untyped]
1313
from bs4 import BeautifulSoup, Tag
1414
from jinja2 import Environment, FileSystemLoader, Template, TemplateNotFound
1515

@@ -615,7 +615,7 @@ def _process_html_matter(matter: str, working_dir: str) -> str:
615615
else:
616616
response = requests.get(FRONTMATTER_URL.format(matter=matter, working_dir=working_dir))
617617
response.raise_for_status()
618-
return response.text
618+
return cast(str, response.text)
619619

620620
@staticmethod
621621
def _get_template(name: str) -> Template:

sutta_publisher/src/sutta_publisher/edition_parsers/helper_functions.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from typing import Any, cast, no_type_check
88
from zipfile import ZipFile
99

10-
import requests
10+
import requests # type: ignore[import-untyped]
1111
from bs4 import BeautifulSoup, Tag
1212
from ebooklib.epub import Link, Section
1313

@@ -322,7 +322,7 @@ def get_true_volume_index(volume: Volume) -> int:
322322
return cast(int, volume.volume_number - 1)
323323

324324

325-
def get_individual_cover_template_name(publication_type, volume: Volume) -> str:
325+
def get_individual_cover_template_name(publication_type: str, volume: Volume) -> str:
326326
"""Get volume's individual cover template name"""
327327
if volume.volume_number and publication_type == "hardcover":
328328
return f"{volume.text_uid}-{volume.volume_number}-hardcover.tex"
@@ -393,7 +393,4 @@ def make_hardcover_zip_files(paths: list[Path], num_of_volumes: int) -> list[Pat
393393
(f"{base_filename}-hardcover-cover.zip", cover_files),
394394
(f"{base_filename}-hardcover.zip", content_files),
395395
)
396-
return [
397-
_make_zip(filename=_filename, paths=_paths)
398-
for _filename, _paths in mapping
399-
]
396+
return [_make_zip(filename=_filename, paths=_paths) for _filename, _paths in mapping]

sutta_publisher/src/sutta_publisher/edition_parsers/latex.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ def _append_section_title(self, tag: Tag) -> str:
286286
if self.config.edition.text_uid == "sn":
287287
_heading_depth -= 1
288288
# if not _heading_depth:
289-
# return ""
289+
# return ""
290290

291291
if self.sutta_depth == 2:
292292
index = _heading_depth
@@ -557,7 +557,12 @@ def _get_individual_template(self, volume: Volume) -> Template | None:
557557
log.warning(f"Template '{_template_name}' for publication/volume specific configuration not found.")
558558
return None
559559

560-
def _get_cover_template(self, name: str, finalize: Callable[[Any], str] = None, template_dir: str = "") -> Template:
560+
def _get_cover_template(
561+
self,
562+
name: str,
563+
finalize: Callable[[Any], str] | None = None,
564+
template_dir: str = "",
565+
) -> Template:
561566

562567
_subdir = LatexParser.COVER_TEMPLATES_SUBDIR
563568

sutta_publisher/src/sutta_publisher/shared/config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import logging
44

5-
import requests
5+
import requests # type: ignore[import-untyped]
66
from pydantic import ValidationError
77

88
from sutta_publisher.shared import API_ENDPOINTS, API_URL, CREATOR_BIOS_URL

sutta_publisher/src/sutta_publisher/shared/data.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from typing import NoReturn
44

5-
import requests
5+
import requests # type: ignore[import-untyped]
66

77
from sutta_publisher.shared import API_ENDPOINTS, API_URL, SUPER_TREE_URL, TREE_URL
88
from sutta_publisher.shared.value_objects.edition_config import EditionConfig, Volumes

sutta_publisher/src/sutta_publisher/shared/edition_finder.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from requests import Response
1+
from requests import Response # type: ignore[import-untyped]
22

33
from sutta_publisher.shared import EDITION_FINDER_PATTERNS, LAST_RUN_DATE_FILE_URL, SCDATA_REPO_URL, SUPER_TREE_URL
44
from sutta_publisher.shared.github_handler import get_last_commit_sha, get_modified_filenames, worker

sutta_publisher/src/sutta_publisher/shared/github_handler.py

Lines changed: 44 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@
66
from datetime import datetime
77
from pathlib import Path
88
from time import sleep
9+
from typing import Optional
910

10-
import requests
11-
from requests import Response
11+
import requests # type: ignore[import-untyped]
12+
from requests import Response # type: ignore[import-untyped]
1213

1314
from sutta_publisher.shared import EDITIONS_REPO_URL, LAST_RUN_DATE_FILE_URL
1415
from sutta_publisher.shared.value_objects.edition import EditionResult
@@ -19,7 +20,7 @@
1920
ERROR_SLEEP_TIME = 1 # in seconds
2021

2122

22-
def worker(queue: list[dict], api_key: str = None, silent: bool = False) -> list[Response]:
23+
def worker(queue: list[dict], api_key: Optional[str] = None, silent: bool = False) -> list[Response]:
2324

2425
_queue: list[tuple[int, dict]] = [(_i, _t) for _i, _t in enumerate(queue)]
2526
errors = 0
@@ -62,15 +63,37 @@ def worker(queue: list[dict], api_key: str = None, silent: bool = False) -> list
6263

6364
def get_last_commit_sha(repo_url: str, api_key: str, branch: str) -> str:
6465
"""Get SHA of the last commit"""
66+
last_commit_sha, _ = get_last_commit_and_tree_sha(repo_url=repo_url, api_key=api_key, branch=branch)
67+
return last_commit_sha
68+
69+
70+
def get_last_commit_and_tree_sha(repo_url: str, api_key: str, branch: str) -> tuple[str, str]:
71+
"""Get SHAs of the last commit and its tree."""
6572
_request = {
6673
"method": "get",
6774
"url": f"{repo_url}/branches/{branch}",
6875
"help_text": "get last commit sha",
6976
}
7077
_response: Response = worker(queue=[_request], api_key=api_key)[0]
7178

72-
sha: str = _response.json()["commit"]["sha"]
73-
return sha
79+
_response_data = _response.json()
80+
_commit = _response_data.get("commit")
81+
if not isinstance(_commit, dict):
82+
raise ValueError(f"Unexpected GitHub response for branch '{branch}': missing 'commit' object.")
83+
84+
commit_sha = _commit.get("sha")
85+
_nested_commit = _commit.get("commit")
86+
if not isinstance(_nested_commit, dict):
87+
raise ValueError(f"Unexpected GitHub response for branch '{branch}': missing nested 'commit' object.")
88+
89+
_tree = _nested_commit.get("tree")
90+
if not isinstance(_tree, dict):
91+
raise ValueError(f"Unexpected GitHub response for branch '{branch}': missing 'tree' object.")
92+
93+
tree_sha = _tree.get("sha")
94+
if not commit_sha or not tree_sha:
95+
raise ValueError(f"Unexpected GitHub response for branch '{branch}': missing commit SHA or tree SHA.")
96+
return commit_sha, tree_sha
7497

7598

7699
def get_blob_shas(file_paths: list[Path], repo_url: str, api_key: str) -> list[str]:
@@ -129,46 +152,27 @@ def get_old_files_shas(file_paths: list[Path], repo_url: str, repo_path: str, ap
129152

130153
def create_new_tree(
131154
file_paths: list[Path],
132-
repo_url: str,
133155
repo_path: str,
134-
api_key: str,
135-
last_commit_sha: str,
136156
blob_shas: list[str],
137-
old_files_shas: list[str],
138157
) -> list[dict]:
139-
"""Create new Git tree with updated files"""
140-
_request = {
141-
"method": "get",
142-
"url": f"{repo_url}/git/trees/{last_commit_sha}?recursive=1",
143-
"help_text": "create new tree",
144-
}
145-
_responses: list[Response] = worker(queue=[_request], api_key=api_key, silent=True)
146-
147-
_old_tree = _responses[0].json().get("tree", []) if _responses else []
148-
149-
new_tree: list[dict] = [
150-
_item for _item in _old_tree if _item.get("type") == "blob" and not _item.get("sha") in old_files_shas
158+
"""Create incremental Git tree entries with updated files only."""
159+
return [
160+
{
161+
"path": f"{repo_path}{'/' if repo_path else ''}{_file.name}",
162+
"mode": "100644",
163+
"type": "blob",
164+
"sha": _sha,
165+
}
166+
for _file, _sha in zip(file_paths, blob_shas)
151167
]
152-
new_tree.extend(
153-
[
154-
{
155-
"path": f"{repo_path}{'/' if repo_path else ''}{_file.name}",
156-
"mode": "100644",
157-
"type": "blob",
158-
"sha": _sha,
159-
}
160-
for _file, _sha in zip(file_paths, blob_shas)
161-
]
162-
)
163-
return new_tree
164168

165169

166-
def get_tree_sha(repo_url: str, api_key: str, tree: list[dict]) -> str:
167-
"""Post a new tree and return its SHA"""
170+
def get_tree_sha(repo_url: str, api_key: str, tree: list[dict], base_tree_sha: str) -> str:
171+
"""Post a new tree on top of base tree and return its SHA."""
168172
_request = {
169173
"method": "post",
170174
"url": f"{repo_url}/git/trees",
171-
"body": json.dumps({"tree": tree}),
175+
"body": json.dumps({"base_tree": base_tree_sha, "tree": tree}),
172176
"help_text": "create new tree",
173177
}
174178
_response: Response = worker(queue=[_request], api_key=api_key)[0]
@@ -217,20 +221,16 @@ def update_head(repo_url: str, api_key: str, new_commit_sha: str) -> None:
217221

218222

219223
def upload_files_to_repo(
220-
file_paths: list[Path], repo_url: str, repo_path: str, api_key: str, edition: EditionResult = None
224+
file_paths: list[Path], repo_url: str, repo_path: str, api_key: str, edition: Optional[EditionResult] = None
221225
) -> None:
222226

223-
last_commit_sha: str = get_last_commit_sha(repo_url, api_key, "main")
227+
last_commit_sha, base_tree_sha = get_last_commit_and_tree_sha(repo_url=repo_url, api_key=api_key, branch="main")
224228

225229
blob_shas: list[str] = get_blob_shas(file_paths, repo_url, api_key)
226230

227-
old_files_shas: list[str] = get_old_files_shas(file_paths, repo_url, repo_path, api_key)
228-
229-
new_tree: list[dict] = create_new_tree(
230-
file_paths, repo_url, repo_path, api_key, last_commit_sha, blob_shas, old_files_shas
231-
)
231+
new_tree: list[dict] = create_new_tree(file_paths=file_paths, repo_path=repo_path, blob_shas=blob_shas)
232232

233-
tree_sha: str = get_tree_sha(repo_url, api_key, new_tree)
233+
tree_sha: str = get_tree_sha(repo_url=repo_url, api_key=api_key, tree=new_tree, base_tree_sha=base_tree_sha)
234234

235235
new_commit_sha: str = get_new_commit_sha(edition, file_paths, repo_url, api_key, last_commit_sha, tree_sha)
236236

0 commit comments

Comments
 (0)