cli.py 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. #!/usr/bin/env python3
  2. import sys
  3. from pprint import pprint
  4. import requests
  5. import argparse
  6. from rscli import rsfiles
  7. from rscli.httputils import req
  8. try:
  9. from colors import color
  10. except ImportError:
  11. def color(text, *args, **kwargs):
  12. return text
  13. def err(msg):
  14. print(color(msg, fg="red", style="bold"))
  15. def is_group_subscribed(mSubscribeFlags):
  16. return bool(mSubscribeFlags & 4)
  17. def main_forum_list(args):
  18. r = req(args, "/rsGxsForums/getForumsSummaries")
  19. forums = r.json()["forums"]
  20. for item in forums:
  21. if is_group_subscribed(item["mSubscribeFlags"]):
  22. if "notsubscribed" in args.select:
  23. continue
  24. style = "bold"
  25. else:
  26. if "subscribed" in args.select:
  27. continue
  28. style = None
  29. print(color(item["mGroupName"], style=style, fg="green"))
  30. print(" " + color(item["mGroupId"], style="underline"))
  31. def main_forum_read(args):
  32. r = req(args, "/rsGxsForums/getForumMsgMetaData", {"forumId": args.forum_id})
  33. items = r.json()["msgMetas"]
  34. items.sort(key=lambda p: p['mPublishTs'], reverse=True)
  35. if args.long:
  36. msgs = [item["mMsgId"] for item in items[: args.num_posts]]
  37. items_r = req(
  38. args,
  39. "/rsGxsForums/getForumContent",
  40. {"forumId": args.forum_id, "msgsIds": msgs},
  41. )
  42. items = items_r.json()["msgs"]
  43. items.sort(key=lambda p: p['mMeta']['mPublishTs'], reverse=True)
  44. for item in items:
  45. print(color(item["mMeta"]["mMsgName"], style="bold", fg="green"))
  46. print()
  47. print(item["mMsg"]) # TODO: html2txt
  48. print()
  49. else:
  50. for item in items[: args.num_posts]:
  51. print(color(item["mMsgName"], style="bold", fg="green"))
  52. print(" " + color(item["mMsgId"], style="underline"))
  53. def main_channel_list(args):
  54. r = req(args, "/rsGxsChannels/getChannelsSummaries")
  55. channels = r.json()["channels"]
  56. for item in channels:
  57. if is_group_subscribed(item["mSubscribeFlags"]):
  58. if "notsubscribed" in args.select:
  59. continue
  60. style = "bold"
  61. else:
  62. if "subscribed" in args.select:
  63. continue
  64. style = None
  65. print(color(item["mGroupName"], style=style, fg="green"))
  66. print(" " + color(item["mGroupId"], style="underline"))
  67. def main_channel_read(args):
  68. r = req(args, "/rsGxsChannels/getContentSummaries", {"channelId": args.channel_id})
  69. posts = r.json()["summaries"]
  70. posts.sort(key=lambda p: p['mPublishTs'], reverse=True)
  71. if args.long:
  72. msgs = [post["mMsgId"] for post in posts[: args.num_posts]]
  73. posts_r = req(
  74. args,
  75. "/rsGxsChannels/getChannelContent",
  76. {"channelId": args.channel_id, "contentsIds": msgs},
  77. )
  78. posts = posts_r.json()["posts"]
  79. posts.sort(key=lambda p: p['mMeta']['mPublishTs'], reverse=True)
  80. for post in posts:
  81. print(color(post["mMeta"]["mMsgName"], style="bold", fg="green"))
  82. print()
  83. print(post["mMsg"])
  84. print()
  85. else:
  86. for post in posts[: args.num_posts]:
  87. print(color(post["mMsgName"], style="bold", fg="green"))
  88. print(" " + color(post["mMsgId"], style="underline"))
  89. def main_channel_show(args):
  90. r = req(args, "/rsGxsChannels/getChannelsInfo", {"chanIds": [args.channel_id]})
  91. data = r.json()
  92. channels = data["channelsInfo"]
  93. for chan in channels:
  94. print(color(chan["mMeta"]["mGroupName"], style="bold", fg="green"))
  95. print(" " + color(chan["mMeta"]["mGroupId"], style="underline"))
  96. print(" " + chan["mDescription"])
  97. print(color("Last Post:", style="bold") + " \t%s" % chan["mMeta"]["mLastPost"])
  98. def main_channel_post_v1(args):
  99. r = req(
  100. args,
  101. "/rsGxsChannels/createPost",
  102. {
  103. "post": {
  104. "mMeta": {"mGroupId": args.channel_id, "mMsgName": args.post_title},
  105. "mMsg": args.post_body,
  106. }
  107. },
  108. )
  109. if r.status_code != 200:
  110. print(color("ERROR: could not create post", fg="red", style="bold"))
  111. print("Error %d" % r.status_code)
  112. sys.exit(1)
  113. ret = r.json()
  114. if ret.get("retval", True) is False:
  115. print(color("ERROR: could not create post", fg="red", style="bold"))
  116. pprint(ret)
  117. sys.exit(1)
  118. pprint(ret)
  119. def main_channel_post(args):
  120. try:
  121. r = req(
  122. args,
  123. "/rsGxsChannels/createPostV2",
  124. {
  125. "channelId": args.channel_id,
  126. "title": args.post_title,
  127. "mBody": args.post_body,
  128. },
  129. )
  130. except requests.exceptions.HTTPError as exc:
  131. if exc.response.status_code != 404:
  132. raise
  133. else:
  134. ret = r.json()
  135. if ret.get("retval", True) is False:
  136. print(color("ERROR: could not create post", fg="red", style="bold"))
  137. print(ret["errorMessage"])
  138. pprint(ret)
  139. sys.exit(1)
  140. pprint(ret)
  141. return main_channel_post_v1(args)
  142. def main_file_publish(args):
  143. ret = rsfiles.file_publish(args, args.fnames)
  144. for filehash, fname in zip(ret, args.fnames):
  145. print(color(filehash, fg="green") + " \t%s" % fname)
  146. print(" " + rsfiles.get_file_link(args, filehash, fname=fname))
  147. def get_parser():
  148. p = argparse.ArgumentParser()
  149. p.add_argument("--endpoint", default="http://127.0.0.1:9092")
  150. p.add_argument("-u", "--auth", dest="auth")
  151. p_sub = p.add_subparsers()
  152. ch = p_sub.add_parser("channel")
  153. ch.add_argument("--channel-id")
  154. ch_sub = ch.add_subparsers()
  155. ch_list = ch_sub.add_parser("list")
  156. ch_list.add_argument(
  157. "--select",
  158. nargs="+",
  159. choices=["all", "subscribed", "notsubscribed"],
  160. default=["all"],
  161. )
  162. ch_list.set_defaults(mainfunc=main_channel_list)
  163. ch_show = ch_sub.add_parser("show")
  164. ch_show.set_defaults(mainfunc=main_channel_show)
  165. ch_read = ch_sub.add_parser("read")
  166. ch_read.add_argument("--long", action="store_true", default=False)
  167. ch_read.add_argument("--num-posts", type=int, default=10)
  168. ch_read.set_defaults(mainfunc=main_channel_read)
  169. ch_post = ch_sub.add_parser("post")
  170. ch_post.set_defaults(mainfunc=main_channel_post)
  171. ch_post.add_argument("--post-title")
  172. ch_post.add_argument("--post-body")
  173. forum = p_sub.add_parser("forum")
  174. forum.add_argument("--forum-id")
  175. forum_sub = forum.add_subparsers()
  176. forum_list = forum_sub.add_parser("list")
  177. forum_list.add_argument(
  178. "--select",
  179. nargs="+",
  180. choices=["all", "subscribed", "notsubscribed"],
  181. default=["all"],
  182. )
  183. forum_list.set_defaults(mainfunc=main_forum_list)
  184. forum_read = forum_sub.add_parser("read")
  185. forum_read.add_argument("--long", action="store_true", default=False)
  186. forum_read.add_argument("--num-posts", type=int, default=10)
  187. forum_read.set_defaults(mainfunc=main_forum_read)
  188. files = p_sub.add_parser("file")
  189. files_sub = files.add_subparsers()
  190. files_list = files_sub.add_parser("publish")
  191. files_list.add_argument("--fname", nargs="+", required=True, dest="fnames")
  192. files_list.set_defaults(mainfunc=main_file_publish)
  193. # TODO: channel rss -> read and convert to rss
  194. return p
  195. def main():
  196. p = get_parser()
  197. args = p.parse_args()
  198. if getattr(args, "mainfunc", None) is None:
  199. print("Not a complete command")
  200. sys.exit(2)
  201. args.mainfunc(args)
  202. if __name__ == "__main__":
  203. main()