Mercurial > libervia-backend
comparison frontends/src/jp/cmd_blog.py @ 2458:4841ad6a5db4
jp (blog): added "set" command to publish content from stdin without editing
author | Goffi <goffi@goffi.org> |
---|---|
date | Tue, 12 Dec 2017 00:12:44 +0100 |
parents | 8b37a62336c3 |
children | 0046283a285d |
comparison
equal
deleted
inserted
replaced
2457:49aa1e3a90b8 | 2458:4841ad6a5db4 |
---|---|
25 from sat.tools.common.ansi import ANSI as A | 25 from sat.tools.common.ansi import ANSI as A |
26 from sat.tools.common import data_objects | 26 from sat.tools.common import data_objects |
27 from sat.tools.common import uri | 27 from sat.tools.common import uri |
28 from sat.tools import config | 28 from sat.tools import config |
29 from ConfigParser import NoSectionError, NoOptionError | 29 from ConfigParser import NoSectionError, NoOptionError |
30 from functools import partial | |
30 import json | 31 import json |
31 import sys | 32 import sys |
32 import os.path | 33 import os.path |
33 import os | 34 import os |
34 import time | 35 import time |
35 import tempfile | 36 import tempfile |
36 import subprocess | 37 import subprocess |
38 import codecs | |
37 from sat.tools.common import data_format | 39 from sat.tools.common import data_format |
38 | 40 |
39 __commands__ = ["Blog"] | 41 __commands__ = ["Blog"] |
40 | 42 |
41 SYNTAX_XHTML = u'xhtml' | 43 SYNTAX_XHTML = u'xhtml' |
97 if k and ext == v: | 99 if k and ext == v: |
98 return k | 100 return k |
99 | 101 |
100 # if not found, we use current syntax | 102 # if not found, we use current syntax |
101 return self.host.bridge.getParamA("Syntax", "Composition", "value", self.profile) | 103 return self.host.bridge.getParamA("Syntax", "Composition", "value", self.profile) |
104 | |
105 | |
106 class BlogPublishCommon(object): | |
107 """handle common option for publising commands (Set and Edit)""" | |
108 | |
109 def add_parser_options(self): | |
110 self.addServiceNodeArgs() | |
111 self.parser.add_argument("-T", '--title', type=base.unicode_decoder, help=_(u"title of the item")) | |
112 self.parser.add_argument("-t", '--tag', type=base.unicode_decoder, action='append', help=_(u"tag (category) of your item")) | |
113 self.parser.add_argument("-C", "--comments", action='store_true', help=_(u"enable comments")) | |
114 self.parser.add_argument("-S", '--syntax', type=base.unicode_decoder, help=_(u"syntax to use (default: get profile's default syntax)")) | |
115 | |
116 def setMbDataContent(self, content, mb_data): | |
117 if self.args.syntax is None: | |
118 # default syntax has been used | |
119 mb_data['content_rich'] = content | |
120 elif self.current_syntax == SYNTAX_XHTML: | |
121 mb_data['content_xhtml'] = content | |
122 else: | |
123 mb_data['content_xhtml'] = self.host.bridge.syntaxConvert(content, self.current_syntax, SYNTAX_XHTML, False, self.profile) | |
124 | |
125 def setMbDataFromArgs(self, mb_data): | |
126 """set microblog metadata according to command line options | |
127 | |
128 if metadata already exist, it will be overwritten | |
129 """ | |
130 mb_data['allow_comments'] = C.boolConst(self.args.comments) | |
131 if self.args.tag: | |
132 data_format.iter2dict('tag', self.args.tag, mb_data, check_conflict=False) | |
133 if self.args.title is not None: | |
134 mb_data['title'] = self.args.title | |
135 | |
136 | |
137 class Set(base.CommandBase, BlogCommon, BlogPublishCommon): | |
138 | |
139 def __init__(self, host): | |
140 base.CommandBase.__init__(self, host, 'set', help=_(u'publish a new blog item or update an existing one')) | |
141 BlogCommon.__init__(self, self.host) | |
142 BlogPublishCommon.__init__(self) | |
143 self.need_loop=True | |
144 | |
145 def add_parser_options(self): | |
146 BlogPublishCommon.add_parser_options(self) | |
147 self.parser.add_argument("item", type=base.unicode_decoder, nargs='?', default=None, help=_(u"id of the item to publish")) | |
148 | |
149 def mbSendCb(self): | |
150 self.disp(u"Item published") | |
151 self.host.quit(C.EXIT_OK) | |
152 | |
153 def start(self): | |
154 common.checkURI(self.args) | |
155 self.pubsub_item = self.args.item | |
156 mb_data = {} | |
157 self.setMbDataFromArgs(mb_data) | |
158 content = codecs.getreader('utf-8')(sys.stdin).read() | |
159 self.setMbDataContent(content, mb_data) | |
160 | |
161 self.host.bridge.mbSend( | |
162 self.args.service, | |
163 self.args.node, | |
164 mb_data, | |
165 self.profile, | |
166 callback=self.exitCb, | |
167 errback=partial(self.errback, | |
168 msg=_(u"can't send item: {}"), | |
169 exit_code=C.EXIT_BRIDGE_ERRBACK)) | |
102 | 170 |
103 | 171 |
104 class Get(base.CommandBase, BlogCommon): | 172 class Get(base.CommandBase, BlogCommon): |
105 TEMPLATE = u"blog/articles.html" | 173 TEMPLATE = u"blog/articles.html" |
106 | 174 |
281 self.profile, | 349 self.profile, |
282 callback=self.mbGetCb, | 350 callback=self.mbGetCb, |
283 errback=self.mbGetEb) | 351 errback=self.mbGetEb) |
284 | 352 |
285 | 353 |
286 class Edit(base.CommandBase, BlogCommon, common.BaseEdit): | 354 class Edit(base.CommandBase, BlogCommon, BlogPublishCommon, common.BaseEdit): |
287 | 355 |
288 def __init__(self, host): | 356 def __init__(self, host): |
289 base.CommandBase.__init__(self, host, 'edit', use_verbose=True, help=_(u'edit an existing or new blog post')) | 357 base.CommandBase.__init__(self, host, 'edit', use_verbose=True, help=_(u'edit an existing or new blog post')) |
290 BlogCommon.__init__(self, self.host) | 358 BlogCommon.__init__(self, self.host) |
359 BlogPublishCommon.__init__(self) | |
291 common.BaseEdit.__init__(self, self.host, BLOG_TMP_DIR, use_metadata=True) | 360 common.BaseEdit.__init__(self, self.host, BLOG_TMP_DIR, use_metadata=True) |
292 | 361 |
293 def add_parser_options(self): | 362 def add_parser_options(self): |
294 self.addServiceNodeArgs() | 363 BlogPublishCommon.add_parser_options(self) |
364 self.parser.add_argument("-P", "--preview", action="store_true", help=_(u"launch a blog preview in parallel")) | |
295 self.parser.add_argument("item", type=base.unicode_decoder, nargs='?', default=u'new', help=_(u"URL of the item to edit, or keyword")) | 365 self.parser.add_argument("item", type=base.unicode_decoder, nargs='?', default=u'new', help=_(u"URL of the item to edit, or keyword")) |
296 self.parser.add_argument("-P", "--preview", action="store_true", help=_(u"launch a blog preview in parallel")) | |
297 self.parser.add_argument("-T", '--title', type=base.unicode_decoder, help=_(u"title of the item")) | |
298 self.parser.add_argument("-t", '--tag', type=base.unicode_decoder, action='append', help=_(u"tag (category) of your item")) | |
299 self.parser.add_argument("--no-comment", action='store_true', help=_(u"disable comments")) | |
300 self.parser.add_argument("-S", '--syntax', type=base.unicode_decoder, help=_(u"syntax to use (default: get profile's default syntax)")) | |
301 common.BaseEdit.add_parser_options(self) | 366 common.BaseEdit.add_parser_options(self) |
302 | 367 |
303 def buildMetadataFile(self, content_file_path, mb_data=None): | 368 def buildMetadataFile(self, content_file_path, mb_data=None): |
304 """Build a metadata file using json | 369 """Build a metadata file using json |
305 | 370 |
329 try: | 394 try: |
330 del mb_data[key] | 395 del mb_data[key] |
331 except KeyError: | 396 except KeyError: |
332 pass | 397 pass |
333 # and override metadata with command-line arguments | 398 # and override metadata with command-line arguments |
334 mb_data['allow_comments'] = C.boolConst(not self.args.no_comment) | 399 self.setMbDataFromArgs(mb_data) |
335 if self.args.tag: | |
336 data_format.iter2dict('tag', self.args.tag, mb_data, check_conflict=False) | |
337 if self.args.title is not None: | |
338 mb_data['title'] = self.args.title | |
339 | 400 |
340 # then we create the file and write metadata there, as JSON dict | 401 # then we create the file and write metadata there, as JSON dict |
341 # XXX: if we port jp one day on Windows, O_BINARY may need to be added here | 402 # XXX: if we port jp one day on Windows, O_BINARY may need to be added here |
342 with os.fdopen(os.open(meta_file_path, os.O_RDWR | os.O_CREAT | os.O_TRUNC,0o600), 'w+b') as f: | 403 with os.fdopen(os.open(meta_file_path, os.O_RDWR | os.O_CREAT | os.O_TRUNC,0o600), 'w+b') as f: |
343 # we need to use an intermediate unicode buffer to write to the file unicode without escaping characters | 404 # we need to use an intermediate unicode buffer to write to the file unicode without escaping characters |
362 | 423 |
363 # we launch editor | 424 # we launch editor |
364 self.runEditor("blog_editor_args", content_file_path, content_file_obj, meta_file_path=meta_file_path, meta_ori=meta_ori) | 425 self.runEditor("blog_editor_args", content_file_path, content_file_obj, meta_file_path=meta_file_path, meta_ori=meta_ori) |
365 | 426 |
366 def publish(self, content, mb_data): | 427 def publish(self, content, mb_data): |
367 if self.args.syntax is None: | 428 self.setMbDataContent(content, mb_data) |
368 # default syntax has been used | |
369 mb_data['content_rich'] = content | |
370 elif self.current_syntax == SYNTAX_XHTML: | |
371 mb_data['content_xhtml'] = content | |
372 else: | |
373 mb_data['content_xhtml'] = self.host.bridge.syntaxConvert(content, self.current_syntax, SYNTAX_XHTML, False, self.profile) | |
374 | 429 |
375 if self.pubsub_item is not None: | 430 if self.pubsub_item is not None: |
376 mb_data['id'] = self.pubsub_item | 431 mb_data['id'] = self.pubsub_item |
377 | 432 |
378 self.host.bridge.mbSend(self.pubsub_service, self.pubsub_node, mb_data, self.profile) | 433 self.host.bridge.mbSend(self.pubsub_service, self.pubsub_node, mb_data, self.profile) |
379 self.disp(u"Blog item published") | 434 self.disp(u"Blog item published") |
435 | |
380 | 436 |
381 def getTmpSuff(self): | 437 def getTmpSuff(self): |
382 # we get current syntax to determine file extension | 438 # we get current syntax to determine file extension |
383 if self.current_syntax is None: | 439 if self.current_syntax is None: |
384 self.current_syntax = self.host.bridge.getParamA("Syntax", "Composition", "value", self.profile) | 440 self.current_syntax = self.host.bridge.getParamA("Syntax", "Composition", "value", self.profile) |
646 self.host.bridge.blogImport(self.args.importer, self.args.location, options, self.args.service, self.args.node, self.profile, | 702 self.host.bridge.blogImport(self.args.importer, self.args.location, options, self.args.service, self.args.node, self.profile, |
647 callback=gotId, errback=self.error) | 703 callback=gotId, errback=self.error) |
648 | 704 |
649 | 705 |
650 class Blog(base.CommandBase): | 706 class Blog(base.CommandBase): |
651 subcommands = (Get, Edit, Preview, Import) | 707 subcommands = (Set, Get, Edit, Preview, Import) |
652 | 708 |
653 def __init__(self, host): | 709 def __init__(self, host): |
654 super(Blog, self).__init__(host, 'blog', use_profile=False, help=_('blog/microblog management')) | 710 super(Blog, self).__init__(host, 'blog', use_profile=False, help=_('blog/microblog management')) |