comparison sat_frontends/jp/cmd_forums.py @ 3040:fee60f17ebac

jp: jp asyncio port: /!\ this commit is huge. Jp is temporarily not working with `dbus` bridge /!\ This patch implements the port of jp to asyncio, so it is now correctly using the bridge asynchronously, and it can be used with bridges like `pb`. This also simplify the code, notably for things which were previously implemented with many callbacks (like pagination with RSM). During the process, some behaviours have been modified/fixed, in jp and backends, check diff for details.
author Goffi <goffi@goffi.org>
date Wed, 25 Sep 2019 08:56:41 +0200
parents ab2696e34d29
children 9d0df638c8b4
comparison
equal deleted inserted replaced
3039:a1bc34f90fa5 3040:fee60f17ebac
21 from . import base 21 from . import base
22 from sat.core.i18n import _ 22 from sat.core.i18n import _
23 from sat_frontends.jp.constants import Const as C 23 from sat_frontends.jp.constants import Const as C
24 from sat_frontends.jp import common 24 from sat_frontends.jp import common
25 from sat.tools.common.ansi import ANSI as A 25 from sat.tools.common.ansi import ANSI as A
26 from functools import partial
27 import codecs 26 import codecs
28 import json 27 import json
29 28
30 __commands__ = ["Forums"] 29 __commands__ = ["Forums"]
31 30
44 use_draft=True, 43 use_draft=True,
45 use_verbose=True, 44 use_verbose=True,
46 help=_("edit forums"), 45 help=_("edit forums"),
47 ) 46 )
48 common.BaseEdit.__init__(self, self.host, FORUMS_TMP_DIR) 47 common.BaseEdit.__init__(self, self.host, FORUMS_TMP_DIR)
49 self.need_loop = True
50 48
51 def add_parser_options(self): 49 def add_parser_options(self):
52 self.parser.add_argument( 50 self.parser.add_argument(
53 "-k", 51 "-k",
54 "--key", 52 "--key",
58 56
59 def getTmpSuff(self): 57 def getTmpSuff(self):
60 """return suffix used for content file""" 58 """return suffix used for content file"""
61 return "json" 59 return "json"
62 60
63 def forumsSetCb(self): 61 async def publish(self, forums_raw):
64 self.disp(_("forums have been edited"), 1) 62 try:
65 self.host.quit() 63 await self.host.bridge.forumsSet(
64 forums_raw,
65 self.args.service,
66 self.args.node,
67 self.args.key,
68 self.profile,
69 )
70 except Exception as e:
71 self.disp(f"can't set forums: {e}", error=True)
72 self.host.quit(C.EXIT_BRIDGE_ERRBACK)
73 else:
74 self.disp(_("forums have been edited"), 1)
75 self.host.quit()
66 76
67 def publish(self, forums_raw): 77 async def start(self):
68 self.host.bridge.forumsSet( 78 try:
69 forums_raw, 79 forums_json = await self.host.bridge.forumsGet(
70 self.args.service, 80 self.args.service,
71 self.args.node, 81 self.args.node,
72 self.args.key, 82 self.args.key,
73 self.profile, 83 self.profile,
74 callback=self.forumsSetCb, 84 )
75 errback=partial( 85 except Exception as e:
76 self.errback, 86 if e.classname == "NotFound":
77 msg=_("can't set forums: {}"), 87 forums_json = ""
78 exit_code=C.EXIT_BRIDGE_ERRBACK, 88 else:
79 ), 89 self.disp(f"can't get node configuration: {e}", error=True)
80 ) 90 self.host.quit(C.EXIT_BRIDGE_ERRBACK)
81 91
82 def forumsGetCb(self, forums_json):
83 content_file_obj, content_file_path = self.getTmpFile() 92 content_file_obj, content_file_path = self.getTmpFile()
84 forums_json = forums_json.strip() 93 forums_json = forums_json.strip()
85 if forums_json: 94 if forums_json:
86 # we loads and dumps to have pretty printed json 95 # we loads and dumps to have pretty printed json
87 forums = json.loads(forums_json) 96 forums = json.loads(forums_json)
88 # cf. https://stackoverflow.com/a/18337754 97 # cf. https://stackoverflow.com/a/18337754
89 f = codecs.getwriter("utf-8")(content_file_obj) 98 f = codecs.getwriter("utf-8")(content_file_obj)
90 json.dump(forums, f, ensure_ascii=False, indent=4) 99 json.dump(forums, f, ensure_ascii=False, indent=4)
91 content_file_obj.seek(0) 100 content_file_obj.seek(0)
92 self.runEditor("forums_editor_args", content_file_path, content_file_obj) 101 await self.runEditor("forums_editor_args", content_file_path, content_file_obj)
93
94 def forumsGetEb(self, failure_):
95 # FIXME: error handling with bridge is broken, need to be properly fixed
96 if failure_.condition == "item-not-found":
97 self.forumsGetCb("")
98 else:
99 self.errback(
100 failure_,
101 msg=_("can't get forums structure: {}"),
102 exit_code=C.EXIT_BRIDGE_ERRBACK,
103 )
104
105 def start(self):
106 self.host.bridge.forumsGet(
107 self.args.service,
108 self.args.node,
109 self.args.key,
110 self.profile,
111 callback=self.forumsGetCb,
112 errback=self.forumsGetEb,
113 )
114 102
115 103
116 class Get(base.CommandBase): 104 class Get(base.CommandBase):
117 def __init__(self, host): 105 def __init__(self, host):
118 extra_outputs = {"default": self.default_output} 106 extra_outputs = {"default": self.default_output}
124 extra_outputs=extra_outputs, 112 extra_outputs=extra_outputs,
125 use_pubsub=True, 113 use_pubsub=True,
126 use_verbose=True, 114 use_verbose=True,
127 help=_("get forums structure"), 115 help=_("get forums structure"),
128 ) 116 )
129 self.need_loop = True
130 117
131 def add_parser_options(self): 118 def add_parser_options(self):
132 self.parser.add_argument( 119 self.parser.add_argument(
133 "-k", 120 "-k",
134 "--key", 121 "--key",
163 head_color = C.A_LEVEL_COLORS[level % len(C.A_LEVEL_COLORS)] 150 head_color = C.A_LEVEL_COLORS[level % len(C.A_LEVEL_COLORS)]
164 self.disp( 151 self.disp(
165 A.color(level * 4 * " ", head_color, key, A.RESET, ": ", value) 152 A.color(level * 4 * " ", head_color, key, A.RESET, ": ", value)
166 ) 153 )
167 154
168 def forumsGetCb(self, forums_raw): 155 async def start(self):
169 if not forums_raw: 156 try:
170 self.disp(_("no schema found"), 1) 157 forums_raw = await self.host.bridge.forumsGet(
171 self.host.quit(1) 158 self.args.service,
172 forums = json.loads(forums_raw) 159 self.args.node,
173 self.output(forums) 160 self.args.key,
174 self.host.quit() 161 self.profile,
175 162 )
176 def start(self): 163 except Exception as e:
177 self.host.bridge.forumsGet( 164 self.disp(f"can't get forums: {e}", error=True)
178 self.args.service, 165 self.host.quit(C.EXIT_BRIDGE_ERRBACK)
179 self.args.node, 166 else:
180 self.args.key, 167 if not forums_raw:
181 self.profile, 168 self.disp(_("no schema found"), 1)
182 callback=self.forumsGetCb, 169 self.host.quit(1)
183 errback=partial( 170 forums = json.loads(forums_raw)
184 self.errback, 171 await self.output(forums)
185 msg=_("can't get forums: {}"), 172 self.host.quit()
186 exit_code=C.EXIT_BRIDGE_ERRBACK,
187 ),
188 )
189 173
190 174
191 class Forums(base.CommandBase): 175 class Forums(base.CommandBase):
192 subcommands = (Get, Edit) 176 subcommands = (Get, Edit)
193 177