GitHub Action commited on
Commit ·
fb4c2c7
1
Parent(s): 16c2760
Sync from GitHub with Git LFS
Browse files- scripts/publish_to_blogger.py +37 -16
scripts/publish_to_blogger.py
CHANGED
|
@@ -20,19 +20,14 @@ GH_PAGES_BASE = "https://kagvi13.github.io/HMP/"
|
|
| 20 |
|
| 21 |
|
| 22 |
def convert_md_links(md_text: str) -> str:
|
| 23 |
-
"""
|
| 24 |
-
Конвертирует относительные ссылки (*.md) в абсолютные ссылки на GitHub Pages.
|
| 25 |
-
"""
|
| 26 |
def replacer(match):
|
| 27 |
text = match.group(1)
|
| 28 |
link = match.group(2)
|
| 29 |
-
|
| 30 |
if link.startswith("http://") or link.startswith("https://") or not link.endswith(".md"):
|
| 31 |
return match.group(0)
|
| 32 |
-
|
| 33 |
abs_link = GH_PAGES_BASE + link.replace(".md", "").lstrip("./")
|
| 34 |
return f"[{text}]({abs_link})"
|
| 35 |
-
|
| 36 |
return re.sub(r"\[([^\]]+)\]\(([^)]+)\)", replacer, md_text)
|
| 37 |
|
| 38 |
|
|
@@ -53,8 +48,28 @@ def file_hash(path):
|
|
| 53 |
return hashlib.md5(Path(path).read_bytes()).hexdigest()
|
| 54 |
|
| 55 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 56 |
def main(force: bool = False):
|
| 57 |
-
# Загружаем токен.json
|
| 58 |
creds = None
|
| 59 |
if os.path.exists(TOKEN_FILE):
|
| 60 |
creds = Credentials.from_authorized_user_file(TOKEN_FILE, ["https://www.googleapis.com/auth/blogger"])
|
|
@@ -66,6 +81,7 @@ def main(force: bool = False):
|
|
| 66 |
|
| 67 |
service = build("blogger", "v3", credentials=creds)
|
| 68 |
published = load_published()
|
|
|
|
| 69 |
|
| 70 |
md_files = list(Path("docs").rglob("*.md"))
|
| 71 |
for md_file in md_files:
|
|
@@ -78,20 +94,15 @@ def main(force: bool = False):
|
|
| 78 |
print(f"📝 {'Форс-обновление' if force else 'Новый или изменённый'} пост: {name}")
|
| 79 |
|
| 80 |
md_text = md_file.read_text(encoding="utf-8")
|
| 81 |
-
|
| 82 |
-
# Добавляем ссылку на исходный файл в начале
|
| 83 |
source_link = f"Источник: [ {md_file.name} ](https://github.com/kagvi13/HMP/blob/main/docs/{md_file.name})\n\n"
|
| 84 |
md_text = source_link + md_text
|
| 85 |
-
|
| 86 |
md_text = convert_md_links(md_text)
|
| 87 |
|
| 88 |
-
# Конвертация Markdown в HTML с расширениями
|
| 89 |
html_content = markdown.markdown(
|
| 90 |
md_text,
|
| 91 |
extensions=["tables", "fenced_code", "codehilite", "toc"]
|
| 92 |
)
|
| 93 |
|
| 94 |
-
# Добавляем CSS для корректного отображения таблиц и блок-схем
|
| 95 |
style = """
|
| 96 |
<style>
|
| 97 |
table { display: block; max-width: 100%; overflow-x: auto; border-collapse: collapse; }
|
|
@@ -108,10 +119,20 @@ def main(force: bool = False):
|
|
| 108 |
}
|
| 109 |
|
| 110 |
try:
|
| 111 |
-
if name in
|
| 112 |
-
|
| 113 |
-
|
| 114 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 115 |
else:
|
| 116 |
post = service.posts().insert(blogId=BLOG_ID, body=body).execute()
|
| 117 |
print(f"🆕 Пост опубликован: {post['url']}")
|
|
|
|
| 20 |
|
| 21 |
|
| 22 |
def convert_md_links(md_text: str) -> str:
|
| 23 |
+
"""Конвертирует относительные ссылки (*.md) в абсолютные ссылки на GitHub Pages."""
|
|
|
|
|
|
|
| 24 |
def replacer(match):
|
| 25 |
text = match.group(1)
|
| 26 |
link = match.group(2)
|
|
|
|
| 27 |
if link.startswith("http://") or link.startswith("https://") or not link.endswith(".md"):
|
| 28 |
return match.group(0)
|
|
|
|
| 29 |
abs_link = GH_PAGES_BASE + link.replace(".md", "").lstrip("./")
|
| 30 |
return f"[{text}]({abs_link})"
|
|
|
|
| 31 |
return re.sub(r"\[([^\]]+)\]\(([^)]+)\)", replacer, md_text)
|
| 32 |
|
| 33 |
|
|
|
|
| 48 |
return hashlib.md5(Path(path).read_bytes()).hexdigest()
|
| 49 |
|
| 50 |
|
| 51 |
+
def get_existing_posts(service):
|
| 52 |
+
"""Возвращает словарь title → post_id для постов, которые можно редактировать."""
|
| 53 |
+
existing = {}
|
| 54 |
+
nextPageToken = None
|
| 55 |
+
while True:
|
| 56 |
+
try:
|
| 57 |
+
response = service.posts().list(blogId=BLOG_ID, maxResults=500, pageToken=nextPageToken).execute()
|
| 58 |
+
for post in response.get("items", []):
|
| 59 |
+
# Проверяем наличие доступа на редактирование
|
| 60 |
+
post_id = post["id"]
|
| 61 |
+
title = post["title"]
|
| 62 |
+
existing[title] = post_id
|
| 63 |
+
nextPageToken = response.get("nextPageToken")
|
| 64 |
+
if not nextPageToken:
|
| 65 |
+
break
|
| 66 |
+
except HttpError as e:
|
| 67 |
+
print(f"❌ Ошибка при получении списка постов: {e}")
|
| 68 |
+
break
|
| 69 |
+
return existing
|
| 70 |
+
|
| 71 |
+
|
| 72 |
def main(force: bool = False):
|
|
|
|
| 73 |
creds = None
|
| 74 |
if os.path.exists(TOKEN_FILE):
|
| 75 |
creds = Credentials.from_authorized_user_file(TOKEN_FILE, ["https://www.googleapis.com/auth/blogger"])
|
|
|
|
| 81 |
|
| 82 |
service = build("blogger", "v3", credentials=creds)
|
| 83 |
published = load_published()
|
| 84 |
+
existing_posts = get_existing_posts(service)
|
| 85 |
|
| 86 |
md_files = list(Path("docs").rglob("*.md"))
|
| 87 |
for md_file in md_files:
|
|
|
|
| 94 |
print(f"📝 {'Форс-обновление' if force else 'Новый или изменённый'} пост: {name}")
|
| 95 |
|
| 96 |
md_text = md_file.read_text(encoding="utf-8")
|
|
|
|
|
|
|
| 97 |
source_link = f"Источник: [ {md_file.name} ](https://github.com/kagvi13/HMP/blob/main/docs/{md_file.name})\n\n"
|
| 98 |
md_text = source_link + md_text
|
|
|
|
| 99 |
md_text = convert_md_links(md_text)
|
| 100 |
|
|
|
|
| 101 |
html_content = markdown.markdown(
|
| 102 |
md_text,
|
| 103 |
extensions=["tables", "fenced_code", "codehilite", "toc"]
|
| 104 |
)
|
| 105 |
|
|
|
|
| 106 |
style = """
|
| 107 |
<style>
|
| 108 |
table { display: block; max-width: 100%; overflow-x: auto; border-collapse: collapse; }
|
|
|
|
| 119 |
}
|
| 120 |
|
| 121 |
try:
|
| 122 |
+
if name in existing_posts:
|
| 123 |
+
# Пытаемся обновить
|
| 124 |
+
try:
|
| 125 |
+
post_id = existing_posts[name]
|
| 126 |
+
post = service.posts().update(blogId=BLOG_ID, postId=post_id, body=body).execute()
|
| 127 |
+
print(f"♻ Обновлён пост: {post['url']}")
|
| 128 |
+
except HttpError as e:
|
| 129 |
+
if e.resp.status == 403:
|
| 130 |
+
# Нет прав на обновление → создаём новый пост
|
| 131 |
+
post = service.posts().insert(blogId=BLOG_ID, body=body).execute()
|
| 132 |
+
print(f"⚠ Пост существовал, но права нет. Создан новый: {post['url']}")
|
| 133 |
+
post_id = post["id"]
|
| 134 |
+
else:
|
| 135 |
+
raise e
|
| 136 |
else:
|
| 137 |
post = service.posts().insert(blogId=BLOG_ID, body=body).execute()
|
| 138 |
print(f"🆕 Пост опубликован: {post['url']}")
|