GitHub Action commited on
Commit
5ebd50e
·
1 Parent(s): 1d0d2aa

Sync from GitHub with Git LFS

Browse files
Files changed (1) hide show
  1. scripts/publish_to_blogger.py +103 -42
scripts/publish_to_blogger.py CHANGED
@@ -1,57 +1,118 @@
1
- import json
2
  import os
 
 
3
  import hashlib
4
  import markdown2
5
- # from googleapiclient.discovery import build
6
- # from google.oauth2.credentials import Credentials
7
- # from googleapiclient.errors import HttpError
8
  import pickle
9
- import sys
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
 
11
- # Файлы — всегда в корне репозитория
12
- JSON_FILE = os.path.join(os.getcwd(), "published_posts.json")
13
-
14
- # Загружаем список опубликованных постов
15
- if os.path.exists(JSON_FILE):
16
- try:
17
- with open(JSON_FILE, 'r', encoding='utf-8') as f:
18
- published = json.load(f)
19
- print(f"✅ Загружен список опубликованных постов: {list(published.keys())}")
20
- print(f"Содержимое JSON при загрузке:\n{json.dumps(published, ensure_ascii=False, indent=2)}")
21
- except json.JSONDecodeError:
22
- print("⚠ published_posts.json пустой или поврежден — начинаем с нуля.")
 
 
 
 
 
 
 
 
23
  published = {}
24
- else:
25
- published = {}
26
- print("⚠ published_posts.json не найден — начинаем с нуля.")
27
 
28
- # Обход markdown файлов
29
- for root, _, files in os.walk("docs"):
30
- for filename in files:
31
- if not filename.endswith(".md"):
32
- continue
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
 
34
- path = os.path.join(root, filename)
35
- title = os.path.splitext(filename)[0]
 
 
 
36
 
37
- with open(path, 'r', encoding='utf-8') as f:
38
- md_content = f.read()
 
 
 
 
 
 
 
39
 
40
- content_hash = hashlib.md5(md_content.encode('utf-8')).hexdigest()
 
 
 
 
 
 
 
 
 
 
 
 
 
41
 
42
- if title in published and published[title]['hash'] == content_hash:
43
- print(f"⏭ Без изменений: {title}")
44
- continue
45
 
46
- # В отладочном режиме пропускаем публикацию в Blogger
47
- print(f"📝 Новый или изменённый пост: {title}")
48
- published[title] = {"id": "DUMMY_ID", "hash": content_hash}
49
 
50
- # Логируем JSON перед записью
51
- print(f"Содержимое JSON перед записью:\n{json.dumps(published, ensure_ascii=False, indent=2)}")
 
 
 
 
52
 
53
- # Сохраняем JSON (можно оставить)
54
- with open(JSON_FILE, 'w', encoding='utf-8') as f:
55
- json.dump(published, f, ensure_ascii=False, indent=2)
56
 
57
- print("✅ Скрипт завершён в отладочном режиме (публикация отключена).")
 
 
 
 
 
1
  import os
2
+ import sys
3
+ import json
4
  import hashlib
5
  import markdown2
 
 
 
6
  import pickle
7
+ import time
8
+ from googleapiclient.discovery import build
9
+ from googleapiclient.errors import HttpError
10
+
11
+ # Настройки
12
+ SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
13
+ JSON_FILE = os.path.abspath(os.path.join(SCRIPT_DIR, "..", "published_posts.json"))
14
+ LOCK_FILE = os.path.abspath(os.path.join(SCRIPT_DIR, "publish.lock"))
15
+
16
+ # Блокировка, чтобы скрипт не запускался дважды
17
+ if os.path.exists(LOCK_FILE):
18
+ print("⚠ Скрипт уже запущен — выходим.")
19
+ sys.exit(0)
20
+
21
+ with open(LOCK_FILE, "w") as f:
22
+ f.write("locked")
23
 
24
+ try:
25
+ # Загружаем токен
26
+ TOKEN_FILE = os.environ.get('TOKEN_FILE', 'token.pkl')
27
+ with open(TOKEN_FILE, 'rb') as f:
28
+ creds = pickle.load(f)
29
+
30
+ service = build('blogger', 'v3', credentials=creds)
31
+ BLOG_ID = os.environ['BLOG_ID']
32
+
33
+ # Загружаем список опубликованных постов
34
+ if os.path.exists(JSON_FILE):
35
+ try:
36
+ with open(JSON_FILE, 'r', encoding='utf-8') as f:
37
+ published = json.load(f)
38
+ print(f"✅ Загружен список опубликованных постов: {list(published.keys())}")
39
+ except json.JSONDecodeError:
40
+ print("⚠ published_posts.json пустой или поврежден — начинаем с нуля.")
41
+ published = {}
42
+ else:
43
+ print("⚠ published_posts.json не найден — начинаем с нуля.")
44
  published = {}
 
 
 
45
 
46
+ # Обходим markdown-файлы
47
+ for root, _, files in os.walk("docs"):
48
+ for filename in files:
49
+ if not filename.endswith(".md"):
50
+ continue
51
+
52
+ path = os.path.join(root, filename)
53
+ title = os.path.splitext(filename)[0]
54
+
55
+ with open(path, 'r', encoding='utf-8') as f:
56
+ md_content = f.read()
57
+
58
+ html_content = markdown2.markdown(md_content)
59
+ content_hash = hashlib.md5(md_content.encode('utf-8')).hexdigest()
60
+
61
+ # Пропускаем если ничего не изменилось
62
+ if title in published and published[title]['hash'] == content_hash:
63
+ continue
64
+
65
+ print(f"📝 Новый или изменённый пост: {title}")
66
 
67
+ post = {
68
+ "kind": "blogger#post",
69
+ "title": title,
70
+ "content": html_content
71
+ }
72
 
73
+ try:
74
+ # Если отладка — просто обновляем JSON
75
+ if os.environ.get('DEBUG_PUBLISH', '0') == '1':
76
+ post_id = published.get(title, {}).get("id", "DUMMY_ID")
77
+ published[title] = {"id": post_id, "hash": content_hash}
78
+ print("✅ Скрипт завершён в отладочном режиме (публикация отключена).")
79
+ with open(JSON_FILE, 'w', encoding='utf-8') as f:
80
+ json.dump(published, f, ensure_ascii=False, indent=2)
81
+ sys.exit(0)
82
 
83
+ # Публикуем новый или обновляем существующий
84
+ if title in published:
85
+ post_id = published[title]['id']
86
+ updated_post = service.posts().update(
87
+ blogId=BLOG_ID, postId=post_id, body=post
88
+ ).execute()
89
+ print(f"♻️ Пост обновлён: {updated_post['url']}")
90
+ published[title] = {"id": post_id, "hash": content_hash}
91
+ else:
92
+ new_post = service.posts().insert(
93
+ blogId=BLOG_ID, body=post, isDraft=False
94
+ ).execute()
95
+ print(f"🆕 Пост опубликован: {new_post['url']}")
96
+ published[title] = {"id": new_post['id'], "hash": content_hash}
97
 
98
+ # Сохраняем прогресс
99
+ with open(JSON_FILE, 'w', encoding='utf-8') as f:
100
+ json.dump(published, f, ensure_ascii=False, indent=2)
101
 
102
+ # Публикуем только один пост за запуск
103
+ print(" Завершаем выполнение после одного поста.")
104
+ sys.exit(0)
105
 
106
+ except HttpError as e:
107
+ if e.resp.status == 403 and "quotaExceeded" in str(e):
108
+ print("⚠ Достигнут лимит Blogger API. Попробуйте снова позже.")
109
+ sys.exit(1)
110
+ else:
111
+ raise
112
 
113
+ print("🎉 Все посты уже актуальны новых публикаций нет.")
 
 
114
 
115
+ finally:
116
+ # Удаляем блокировку
117
+ if os.path.exists(LOCK_FILE):
118
+ os.remove(LOCK_FILE)