GitHub Action commited on
Commit
2c5aea5
·
1 Parent(s): 1595318

Sync from GitHub with Git LFS

Browse files
Files changed (1) hide show
  1. scripts/publish_to_hashnode.py +28 -11
scripts/publish_to_hashnode.py CHANGED
@@ -14,7 +14,9 @@ HASHNODE_TOKEN = os.environ["HASHNODE_TOKEN"]
14
  HASHNODE_PUBLICATION_ID = os.environ["HASHNODE_PUBLICATION_ID"]
15
  API_URL = "https://gql.hashnode.com"
16
 
 
17
  def convert_md_links(md_text: str) -> str:
 
18
  def replacer(match):
19
  text, link = match.groups()
20
  if link.startswith("http://") or link.startswith("https://") or not link.endswith(".md"):
@@ -23,19 +25,23 @@ def convert_md_links(md_text: str) -> str:
23
  return f"[{text}]({abs_link})"
24
  return re.sub(r"\[([^\]]+)\]\(([^)]+)\)", replacer, md_text)
25
 
 
26
  def load_published():
27
  if Path(PUBLISHED_FILE).exists():
28
  with open(PUBLISHED_FILE, "r", encoding="utf-8") as f:
29
  return json.load(f)
30
  return {}
31
 
 
32
  def save_published(data):
33
  with open(PUBLISHED_FILE, "w", encoding="utf-8") as f:
34
  json.dump(data, f, ensure_ascii=False, indent=2)
35
 
 
36
  def file_hash(md_text: str):
37
  return hashlib.md5(md_text.encode("utf-8")).hexdigest()
38
 
 
39
  def graphql_request(query, variables):
40
  headers = {"Authorization": f"Bearer {HASHNODE_TOKEN}", "Content-Type": "application/json"}
41
  resp = requests.post(API_URL, json={"query": query, "variables": variables}, headers=headers)
@@ -44,24 +50,29 @@ def graphql_request(query, variables):
44
  raise Exception(f"GraphQL errors: {data['errors']}")
45
  return data
46
 
 
47
  def create_post(title, slug, markdown_content):
48
  query = """
49
  mutation CreateDraft($input: CreateDraftInput!) {
50
- createDraft(input: $input) {
51
- draft { id slug title }
52
- }
53
  }
54
  """
55
- variables = {"input": {"title": title, "contentMarkdown": markdown_content,
56
- "slug": slug, "publicationId": HASHNODE_PUBLICATION_ID}}
 
 
 
 
 
 
57
  return graphql_request(query, variables)["data"]["createDraft"]["draft"]
58
 
 
59
  def update_post(draft_id, title, markdown_content):
 
60
  query = """
61
  mutation UpdateDraft($input: UpdateDraftInput!) {
62
- updateDraft(input: $input) {
63
- draft { id slug title }
64
- }
65
  }
66
  """
67
  variables = {
@@ -83,6 +94,7 @@ def publish_draft(draft_id):
83
  variables = {"input": {"draftId": draft_id}}
84
  return graphql_request(query, variables)["data"]["publishDraft"]["post"]
85
 
 
86
  def main(force=False):
87
  published = load_published()
88
  md_files = list(Path("docs").rglob("*.md"))
@@ -92,7 +104,8 @@ def main(force=False):
92
  title = name if len(name) >= 6 else name + "-HMP"
93
  slug = re.sub(r'[^a-z0-9-]', '-', title.lower()).strip('-')[:250]
94
 
95
- md_text = f"Источник: [ {md_file.name} ](https://github.com/kagvi13/HMP/blob/main/docs/{md_file.name})\n\n" + md_file.read_text(encoding="utf-8")
 
96
  md_text = convert_md_links(md_text)
97
  h = file_hash(md_text)
98
 
@@ -102,15 +115,18 @@ def main(force=False):
102
 
103
  try:
104
  if name in published and "id" in published[name]:
105
- update_post(published[name]["id"], title, md_text)
106
  print(f"♻ Обновлён пост: https://hashnode.com/@yourusername/{post['slug']}")
107
  else:
108
  draft = create_post(title, slug, md_text)
109
  post = publish_draft(draft["id"])
110
  print(f"🆕 Пост опубликован: https://hashnode.com/@yourusername/{post['slug']}")
111
 
 
112
  published[name] = {"id": post["id"], "slug": post["slug"], "hash": h}
113
  save_published(published)
 
 
114
  time.sleep(30)
115
 
116
  except Exception as e:
@@ -118,9 +134,10 @@ def main(force=False):
118
  save_published(published)
119
  break
120
 
 
121
  if __name__ == "__main__":
122
  import argparse
123
  parser = argparse.ArgumentParser()
124
- parser.add_argument("--force", action="store_true")
125
  args = parser.parse_args()
126
  main(force=args.force)
 
14
  HASHNODE_PUBLICATION_ID = os.environ["HASHNODE_PUBLICATION_ID"]
15
  API_URL = "https://gql.hashnode.com"
16
 
17
+
18
  def convert_md_links(md_text: str) -> str:
19
+ """Конвертирует относительные ссылки (*.md) в абсолютные ссылки на GitHub Pages."""
20
  def replacer(match):
21
  text, link = match.groups()
22
  if link.startswith("http://") or link.startswith("https://") or not link.endswith(".md"):
 
25
  return f"[{text}]({abs_link})"
26
  return re.sub(r"\[([^\]]+)\]\(([^)]+)\)", replacer, md_text)
27
 
28
+
29
  def load_published():
30
  if Path(PUBLISHED_FILE).exists():
31
  with open(PUBLISHED_FILE, "r", encoding="utf-8") as f:
32
  return json.load(f)
33
  return {}
34
 
35
+
36
  def save_published(data):
37
  with open(PUBLISHED_FILE, "w", encoding="utf-8") as f:
38
  json.dump(data, f, ensure_ascii=False, indent=2)
39
 
40
+
41
  def file_hash(md_text: str):
42
  return hashlib.md5(md_text.encode("utf-8")).hexdigest()
43
 
44
+
45
  def graphql_request(query, variables):
46
  headers = {"Authorization": f"Bearer {HASHNODE_TOKEN}", "Content-Type": "application/json"}
47
  resp = requests.post(API_URL, json={"query": query, "variables": variables}, headers=headers)
 
50
  raise Exception(f"GraphQL errors: {data['errors']}")
51
  return data
52
 
53
+
54
  def create_post(title, slug, markdown_content):
55
  query = """
56
  mutation CreateDraft($input: CreateDraftInput!) {
57
+ createDraft(input: $input) { draft { id slug title } }
 
 
58
  }
59
  """
60
+ variables = {
61
+ "input": {
62
+ "title": title,
63
+ "contentMarkdown": markdown_content,
64
+ "slug": slug,
65
+ "publicationId": HASHNODE_PUBLICATION_ID
66
+ }
67
+ }
68
  return graphql_request(query, variables)["data"]["createDraft"]["draft"]
69
 
70
+
71
  def update_post(draft_id, title, markdown_content):
72
+ """Используем draftId для обновления, чтобы соответствовать текущему API Hashnode."""
73
  query = """
74
  mutation UpdateDraft($input: UpdateDraftInput!) {
75
+ updateDraft(input: $input) { draft { id slug title } }
 
 
76
  }
77
  """
78
  variables = {
 
94
  variables = {"input": {"draftId": draft_id}}
95
  return graphql_request(query, variables)["data"]["publishDraft"]["post"]
96
 
97
+
98
  def main(force=False):
99
  published = load_published()
100
  md_files = list(Path("docs").rglob("*.md"))
 
104
  title = name if len(name) >= 6 else name + "-HMP"
105
  slug = re.sub(r'[^a-z0-9-]', '-', title.lower()).strip('-')[:250]
106
 
107
+ md_text = f"Источник: [ {md_file.name} ](https://github.com/kagvi13/HMP/blob/main/docs/{md_file.name})\n\n" \
108
+ + md_file.read_text(encoding="utf-8")
109
  md_text = convert_md_links(md_text)
110
  h = file_hash(md_text)
111
 
 
115
 
116
  try:
117
  if name in published and "id" in published[name]:
118
+ post = update_post(published[name]["id"], title, md_text)
119
  print(f"♻ Обновлён пост: https://hashnode.com/@yourusername/{post['slug']}")
120
  else:
121
  draft = create_post(title, slug, md_text)
122
  post = publish_draft(draft["id"])
123
  print(f"🆕 Пост опубликован: https://hashnode.com/@yourusername/{post['slug']}")
124
 
125
+ # Обновляем локальный JSON после публикации/обновления
126
  published[name] = {"id": post["id"], "slug": post["slug"], "hash": h}
127
  save_published(published)
128
+
129
+ print("⏱ Пауза 30 секунд перед следующим постом...")
130
  time.sleep(30)
131
 
132
  except Exception as e:
 
134
  save_published(published)
135
  break
136
 
137
+
138
  if __name__ == "__main__":
139
  import argparse
140
  parser = argparse.ArgumentParser()
141
+ parser.add_argument("--force", action="store_true", help="Обновить все посты, даже без изменений")
142
  args = parser.parse_args()
143
  main(force=args.force)