api.py 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443
  1. #! /usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. # vi:ts=4:et
  4. # Wekan API Python CLI, originally from here, where is more details:
  5. # https://github.com/wekan/wekan/wiki/New-card-with-Python3-and-REST-API
  6. # TODO:
  7. # addcustomfieldtoboard: There is error: Settings must be object. So adding does not work yet.
  8. try:
  9. # python 3
  10. from urllib.parse import urlencode
  11. except ImportError:
  12. # python 2
  13. from urllib import urlencode
  14. import json
  15. import requests
  16. import sys
  17. arguments = len(sys.argv) - 1
  18. syntax = """=== Wekan API Python CLI: Shows IDs for addcard ===
  19. # AUTHORID is USERID that writes card or custom field.
  20. If *nix: chmod +x api.py => ./api.py users
  21. Syntax:
  22. User API:
  23. python3 api.py user # Current user and list of current user boards
  24. python3 api.py boards USERID # Boards of USERID
  25. python3 api.py swimlanes BOARDID # Swimlanes of BOARDID
  26. python3 api.py lists BOARDID # Lists of BOARDID
  27. python3 api.py list BOARDID LISTID # Info of LISTID
  28. python3 api.py createlist BOARDID LISTTITLE # Create list
  29. python3 api.py addcard AUTHORID BOARDID SWIMLANEID LISTID CARDTITLE CARDDESCRIPTION
  30. python3 api.py editcard BOARDID LISTID CARDID NEWCARDTITLE NEWCARDDESCRIPTION
  31. python3 api.py customfields BOARDID # Custom Fields of BOARDID
  32. python3 api.py customfield BOARDID CUSTOMFIELDID # Info of CUSTOMFIELDID
  33. python3 api.py addcustomfieldtoboard AUTHORID BOARDID NAME TYPE SETTINGS SHOWONCARD AUTOMATICALLYONCARD SHOWLABELONMINICARD SHOWSUMATTOPOFLIST # Add Custom Field to Board
  34. python3 api.py editcustomfield BOARDID LISTID CARDID CUSTOMFIELDID NEWCUSTOMFIELDVALUE
  35. python3 api.py listattachments BOARDID # List attachments
  36. python3 api.py cardsbyswimlane BOARDID LISTID
  37. python3 api.py getcard BOARDID LISTID CARDID
  38. Admin API:
  39. python3 api.py users # All users
  40. python3 api.py boards # All Public Boards
  41. python3 api.py newuser USERNAME EMAIL PASSWORD
  42. """
  43. if arguments == 0:
  44. print(syntax)
  45. exit
  46. # TODO:
  47. # print(" python3 api.py attachmentjson BOARDID ATTACHMENTID # One attachment as JSON base64")
  48. # print(" python3 api.py attachmentbinary BOARDID ATTACHMENTID # One attachment as binary file")
  49. # print(" python3 api.py attachmentdownload BOARDID ATTACHMENTID # One attachment as file")
  50. # print(" python3 api.py attachmentsdownload BOARDID # All attachments as files")
  51. # ------- SETTINGS START -------------
  52. # Username is your Wekan username or email address.
  53. # OIDC/OAuth2 etc uses email address as username.
  54. username = 'testtest'
  55. password = 'testtest'
  56. wekanurl = 'http://localhost:4000/'
  57. # ------- SETTINGS END -------------
  58. """
  59. === ADD CUSTOM FIELD TO BOARD ===
  60. Type: text, number, date, dropdown, checkbox, currency, stringtemplate.
  61. python3 api.py addcustomfieldtoboard cmx3gmHLKwAXLqjxz LcDW4QdooAx8hsZh8 "SomeField" "date" "" true true true true
  62. === USERS ===
  63. python3 api.py users
  64. => abcd1234
  65. === BOARDS ===
  66. python3 api.py boards abcd1234
  67. === SWIMLANES ===
  68. python3 api.py swimlanes dYZ
  69. [{"_id":"Jiv","title":"Default"}
  70. ]
  71. === LISTS ===
  72. python3 api.py lists dYZ
  73. []
  74. There is no lists, so create a list:
  75. === CREATE LIST ===
  76. python3 api.py createlist dYZ 'Test'
  77. {"_id":"7Kp"}
  78. # python3 api.py addcard AUTHORID BOARDID SWIMLANEID LISTID CARDTITLE CARDDESCRIPTION
  79. python3 api.py addcard ppg dYZ Jiv 7Kp 'Test card' 'Test description'
  80. === LIST ATTACHMENTS WITH DOWNLOAD URLs ====
  81. python3 api.py listattachments BOARDID
  82. """
  83. # ------- API URL GENERATION START -----------
  84. loginurl = 'users/login'
  85. wekanloginurl = wekanurl + loginurl
  86. apiboards = 'api/boards/'
  87. apiattachments = 'api/attachments/'
  88. apiusers = 'api/users'
  89. apiuser = 'api/user'
  90. apiallusers = 'api/allusers'
  91. e = 'export'
  92. s = '/'
  93. l = 'lists'
  94. sw = 'swimlane'
  95. sws = 'swimlanes'
  96. cs = 'cards'
  97. cf = 'custom-fields'
  98. bs = 'boards'
  99. apbs = 'allpublicboards'
  100. atl = 'attachmentslist'
  101. at = 'attachment'
  102. ats = 'attachments'
  103. users = wekanurl + apiusers
  104. user = wekanurl + apiuser
  105. allusers = wekanurl + apiallusers
  106. # ------- API URL GENERATION END -----------
  107. # ------- LOGIN TOKEN START -----------
  108. data = {"username": username, "password": password}
  109. body = requests.post(wekanloginurl, json=data)
  110. d = body.json()
  111. apikey = d['token']
  112. # ------- LOGIN TOKEN END -----------
  113. if arguments == 10:
  114. if sys.argv[1] == 'addcustomfieldtoboard':
  115. # ------- ADD CUSTOM FIELD TO BOARD START -----------
  116. authorid = sys.argv[2]
  117. boardid = sys.argv[3]
  118. name = sys.argv[4]
  119. type1 = sys.argv[5]
  120. settings = str(json.loads(sys.argv[6]))
  121. # There is error: Settings must be object. So this does not work yet.
  122. #settings = {'currencyCode': 'EUR'}
  123. print(type(settings))
  124. showoncard = sys.argv[7]
  125. automaticallyoncard = sys.argv[8]
  126. showlabelonminicard = sys.argv[9]
  127. showsumattopoflist = sys.argv[10]
  128. customfieldtoboard = wekanurl + apiboards + boardid + s + cf
  129. # Add Custom Field to Board
  130. headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey)}
  131. post_data = {'authorId': '{}'.format(authorid), 'name': '{}'.format(name), 'type': '{}'.format(type1), 'settings': '{}'.format(settings), 'showoncard': '{}'.format(showoncard), 'automaticallyoncard': '{}'.format(automaticallyoncard), 'showlabelonminicard': '{}'.format(showlabelonminicard), 'showsumattopoflist': '{}'.format(showsumattopoflist)}
  132. body = requests.post(customfieldtoboard, data=post_data, headers=headers)
  133. print(body.text)
  134. # ------- ADD CUSTOM FIELD TO BOARD END -----------
  135. if arguments == 7:
  136. if sys.argv[1] == 'addcard':
  137. # ------- ADD CARD START -----------
  138. authorid = sys.argv[2]
  139. boardid = sys.argv[3]
  140. swimlaneid = sys.argv[4]
  141. listid = sys.argv[5]
  142. cardtitle = sys.argv[6]
  143. carddescription = sys.argv[7]
  144. cardtolist = wekanurl + apiboards + boardid + s + l + s + listid + s + cs
  145. # Add card
  146. headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey)}
  147. post_data = {'authorId': '{}'.format(authorid), 'title': '{}'.format(cardtitle), 'description': '{}'.format(carddescription), 'swimlaneId': '{}'.format(swimlaneid)}
  148. body = requests.post(cardtolist, data=post_data, headers=headers)
  149. print(body.text)
  150. # ------- ADD CARD END -----------
  151. if arguments == 6:
  152. if sys.argv[1] == 'editcard':
  153. # ------- EDIT CARD START -----------
  154. boardid = sys.argv[2]
  155. listid = sys.argv[3]
  156. cardid = sys.argv[4]
  157. newcardtitle = sys.argv[5]
  158. newcarddescription = sys.argv[6]
  159. edcard = wekanurl + apiboards + boardid + s + l + s + listid + s + cs + s + cardid
  160. print(edcard)
  161. headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey)}
  162. put_data = {'title': '{}'.format(newcardtitle), 'description': '{}'.format(newcarddescription)}
  163. body = requests.put(edcard, data=put_data, headers=headers)
  164. print("=== EDIT CARD ===\n")
  165. body = requests.get(edcard, headers=headers)
  166. data2 = body.text.replace('}',"}\n")
  167. print(data2)
  168. # ------- EDIT CARD END -----------
  169. if sys.argv[1] == 'editcustomfield':
  170. # ------- EDIT CUSTOMFIELD START -----------
  171. boardid = sys.argv[2]
  172. listid = sys.argv[3]
  173. cardid = sys.argv[4]
  174. customfieldid = sys.argv[5]
  175. newcustomfieldvalue = sys.argv[6]
  176. edfield = wekanurl + apiboards + boardid + s + l + s + listid + s + cs + s + cardid + s + 'customFields' + s + customfieldid
  177. #print(edfield)
  178. headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey)}
  179. post_data = {'_id': '{}'.format(customfieldid), 'value': '{}'.format(newcustomfieldvalue)}
  180. #print(post_data)
  181. body = requests.post(edfield, data=post_data, headers=headers)
  182. print("=== EDIT CUSTOMFIELD ===\n")
  183. data2 = body.text.replace('}',"}\n")
  184. print(data2)
  185. # ------- EDIT CUSTOMFIELD END -----------
  186. if arguments == 4:
  187. if sys.argv[1] == 'newuser':
  188. # ------- CREATE NEW USER START -----------
  189. username = sys.argv[2]
  190. email = sys.argv[3]
  191. password = sys.argv[4]
  192. headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey)}
  193. post_data = {'username': '{}'.format(username),'email': '{}'.format(email),'password': '{}'.format(password)}
  194. body = requests.post(users, data=post_data, headers=headers)
  195. print("=== CREATE NEW USER ===\n")
  196. print(body.text)
  197. # ------- CREATE NEW USER END -----------
  198. if sys.argv[1] == 'getcard':
  199. # ------- LIST OF CARD START -----------
  200. boardid = sys.argv[2]
  201. listid = sys.argv[3]
  202. cardid = sys.argv[4]
  203. listone = wekanurl + apiboards + boardid + s + l + s + listid + s + cs + s + cardid
  204. headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey)}
  205. print("=== INFO OF ONE LIST ===\n")
  206. print("URL:", listone) # Stampa l'URL per debug
  207. try:
  208. response = requests.get(listone, headers=headers)
  209. print("=== RESPONSE ===\n")
  210. print("Status Code:", response.status_code) # Stampa il codice di stato per debug
  211. if response.status_code == 200:
  212. data2 = response.text.replace('}', "}\n")
  213. print(data2)
  214. else:
  215. print(f"Error: {response.status_code}")
  216. print(f"Response: {response.text}")
  217. except Exception as e:
  218. print(f"Error in the GET request: {e}")
  219. # ------- LISTS OF CARD END -----------
  220. if arguments == 3:
  221. if sys.argv[1] == 'createlist':
  222. # ------- CREATE LIST START -----------
  223. boardid = sys.argv[2]
  224. listtitle = sys.argv[3]
  225. list = wekanurl + apiboards + boardid + s + l
  226. headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey)}
  227. post_data = {'title': '{}'.format(listtitle)}
  228. body = requests.post(list, data=post_data, headers=headers)
  229. print("=== CREATE LIST ===\n")
  230. print(body.text)
  231. # ------- CREATE LIST END -----------
  232. if sys.argv[1] == 'list':
  233. # ------- LIST OF BOARD START -----------
  234. boardid = sys.argv[2]
  235. listid = sys.argv[3]
  236. listone = wekanurl + apiboards + boardid + s + l + s + listid
  237. headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey)}
  238. print("=== INFO OF ONE LIST ===\n")
  239. body = requests.get(listone, headers=headers)
  240. data2 = body.text.replace('}',"}\n")
  241. print(data2)
  242. # ------- LISTS OF BOARD END -----------
  243. if sys.argv[1] == 'customfield':
  244. # ------- INFO OF CUSTOM FIELD START -----------
  245. boardid = sys.argv[2]
  246. customfieldid = sys.argv[3]
  247. customfieldone = wekanurl + apiboards + boardid + s + cf + s + customfieldid
  248. headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey)}
  249. print("=== INFO OF ONE CUSTOM FIELD ===\n")
  250. body = requests.get(customfieldone, headers=headers)
  251. data2 = body.text.replace('}',"}\n")
  252. print(data2)
  253. # ------- INFO OF CUSTOM FIELD END -----------
  254. if sys.argv[1] == 'cardsbyswimlane':
  255. # ------- RETRIEVE CARDS BY SWIMLANE ID START -----------
  256. boardid = sys.argv[2]
  257. swimlaneid = sys.argv[3]
  258. cardsbyswimlane = wekanurl + apiboards + boardid + s + sws + s + swimlaneid + s + cs
  259. headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey)}
  260. print("=== CARDS BY SWIMLANE ID ===\n")
  261. print("URL:", cardsbyswimlane) # Debug
  262. try:
  263. body = requests.get(cardsbyswimlane, headers=headers)
  264. print("Status Code:", body.status_code) # Debug
  265. data = body.text.replace('}', "}\n")
  266. print("Data:", data)
  267. except Exception as e:
  268. print("Error GET:", e)
  269. # ------- RETRIEVE CARDS BY SWIMLANE ID END -----------
  270. if arguments == 2:
  271. # ------- BOARDS LIST START -----------
  272. userid = sys.argv[2]
  273. boards = users + s + userid + s + bs
  274. if sys.argv[1] == 'boards':
  275. headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey)}
  276. #post_data = {'userId': '{}'.format(userid)}
  277. body = requests.get(boards, headers=headers)
  278. print("=== BOARDS ===\n")
  279. data2 = body.text.replace('}',"}\n")
  280. print(data2)
  281. # ------- BOARDS LIST END -----------
  282. if sys.argv[1] == 'board':
  283. # ------- BOARD INFO START -----------
  284. boardid = sys.argv[2]
  285. board = wekanurl + apiboards + boardid
  286. headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey)}
  287. body = requests.get(board, headers=headers)
  288. print("=== BOARD ===\n")
  289. data2 = body.text.replace('}',"}\n")
  290. print(data2)
  291. # ------- BOARD INFO END -----------
  292. if sys.argv[1] == 'customfields':
  293. # ------- CUSTOM FIELDS OF BOARD START -----------
  294. boardid = sys.argv[2]
  295. boardcustomfields = wekanurl + apiboards + boardid + s + cf
  296. headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey)}
  297. body = requests.get(boardcustomfields, headers=headers)
  298. print("=== CUSTOM FIELDS OF BOARD ===\n")
  299. data2 = body.text.replace('}',"}\n")
  300. print(data2)
  301. # ------- CUSTOM FIELDS OF BOARD END -----------
  302. if sys.argv[1] == 'swimlanes':
  303. boardid = sys.argv[2]
  304. swimlanes = wekanurl + apiboards + boardid + s + sws
  305. # ------- SWIMLANES OF BOARD START -----------
  306. headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey)}
  307. print("=== SWIMLANES ===\n")
  308. body = requests.get(swimlanes, headers=headers)
  309. data2 = body.text.replace('}',"}\n")
  310. print(data2)
  311. # ------- SWIMLANES OF BOARD END -----------
  312. if sys.argv[1] == 'lists':
  313. # ------- LISTS OF BOARD START -----------
  314. boardid = sys.argv[2]
  315. lists = wekanurl + apiboards + boardid + s + l
  316. headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey)}
  317. print("=== LISTS ===\n")
  318. body = requests.get(lists, headers=headers)
  319. data2 = body.text.replace('}',"}\n")
  320. print(data2)
  321. # ------- LISTS OF BOARD END -----------
  322. if sys.argv[1] == 'listattachments':
  323. # ------- LISTS OF ATTACHMENTS START -----------
  324. boardid = sys.argv[2]
  325. listattachments = wekanurl + apiboards + boardid + s + ats
  326. headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey)}
  327. print("=== LIST OF ATTACHMENTS ===\n")
  328. body = requests.get(listattachments, headers=headers)
  329. data2 = body.text.replace('}',"}\n")
  330. print(data2)
  331. # ------- LISTS OF ATTACHMENTS END -----------
  332. if arguments == 1:
  333. if sys.argv[1] == 'users':
  334. # ------- LIST OF USERS START -----------
  335. headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey)}
  336. print(users)
  337. print("=== USERS ===\n")
  338. body = requests.get(users, headers=headers)
  339. data2 = body.text.replace('}',"}\n")
  340. print(data2)
  341. # ------- LIST OF USERS END -----------
  342. if sys.argv[1] == 'user':
  343. # ------- LIST OF ALL USERS START -----------
  344. headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey)}
  345. print(user)
  346. print("=== USER ===\n")
  347. body = requests.get(user, headers=headers)
  348. data2 = body.text.replace('}',"}\n")
  349. print(data2)
  350. # ------- LIST OF ALL USERS END -----------
  351. if sys.argv[1] == 'boards':
  352. # ------- LIST OF PUBLIC BOARDS START -----------
  353. headers = {'Accept': 'application/json', 'Authorization': 'Bearer {}'.format(apikey)}
  354. print("=== PUBLIC BOARDS ===\n")
  355. listpublicboards = wekanurl + apiboards
  356. body = requests.get(listpublicboards, headers=headers)
  357. data2 = body.text.replace('}',"}\n")
  358. print(data2)
  359. # ------- LIST OF PUBLIC BOARDS END -----------