55from enum import Enum
66
77# readme url
8- URL = "https://api.readme.com/v2/branches/stable"
8+ BRANCH = "stable"
9+ URL = f"https://api.readme.com/v2/branches/{ BRANCH } "
910CATEGORY_SLUG = "JSON-RPC"
11+ NOTIFICATIONS_CATEGORY_SLUG = "Notifications"
12+ HOOKS_CATEGORY_SLUG = "Hooks"
1013
1114
1215class Action (Enum ):
@@ -15,8 +18,8 @@ class Action(Enum):
1518 DELETE = 'delete'
1619
1720
18- def getListOfRPCDocs (headers ):
19- response = requests .get (f"{ URL } /categories/reference/{ CATEGORY_SLUG } /pages" , headers = headers )
21+ def getListOfDocs (headers , category ):
22+ response = requests .get (f"{ URL } /categories/reference/{ category } /pages" , headers = headers )
2023 if response .status_code == 200 :
2124 return response .json ().get ('data' , [])
2225 else :
@@ -47,15 +50,15 @@ def check_renderable(response, action, title):
4750 return True
4851
4952
50- def publishDoc (action , title , body , position , headers ):
53+ def publishDoc (action , title , body , position , headers , category ):
5154 payload = {
52- "title" : title ,
55+ "title" : get_display_name ( title ) ,
5356 "type" : "basic" ,
5457 "content" : {
5558 "body" : body ,
5659 },
5760 "category" : {
58- "uri" : f"/branches/stable /categories/reference/{ CATEGORY_SLUG } "
61+ "uri" : f"/branches/{ BRANCH } /categories/reference/{ category } "
5962 },
6063 "hidden" : False ,
6164 "position" : position ,
@@ -99,18 +102,78 @@ def publishDoc(action, title, body, position, headers):
99102 print ("Invalid action" )
100103
101104
102- def extract_rpc_commands (rst_content ):
105+ def extract_all_from_rst (rst_content ):
103106 manpages_block = re .search (
104- r"\.\. block_start manpages(.*?)" r" \.\. block_end manpages" ,
107+ r"\.\. block_start manpages(.*?)\.\. block_end manpages" ,
105108 rst_content ,
106109 re .DOTALL ,
107110 )
108- if manpages_block :
109- commands = re .findall (
110- r"\b([a-zA-Z0-9_-]+)" r"\s+<([^>]+)>\n" , manpages_block .group (1 )
111- )
112- return commands
113- return []
111+
112+ if not manpages_block :
113+ return [], [], []
114+
115+ entries = re .findall (
116+ r"^\s*([a-zA-Z0-9_-]+)\s+<([^>]+)>" ,
117+ manpages_block .group (1 ),
118+ re .MULTILINE ,
119+ )
120+
121+ rpc_commands = []
122+ notifications = []
123+ hooks = []
124+
125+ for name , target in entries :
126+ if name .startswith ("notification-" ):
127+ notifications .append ((name , target ))
128+ elif name .startswith ("hook-" ):
129+ hooks .append ((name , target ))
130+ else :
131+ rpc_commands .append ((name , target ))
132+
133+ return rpc_commands , notifications , hooks
134+
135+
136+ def sync_docs (local_items , readme_items , category_slug , headers , label ):
137+ local_titles = {name for name , _ in local_items }
138+ readme_titles = {item ['slug' ] for item in readme_items }
139+
140+ to_delete = readme_titles - local_titles
141+ to_add = local_titles - readme_titles
142+
143+ # Deletions
144+ for name in to_delete :
145+ publishDoc (Action .DELETE , name , "" , 0 , headers , category_slug )
146+ sleep (1 )
147+
148+ # Add / Update
149+ if not local_items :
150+ print (f"⚠️ No { label } found in the Manpages block." )
151+ return
152+
153+ position = 0
154+ for name , file in local_items :
155+ file_path = os .path .join ("doc" , file )
156+
157+ if not os .path .exists (file_path ):
158+ print (f"⚠️ WARNING: File not found: { file_path } , skipping { name } " )
159+ continue
160+
161+ with open (file_path ) as f :
162+ body = f .read ()
163+
164+ action = Action .ADD if name in to_add else Action .UPDATE
165+ publishDoc (action , name , body , position , headers , category_slug )
166+
167+ position += 1
168+ sleep (1 )
169+
170+
171+ def get_display_name (name ):
172+ if name .startswith ("notification-" ):
173+ return name [len ("notification-" ):]
174+ if name .startswith ("hook-" ):
175+ return name [len ("hook-" ):]
176+ return name
114177
115178
116179def main ():
@@ -136,34 +199,34 @@ def main():
136199 with open (path_to_rst , "r" ) as file :
137200 rst_content = file .read ()
138201
139- commands_from_local = extract_rpc_commands (rst_content )
140- commands_from_readme = getListOfRPCDocs (headers )
202+ commands_from_local , notifications_from_local , hooks_from_local = extract_all_from_rst (rst_content )
203+ commands_from_readme = getListOfDocs (headers , CATEGORY_SLUG )
204+ notifications_from_readme = getListOfDocs (headers , NOTIFICATIONS_CATEGORY_SLUG )
205+ hooks_from_readme = getListOfDocs (headers , HOOKS_CATEGORY_SLUG )
206+
207+ sync_docs (
208+ commands_from_local ,
209+ commands_from_readme ,
210+ CATEGORY_SLUG ,
211+ headers ,
212+ "commands"
213+ )
141214
142- # Compare local and server commands list to get the list of command to add or delete
143- commands_local_title = set (command [0 ] for command in commands_from_local )
144- commands_readme_title = set (command ['slug' ] for command in commands_from_readme )
145- commands_to_delete = commands_readme_title - commands_local_title
146- commands_to_add = commands_local_title - commands_readme_title
147- for name in commands_to_delete :
148- publishDoc (Action .DELETE , name , "" , 0 , headers )
149- sleep (1 )
215+ sync_docs (
216+ notifications_from_local ,
217+ notifications_from_readme ,
218+ NOTIFICATIONS_CATEGORY_SLUG ,
219+ headers ,
220+ "notifications"
221+ )
150222
151- if commands_from_local :
152- position = 0
153- for name , file in commands_from_local :
154- file_path = "doc/" + file
155- if not os .path .exists (file_path ):
156- print (f"⚠️ WARNING: File not found: { file_path } , skipping { name } " )
157- continue
158-
159- with open (file_path ) as f :
160- body = f .read ()
161- action = Action .ADD if name in commands_to_add else Action .UPDATE
162- publishDoc (action , name , body , position , headers )
163- position += 1
164- sleep (1 )
165- else :
166- print ("⚠️ No commands found in the Manpages block." )
223+ sync_docs (
224+ hooks_from_local ,
225+ hooks_from_readme ,
226+ HOOKS_CATEGORY_SLUG ,
227+ headers ,
228+ "hooks"
229+ )
167230
168231 print ("\n ✨ Sync complete!" )
169232
0 commit comments