annotate frontends/src/jp/cmd_blog.py @ 2528:65e278997715

component file sharing: comments metadata: new <comments> element is added to file metadata, it contains the URL to the comments virtual node and the count of comments (this way client knows if it make sense to request comments or not). Fixed triggers in plugin XEP-0264 (return value was missing). New trigger in plugin XEP-0329 to allow component to add metadata (used here for comments url).
author Goffi <goffi@goffi.org>
date Fri, 16 Mar 2018 18:43:11 +0100
parents 512c443a58ba
children 772447ec070f
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1960
3e168cde7a7d jp: fixed shebang python call
Goffi <goffi@goffi.org>
parents: 1929
diff changeset
1 #!/usr/bin/env python2
1827
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
2 # -*- coding: utf-8 -*-
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
3
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
4 # jp: a SàT command line tool
2483
0046283a285d dates update
Goffi <goffi@goffi.org>
parents: 2458
diff changeset
5 # Copyright (C) 2009-2018 Jérôme Poisson (goffi@goffi.org)
1827
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
6
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
7 # This program is free software: you can redistribute it and/or modify
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
8 # it under the terms of the GNU Affero General Public License as published by
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
9 # the Free Software Foundation, either version 3 of the License, or
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
10 # (at your option) any later version.
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
11
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
12 # This program is distributed in the hope that it will be useful,
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
15 # GNU Affero General Public License for more details.
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
16
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
17 # You should have received a copy of the GNU Affero General Public License
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
19
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
20
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
21 import base
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
22 from sat.core.i18n import _
2157
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
23 from sat_frontends.jp.constants import Const as C
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents: 2267
diff changeset
24 from sat_frontends.jp import common
2157
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
25 from sat.tools.common.ansi import ANSI as A
2164
63d191c05ecd jp (blog): set default template and data mapping for the new template output
Goffi <goffi@goffi.org>
parents: 2161
diff changeset
26 from sat.tools.common import data_objects
2327
dad500e7ae50 jp (blog/get): added "url" key, which compute xmpp: URL of items
Goffi <goffi@goffi.org>
parents: 2325
diff changeset
27 from sat.tools.common import uri
1866
397ef87958b9 jp (blog): edit command, first draft:
Goffi <goffi@goffi.org>
parents: 1864
diff changeset
28 from sat.tools import config
1872
df1ca137b0cb jp (blog/edit): editor arguments can now be specified on sat.conf, and default on are applied for known editors:
Goffi <goffi@goffi.org>
parents: 1871
diff changeset
29 from ConfigParser import NoSectionError, NoOptionError
2458
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
30 from functools import partial
1834
6209de5e3e25 jp (blog): import now show progression + value to add to sat.conf for URLs redirection
Goffi <goffi@goffi.org>
parents: 1827
diff changeset
31 import json
1887
16527dd5a81b blog (jp/edit): added --preview option to launch a "blog preview" in parallel
Goffi <goffi@goffi.org>
parents: 1886
diff changeset
32 import sys
1866
397ef87958b9 jp (blog): edit command, first draft:
Goffi <goffi@goffi.org>
parents: 1864
diff changeset
33 import os.path
397ef87958b9 jp (blog): edit command, first draft:
Goffi <goffi@goffi.org>
parents: 1864
diff changeset
34 import os
397ef87958b9 jp (blog): edit command, first draft:
Goffi <goffi@goffi.org>
parents: 1864
diff changeset
35 import time
397ef87958b9 jp (blog): edit command, first draft:
Goffi <goffi@goffi.org>
parents: 1864
diff changeset
36 import tempfile
397ef87958b9 jp (blog): edit command, first draft:
Goffi <goffi@goffi.org>
parents: 1864
diff changeset
37 import subprocess
2458
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
38 import codecs
1919
d3354c80bd1f core (tools): moved common to a separate package, and put data method in a data_format module
Goffi <goffi@goffi.org>
parents: 1912
diff changeset
39 from sat.tools.common import data_format
1866
397ef87958b9 jp (blog): edit command, first draft:
Goffi <goffi@goffi.org>
parents: 1864
diff changeset
40
397ef87958b9 jp (blog): edit command, first draft:
Goffi <goffi@goffi.org>
parents: 1864
diff changeset
41 __commands__ = ["Blog"]
397ef87958b9 jp (blog): edit command, first draft:
Goffi <goffi@goffi.org>
parents: 1864
diff changeset
42
2330
74c1dbabeec8 jp (blog/edit): pretty format XHTML before editing it
Goffi <goffi@goffi.org>
parents: 2327
diff changeset
43 SYNTAX_XHTML = u'xhtml'
1872
df1ca137b0cb jp (blog/edit): editor arguments can now be specified on sat.conf, and default on are applied for known editors:
Goffi <goffi@goffi.org>
parents: 1871
diff changeset
44 # extensions to use with known syntaxes
df1ca137b0cb jp (blog/edit): editor arguments can now be specified on sat.conf, and default on are applied for known editors:
Goffi <goffi@goffi.org>
parents: 1871
diff changeset
45 SYNTAX_EXT = {
df1ca137b0cb jp (blog/edit): editor arguments can now be specified on sat.conf, and default on are applied for known editors:
Goffi <goffi@goffi.org>
parents: 1871
diff changeset
46 '': 'txt', # used when the syntax is not found
2330
74c1dbabeec8 jp (blog/edit): pretty format XHTML before editing it
Goffi <goffi@goffi.org>
parents: 2327
diff changeset
47 SYNTAX_XHTML: "xhtml",
1872
df1ca137b0cb jp (blog/edit): editor arguments can now be specified on sat.conf, and default on are applied for known editors:
Goffi <goffi@goffi.org>
parents: 1871
diff changeset
48 "markdown": "md"
df1ca137b0cb jp (blog/edit): editor arguments can now be specified on sat.conf, and default on are applied for known editors:
Goffi <goffi@goffi.org>
parents: 1871
diff changeset
49 }
df1ca137b0cb jp (blog/edit): editor arguments can now be specified on sat.conf, and default on are applied for known editors:
Goffi <goffi@goffi.org>
parents: 1871
diff changeset
50
df1ca137b0cb jp (blog/edit): editor arguments can now be specified on sat.conf, and default on are applied for known editors:
Goffi <goffi@goffi.org>
parents: 1871
diff changeset
51
2330
74c1dbabeec8 jp (blog/edit): pretty format XHTML before editing it
Goffi <goffi@goffi.org>
parents: 2327
diff changeset
52 CONF_SYNTAX_EXT = u'syntax_ext_dict'
2273
5f0dbf42aa9c jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents: 2271
diff changeset
53 BLOG_TMP_DIR = u"blog"
1868
28b29381db75 jp (blog/edit): added metadata handling through a .json file (named like content temporary file, but with extension replaced by "_metadata.json"). Modification to this file before the end of edition will be taken into account.
Goffi <goffi@goffi.org>
parents: 1866
diff changeset
54 # key to remove from metadata tmp file if they exist
1912
c38bcc0343b6 jp (blog): added "updated" to keys to keys to remove from tmp metadata
Goffi <goffi@goffi.org>
parents: 1906
diff changeset
55 KEY_TO_REMOVE_METADATA = ('id','content', 'content_xhtml', 'comments_node', 'comments_service', 'updated')
1866
397ef87958b9 jp (blog): edit command, first draft:
Goffi <goffi@goffi.org>
parents: 1864
diff changeset
56
1834
6209de5e3e25 jp (blog): import now show progression + value to add to sat.conf for URLs redirection
Goffi <goffi@goffi.org>
parents: 1827
diff changeset
57 URL_REDIRECT_PREFIX = 'url_redirect_'
1882
ed444e9aa078 jp (blog/preview): added inotify support, so preview can be updated each time the file is modified (actually IN_CLOSE_WRITE is used, but this may change in the future)
Goffi <goffi@goffi.org>
parents: 1881
diff changeset
58 INOTIFY_INSTALL = '"pip install inotify"'
2157
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
59 MB_KEYS = (u"id",
2327
dad500e7ae50 jp (blog/get): added "url" key, which compute xmpp: URL of items
Goffi <goffi@goffi.org>
parents: 2325
diff changeset
60 u"url",
2157
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
61 u"atom_id",
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
62 u"updated",
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
63 u"published",
2267
ed28798fd76c jp (blog): added language in managed keys
Goffi <goffi@goffi.org>
parents: 2232
diff changeset
64 u"language",
2157
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
65 u"comments", # this key is used for all comments* keys
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
66 u"tags", # this key is used for all tag* keys
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
67 u"author",
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
68 u"author_jid",
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
69 u"author_email",
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
70 u"author_jid_verified",
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
71 u"content",
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
72 u"content_xhtml",
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
73 u"title",
2327
dad500e7ae50 jp (blog/get): added "url" key, which compute xmpp: URL of items
Goffi <goffi@goffi.org>
parents: 2325
diff changeset
74 u"title_xhtml",
dad500e7ae50 jp (blog/get): added "url" key, which compute xmpp: URL of items
Goffi <goffi@goffi.org>
parents: 2325
diff changeset
75 )
2157
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
76 OUTPUT_OPT_NO_HEADER = u'no-header'
1827
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
77
1866
397ef87958b9 jp (blog): edit command, first draft:
Goffi <goffi@goffi.org>
parents: 1864
diff changeset
78
1877
a97db84c048d jp (blog): moved common method in a BlogCommon class + added "current" as an item keyword for blog/edit
Goffi <goffi@goffi.org>
parents: 1876
diff changeset
79 class BlogCommon(object):
1921
b111f6589da4 jp (blog): drafts are now put in a sub dir per profile + added a security which keep the last 10 drafts before removing them (all profiles included).
Goffi <goffi@goffi.org>
parents: 1919
diff changeset
80
b111f6589da4 jp (blog): drafts are now put in a sub dir per profile + added a security which keep the last 10 drafts before removing them (all profiles included).
Goffi <goffi@goffi.org>
parents: 1919
diff changeset
81 def __init__(self, host):
b111f6589da4 jp (blog): drafts are now put in a sub dir per profile + added a security which keep the last 10 drafts before removing them (all profiles included).
Goffi <goffi@goffi.org>
parents: 1919
diff changeset
82 self.host = host
b111f6589da4 jp (blog): drafts are now put in a sub dir per profile + added a security which keep the last 10 drafts before removing them (all profiles included).
Goffi <goffi@goffi.org>
parents: 1919
diff changeset
83
2225
301bb52c8715 jp (blog): service and node can now be specified for edit command
Goffi <goffi@goffi.org>
parents: 2164
diff changeset
84 def addServiceNodeArgs(self):
301bb52c8715 jp (blog): service and node can now be specified for edit command
Goffi <goffi@goffi.org>
parents: 2164
diff changeset
85 self.parser.add_argument("-n", "--node", type=base.unicode_decoder, default=u'', help=_(u"PubSub node to request (default: microblog namespace)"))
301bb52c8715 jp (blog): service and node can now be specified for edit command
Goffi <goffi@goffi.org>
parents: 2164
diff changeset
86 self.parser.add_argument("-s", "--service", type=base.unicode_decoder, default=u'', help=_(u"JID of the PubSub service (default: request profile own blog)"))
301bb52c8715 jp (blog): service and node can now be specified for edit command
Goffi <goffi@goffi.org>
parents: 2164
diff changeset
87
1877
a97db84c048d jp (blog): moved common method in a BlogCommon class + added "current" as an item keyword for blog/edit
Goffi <goffi@goffi.org>
parents: 1876
diff changeset
88 def guessSyntaxFromPath(self, sat_conf, path):
a97db84c048d jp (blog): moved common method in a BlogCommon class + added "current" as an item keyword for blog/edit
Goffi <goffi@goffi.org>
parents: 1876
diff changeset
89 """Return syntax guessed according to filename extension
a97db84c048d jp (blog): moved common method in a BlogCommon class + added "current" as an item keyword for blog/edit
Goffi <goffi@goffi.org>
parents: 1876
diff changeset
90
a97db84c048d jp (blog): moved common method in a BlogCommon class + added "current" as an item keyword for blog/edit
Goffi <goffi@goffi.org>
parents: 1876
diff changeset
91 @param sat_conf(ConfigParser.ConfigParser): instance opened on sat configuration
a97db84c048d jp (blog): moved common method in a BlogCommon class + added "current" as an item keyword for blog/edit
Goffi <goffi@goffi.org>
parents: 1876
diff changeset
92 @param path(str): path to the content file
a97db84c048d jp (blog): moved common method in a BlogCommon class + added "current" as an item keyword for blog/edit
Goffi <goffi@goffi.org>
parents: 1876
diff changeset
93 @return(unicode): syntax to use
a97db84c048d jp (blog): moved common method in a BlogCommon class + added "current" as an item keyword for blog/edit
Goffi <goffi@goffi.org>
parents: 1876
diff changeset
94 """
a97db84c048d jp (blog): moved common method in a BlogCommon class + added "current" as an item keyword for blog/edit
Goffi <goffi@goffi.org>
parents: 1876
diff changeset
95 # we first try to guess syntax with extension
a97db84c048d jp (blog): moved common method in a BlogCommon class + added "current" as an item keyword for blog/edit
Goffi <goffi@goffi.org>
parents: 1876
diff changeset
96 ext = os.path.splitext(path)[1][1:] # we get extension without the '.'
a97db84c048d jp (blog): moved common method in a BlogCommon class + added "current" as an item keyword for blog/edit
Goffi <goffi@goffi.org>
parents: 1876
diff changeset
97 if ext:
a97db84c048d jp (blog): moved common method in a BlogCommon class + added "current" as an item keyword for blog/edit
Goffi <goffi@goffi.org>
parents: 1876
diff changeset
98 for k,v in SYNTAX_EXT.iteritems():
1968
eca59bc4e6c6 jp (blog): fixed syntax detection when extension is .txt
Goffi <goffi@goffi.org>
parents: 1929
diff changeset
99 if k and ext == v:
1883
abb2f253188e jp (blog): fixed syntax guessing on existing files
Goffi <goffi@goffi.org>
parents: 1882
diff changeset
100 return k
1877
a97db84c048d jp (blog): moved common method in a BlogCommon class + added "current" as an item keyword for blog/edit
Goffi <goffi@goffi.org>
parents: 1876
diff changeset
101
a97db84c048d jp (blog): moved common method in a BlogCommon class + added "current" as an item keyword for blog/edit
Goffi <goffi@goffi.org>
parents: 1876
diff changeset
102 # if not found, we use current syntax
a97db84c048d jp (blog): moved common method in a BlogCommon class + added "current" as an item keyword for blog/edit
Goffi <goffi@goffi.org>
parents: 1876
diff changeset
103 return self.host.bridge.getParamA("Syntax", "Composition", "value", self.profile)
1874
658824755a0c jp (blog): preview command, first draft
Goffi <goffi@goffi.org>
parents: 1873
diff changeset
104
658824755a0c jp (blog): preview command, first draft
Goffi <goffi@goffi.org>
parents: 1873
diff changeset
105
2458
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
106 class BlogPublishCommon(object):
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
107 """handle common option for publising commands (Set and Edit)"""
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
108
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
109 def add_parser_options(self):
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
110 self.addServiceNodeArgs()
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
111 self.parser.add_argument("-T", '--title', type=base.unicode_decoder, help=_(u"title of the item"))
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
112 self.parser.add_argument("-t", '--tag', type=base.unicode_decoder, action='append', help=_(u"tag (category) of your item"))
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
113 self.parser.add_argument("-C", "--comments", action='store_true', help=_(u"enable comments"))
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
114 self.parser.add_argument("-S", '--syntax', type=base.unicode_decoder, help=_(u"syntax to use (default: get profile's default syntax)"))
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
115
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
116 def setMbDataContent(self, content, mb_data):
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
117 if self.args.syntax is None:
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
118 # default syntax has been used
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
119 mb_data['content_rich'] = content
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
120 elif self.current_syntax == SYNTAX_XHTML:
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
121 mb_data['content_xhtml'] = content
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
122 else:
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
123 mb_data['content_xhtml'] = self.host.bridge.syntaxConvert(content, self.current_syntax, SYNTAX_XHTML, False, self.profile)
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
124
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
125 def setMbDataFromArgs(self, mb_data):
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
126 """set microblog metadata according to command line options
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
127
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
128 if metadata already exist, it will be overwritten
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
129 """
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
130 mb_data['allow_comments'] = C.boolConst(self.args.comments)
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
131 if self.args.tag:
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
132 data_format.iter2dict('tag', self.args.tag, mb_data, check_conflict=False)
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
133 if self.args.title is not None:
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
134 mb_data['title'] = self.args.title
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
135
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
136
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
137 class Set(base.CommandBase, BlogCommon, BlogPublishCommon):
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
138
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
139 def __init__(self, host):
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
140 base.CommandBase.__init__(self, host, 'set', help=_(u'publish a new blog item or update an existing one'))
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
141 BlogCommon.__init__(self, self.host)
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
142 BlogPublishCommon.__init__(self)
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
143 self.need_loop=True
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
144
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
145 def add_parser_options(self):
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
146 BlogPublishCommon.add_parser_options(self)
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
147 self.parser.add_argument("item", type=base.unicode_decoder, nargs='?', default=None, help=_(u"id of the item to publish"))
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
148
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
149 def mbSendCb(self):
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
150 self.disp(u"Item published")
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
151 self.host.quit(C.EXIT_OK)
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
152
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
153 def start(self):
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
154 common.checkURI(self.args)
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
155 self.pubsub_item = self.args.item
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
156 mb_data = {}
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
157 self.setMbDataFromArgs(mb_data)
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
158 content = codecs.getreader('utf-8')(sys.stdin).read()
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
159 self.setMbDataContent(content, mb_data)
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
160
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
161 self.host.bridge.mbSend(
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
162 self.args.service,
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
163 self.args.node,
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
164 mb_data,
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
165 self.profile,
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
166 callback=self.exitCb,
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
167 errback=partial(self.errback,
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
168 msg=_(u"can't send item: {}"),
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
169 exit_code=C.EXIT_BRIDGE_ERRBACK))
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
170
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
171
2225
301bb52c8715 jp (blog): service and node can now be specified for edit command
Goffi <goffi@goffi.org>
parents: 2164
diff changeset
172 class Get(base.CommandBase, BlogCommon):
2164
63d191c05ecd jp (blog): set default template and data mapping for the new template output
Goffi <goffi@goffi.org>
parents: 2161
diff changeset
173 TEMPLATE = u"blog/articles.html"
2157
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
174
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
175 def __init__(self, host):
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
176 extra_outputs = {'default': self.default_output,
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
177 'fancy': self.fancy_output}
2485
512c443a58ba jp (forums): forums handling commands, first draft
Goffi <goffi@goffi.org>
parents: 2483
diff changeset
178 base.CommandBase.__init__(self, host, 'get', use_verbose=True, use_output=C.OUTPUT_COMPLEX, extra_outputs=extra_outputs, help=_(u'get blog item(s)'))
2225
301bb52c8715 jp (blog): service and node can now be specified for edit command
Goffi <goffi@goffi.org>
parents: 2164
diff changeset
179 BlogCommon.__init__(self, self.host)
2157
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
180 self.need_loop=True
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
181
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
182 def add_parser_options(self):
2225
301bb52c8715 jp (blog): service and node can now be specified for edit command
Goffi <goffi@goffi.org>
parents: 2164
diff changeset
183 self.addServiceNodeArgs()
2157
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
184 self.parser.add_argument("-i", "--item", type=base.unicode_decoder, action='append', default=[], dest='items',
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
185 help=_(u"item(s) id(s) to get (default: request all items)"))
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
186 self.parser.add_argument("-m", "--max", type=int, default=10, help=_(u"maximum number of items to get ({} to get all items)".format(C.NO_LIMIT)))
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
187 # TODO: a key(s) argument to select keys to display
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
188 self.parser.add_argument("-k", "--key", type=base.unicode_decoder, action='append', dest='keys',
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
189 help=_(u"microblog data key(s) to display (default: depend of verbosity)"))
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
190 # TODO: add MAM filters
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
191
2164
63d191c05ecd jp (blog): set default template and data mapping for the new template output
Goffi <goffi@goffi.org>
parents: 2161
diff changeset
192 def template_data_mapping(self, data):
63d191c05ecd jp (blog): set default template and data mapping for the new template output
Goffi <goffi@goffi.org>
parents: 2161
diff changeset
193 return {u'items': data_objects.BlogItems(data)}
63d191c05ecd jp (blog): set default template and data mapping for the new template output
Goffi <goffi@goffi.org>
parents: 2161
diff changeset
194
2157
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
195 def format_comments(self, item, keys):
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
196 comments_data = data_format.dict2iterdict(u'comments', item, (u'node', u'service'), pop=True)
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
197 lines = []
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
198 for data in comments_data:
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
199 lines.append(data[u'comments'])
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
200 for k in (u'node', u'service'):
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
201 if OUTPUT_OPT_NO_HEADER in self.args.output_opts:
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
202 header = u''
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
203 else:
2232
4f389486667d jp: added constant to handle ANSI code for header and subheaders
Goffi <goffi@goffi.org>
parents: 2225
diff changeset
204 header = C.A_HEADER + k + u': ' + A.RESET
2157
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
205 lines.append(header + data[k])
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
206 return u'\n'.join(lines)
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
207
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
208 def format_tags(self, item, keys):
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
209 tags = data_format.dict2iter('tag', item, pop=True)
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
210 return u', '.join(tags)
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
211
2158
970a348d3fe9 jp (blog/get): fancy output prints author, published and updated if verbosity > 1 and tags if verbosity > 2 + format published and updated
Goffi <goffi@goffi.org>
parents: 2157
diff changeset
212 def format_updated(self, item, keys):
970a348d3fe9 jp (blog/get): fancy output prints author, published and updated if verbosity > 1 and tags if verbosity > 2 + format published and updated
Goffi <goffi@goffi.org>
parents: 2157
diff changeset
213 return self.format_time(item['updated'])
970a348d3fe9 jp (blog/get): fancy output prints author, published and updated if verbosity > 1 and tags if verbosity > 2 + format published and updated
Goffi <goffi@goffi.org>
parents: 2157
diff changeset
214
970a348d3fe9 jp (blog/get): fancy output prints author, published and updated if verbosity > 1 and tags if verbosity > 2 + format published and updated
Goffi <goffi@goffi.org>
parents: 2157
diff changeset
215 def format_published(self, item, keys):
970a348d3fe9 jp (blog/get): fancy output prints author, published and updated if verbosity > 1 and tags if verbosity > 2 + format published and updated
Goffi <goffi@goffi.org>
parents: 2157
diff changeset
216 return self.format_time(item['published'])
970a348d3fe9 jp (blog/get): fancy output prints author, published and updated if verbosity > 1 and tags if verbosity > 2 + format published and updated
Goffi <goffi@goffi.org>
parents: 2157
diff changeset
217
2327
dad500e7ae50 jp (blog/get): added "url" key, which compute xmpp: URL of items
Goffi <goffi@goffi.org>
parents: 2325
diff changeset
218 def format_url(self, item, keys):
dad500e7ae50 jp (blog/get): added "url" key, which compute xmpp: URL of items
Goffi <goffi@goffi.org>
parents: 2325
diff changeset
219 return uri.buildXMPPUri(u'pubsub',
dad500e7ae50 jp (blog/get): added "url" key, which compute xmpp: URL of items
Goffi <goffi@goffi.org>
parents: 2325
diff changeset
220 subtype=u'microblog',
dad500e7ae50 jp (blog/get): added "url" key, which compute xmpp: URL of items
Goffi <goffi@goffi.org>
parents: 2325
diff changeset
221 path=self.metadata[u'service'],
dad500e7ae50 jp (blog/get): added "url" key, which compute xmpp: URL of items
Goffi <goffi@goffi.org>
parents: 2325
diff changeset
222 node=self.metadata[u'node'],
dad500e7ae50 jp (blog/get): added "url" key, which compute xmpp: URL of items
Goffi <goffi@goffi.org>
parents: 2325
diff changeset
223 item=item[u'id'])
dad500e7ae50 jp (blog/get): added "url" key, which compute xmpp: URL of items
Goffi <goffi@goffi.org>
parents: 2325
diff changeset
224
2157
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
225 def get_keys(self):
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
226 """return keys to display according to verbosity or explicit key request"""
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
227 verbosity = self.args.verbose
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
228 if self.args.keys:
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
229 if not set(MB_KEYS).issuperset(self.args.keys):
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
230 self.disp(u"following keys are invalid: {invalid}.\n"
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
231 u"Valid keys are: {valid}.".format(
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
232 invalid = u', '.join(set(self.args.keys).difference(MB_KEYS)),
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
233 valid = u', '.join(sorted(MB_KEYS))),
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
234 error=True)
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
235 self.host.quit(C.EXIT_BAD_ARG)
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
236 return self.args.keys
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
237 else:
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
238 if verbosity == 0:
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
239 return (u'title', u'content')
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
240 elif verbosity == 1:
2158
970a348d3fe9 jp (blog/get): fancy output prints author, published and updated if verbosity > 1 and tags if verbosity > 2 + format published and updated
Goffi <goffi@goffi.org>
parents: 2157
diff changeset
241 return (u"title", u"tags", u"author", u"author_jid", u"author_email", u"author_jid_verified", u"published", u"updated", u"content")
2157
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
242 else:
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
243 return MB_KEYS
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
244
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
245 def default_output(self, data):
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
246 """simple key/value output"""
2327
dad500e7ae50 jp (blog/get): added "url" key, which compute xmpp: URL of items
Goffi <goffi@goffi.org>
parents: 2325
diff changeset
247 items, self.metadata = data
2157
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
248 keys = self.get_keys()
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
249
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
250 # k_cb use format_[key] methods for complex formattings
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
251 k_cb = {}
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
252 for k in keys:
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
253 try:
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
254 callback = getattr(self, "format_" + k)
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
255 except AttributeError:
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
256 pass
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
257 else:
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
258 k_cb[k] = callback
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
259 for idx, item in enumerate(items):
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
260 for k in keys:
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
261 if k not in item and k not in k_cb:
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
262 continue
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
263 if OUTPUT_OPT_NO_HEADER in self.args.output_opts:
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
264 header = ''
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
265 else:
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
266 header = u"{k_fmt}{key}:{k_fmt_e} {sep}".format(
2232
4f389486667d jp: added constant to handle ANSI code for header and subheaders
Goffi <goffi@goffi.org>
parents: 2225
diff changeset
267 k_fmt = C.A_HEADER,
2157
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
268 key = k,
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
269 k_fmt_e = A.RESET,
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
270 sep = u'\n' if 'content' in k else u'')
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
271 value = k_cb[k](item, keys) if k in k_cb else item[k]
2161
62dfa6e02f54 jp (base, blog, output(std)): fixed bad unicode handling in stdout, use of jp.disp instead of simple print
Goffi <goffi@goffi.org>
parents: 2158
diff changeset
272 self.disp(header + value)
2157
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
273 # we want a separation line after each item but the last one
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
274 if idx < len(items)-1:
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
275 print(u'')
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
276
2158
970a348d3fe9 jp (blog/get): fancy output prints author, published and updated if verbosity > 1 and tags if verbosity > 2 + format published and updated
Goffi <goffi@goffi.org>
parents: 2157
diff changeset
277 def format_time(self, timestamp):
970a348d3fe9 jp (blog/get): fancy output prints author, published and updated if verbosity > 1 and tags if verbosity > 2 + format published and updated
Goffi <goffi@goffi.org>
parents: 2157
diff changeset
278 """return formatted date for timestamp
970a348d3fe9 jp (blog/get): fancy output prints author, published and updated if verbosity > 1 and tags if verbosity > 2 + format published and updated
Goffi <goffi@goffi.org>
parents: 2157
diff changeset
279
970a348d3fe9 jp (blog/get): fancy output prints author, published and updated if verbosity > 1 and tags if verbosity > 2 + format published and updated
Goffi <goffi@goffi.org>
parents: 2157
diff changeset
280 @param timestamp(str,int,float): unix timestamp
970a348d3fe9 jp (blog/get): fancy output prints author, published and updated if verbosity > 1 and tags if verbosity > 2 + format published and updated
Goffi <goffi@goffi.org>
parents: 2157
diff changeset
281 @return (unicode): formatted date
970a348d3fe9 jp (blog/get): fancy output prints author, published and updated if verbosity > 1 and tags if verbosity > 2 + format published and updated
Goffi <goffi@goffi.org>
parents: 2157
diff changeset
282 """
970a348d3fe9 jp (blog/get): fancy output prints author, published and updated if verbosity > 1 and tags if verbosity > 2 + format published and updated
Goffi <goffi@goffi.org>
parents: 2157
diff changeset
283 fmt = u"%d/%m/%Y %H:%M:%S"
970a348d3fe9 jp (blog/get): fancy output prints author, published and updated if verbosity > 1 and tags if verbosity > 2 + format published and updated
Goffi <goffi@goffi.org>
parents: 2157
diff changeset
284 return time.strftime(fmt, time.localtime(float(timestamp)))
970a348d3fe9 jp (blog/get): fancy output prints author, published and updated if verbosity > 1 and tags if verbosity > 2 + format published and updated
Goffi <goffi@goffi.org>
parents: 2157
diff changeset
285
2157
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
286 def fancy_output(self, data):
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
287 """display blog is a nice to read way
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
288
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
289 this output doesn't use keys filter
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
290 """
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
291 # thanks to http://stackoverflow.com/a/943921
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
292 rows, columns = map(int, os.popen('stty size', 'r').read().split())
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
293 items, metadata = data
2158
970a348d3fe9 jp (blog/get): fancy output prints author, published and updated if verbosity > 1 and tags if verbosity > 2 + format published and updated
Goffi <goffi@goffi.org>
parents: 2157
diff changeset
294 verbosity = self.args.verbose
2157
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
295 sep = A.color(A.FG_BLUE, columns * u'▬')
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
296 if items:
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
297 print(u'\n' + sep + '\n')
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
298
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
299 for idx, item in enumerate(items):
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
300 title = item.get(u'title')
2158
970a348d3fe9 jp (blog/get): fancy output prints author, published and updated if verbosity > 1 and tags if verbosity > 2 + format published and updated
Goffi <goffi@goffi.org>
parents: 2157
diff changeset
301 if verbosity > 0:
970a348d3fe9 jp (blog/get): fancy output prints author, published and updated if verbosity > 1 and tags if verbosity > 2 + format published and updated
Goffi <goffi@goffi.org>
parents: 2157
diff changeset
302 author = item[u'author']
970a348d3fe9 jp (blog/get): fancy output prints author, published and updated if verbosity > 1 and tags if verbosity > 2 + format published and updated
Goffi <goffi@goffi.org>
parents: 2157
diff changeset
303 published, updated = item[u'published'], item.get('updated')
970a348d3fe9 jp (blog/get): fancy output prints author, published and updated if verbosity > 1 and tags if verbosity > 2 + format published and updated
Goffi <goffi@goffi.org>
parents: 2157
diff changeset
304 else:
970a348d3fe9 jp (blog/get): fancy output prints author, published and updated if verbosity > 1 and tags if verbosity > 2 + format published and updated
Goffi <goffi@goffi.org>
parents: 2157
diff changeset
305 author = published = updated = None
970a348d3fe9 jp (blog/get): fancy output prints author, published and updated if verbosity > 1 and tags if verbosity > 2 + format published and updated
Goffi <goffi@goffi.org>
parents: 2157
diff changeset
306 if verbosity > 1:
970a348d3fe9 jp (blog/get): fancy output prints author, published and updated if verbosity > 1 and tags if verbosity > 2 + format published and updated
Goffi <goffi@goffi.org>
parents: 2157
diff changeset
307 tags = list(data_format.dict2iter('tag', item, pop=True))
970a348d3fe9 jp (blog/get): fancy output prints author, published and updated if verbosity > 1 and tags if verbosity > 2 + format published and updated
Goffi <goffi@goffi.org>
parents: 2157
diff changeset
308 else:
970a348d3fe9 jp (blog/get): fancy output prints author, published and updated if verbosity > 1 and tags if verbosity > 2 + format published and updated
Goffi <goffi@goffi.org>
parents: 2157
diff changeset
309 tags = None
2157
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
310 content = item.get(u'content')
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
311
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
312 if title:
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
313 print(A.color(A.BOLD, A.FG_CYAN, item[u'title']))
2158
970a348d3fe9 jp (blog/get): fancy output prints author, published and updated if verbosity > 1 and tags if verbosity > 2 + format published and updated
Goffi <goffi@goffi.org>
parents: 2157
diff changeset
314 meta = []
970a348d3fe9 jp (blog/get): fancy output prints author, published and updated if verbosity > 1 and tags if verbosity > 2 + format published and updated
Goffi <goffi@goffi.org>
parents: 2157
diff changeset
315 if author:
970a348d3fe9 jp (blog/get): fancy output prints author, published and updated if verbosity > 1 and tags if verbosity > 2 + format published and updated
Goffi <goffi@goffi.org>
parents: 2157
diff changeset
316 meta.append(A.color(A.FG_YELLOW, author))
970a348d3fe9 jp (blog/get): fancy output prints author, published and updated if verbosity > 1 and tags if verbosity > 2 + format published and updated
Goffi <goffi@goffi.org>
parents: 2157
diff changeset
317 if published:
970a348d3fe9 jp (blog/get): fancy output prints author, published and updated if verbosity > 1 and tags if verbosity > 2 + format published and updated
Goffi <goffi@goffi.org>
parents: 2157
diff changeset
318 meta.append(A.color(A.FG_YELLOW, u'on ', self.format_time(published)))
970a348d3fe9 jp (blog/get): fancy output prints author, published and updated if verbosity > 1 and tags if verbosity > 2 + format published and updated
Goffi <goffi@goffi.org>
parents: 2157
diff changeset
319 if updated != published:
970a348d3fe9 jp (blog/get): fancy output prints author, published and updated if verbosity > 1 and tags if verbosity > 2 + format published and updated
Goffi <goffi@goffi.org>
parents: 2157
diff changeset
320 meta.append(A.color(A.FG_YELLOW, u'(updated on ', self.format_time(updated), u')'))
970a348d3fe9 jp (blog/get): fancy output prints author, published and updated if verbosity > 1 and tags if verbosity > 2 + format published and updated
Goffi <goffi@goffi.org>
parents: 2157
diff changeset
321 print(u' '.join(meta))
2157
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
322 if tags:
2158
970a348d3fe9 jp (blog/get): fancy output prints author, published and updated if verbosity > 1 and tags if verbosity > 2 + format published and updated
Goffi <goffi@goffi.org>
parents: 2157
diff changeset
323 print(A.color(A.FG_MAGENTA, u', '.join(tags)))
2157
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
324 if (title or tags) and content:
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
325 print("")
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
326 if content:
2161
62dfa6e02f54 jp (base, blog, output(std)): fixed bad unicode handling in stdout, use of jp.disp instead of simple print
Goffi <goffi@goffi.org>
parents: 2158
diff changeset
327 self.disp(content)
2157
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
328
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
329 print(u'\n' + sep + '\n')
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
330
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
331
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
332 def mbGetCb(self, mb_result):
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
333 self.output(mb_result)
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
334 self.host.quit(C.EXIT_OK)
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
335
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
336 def mbGetEb(self, failure_):
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
337 self.disp(u"can't get blog items: {reason}".format(
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
338 reason=failure_), error=True)
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
339 self.host.quit(C.EXIT_BRIDGE_ERRBACK)
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
340
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
341 def start(self):
2284
4fd010f29f99 jp (blog, event): added checkURI to some command to be able to enter a xmpp: uri as argument
Goffi <goffi@goffi.org>
parents: 2280
diff changeset
342 common.checkURI(self.args)
2157
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
343 self.host.bridge.mbGet(
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
344 self.args.service,
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
345 self.args.node,
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
346 self.args.max,
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
347 self.args.items,
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
348 {},
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
349 self.profile,
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
350 callback=self.mbGetCb,
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
351 errback=self.mbGetEb)
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
352
b4a515e36631 jp (blog): added blog/get command:
Goffi <goffi@goffi.org>
parents: 1969
diff changeset
353
2458
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
354 class Edit(base.CommandBase, BlogCommon, BlogPublishCommon, common.BaseEdit):
1866
397ef87958b9 jp (blog): edit command, first draft:
Goffi <goffi@goffi.org>
parents: 1864
diff changeset
355
397ef87958b9 jp (blog): edit command, first draft:
Goffi <goffi@goffi.org>
parents: 1864
diff changeset
356 def __init__(self, host):
1921
b111f6589da4 jp (blog): drafts are now put in a sub dir per profile + added a security which keep the last 10 drafts before removing them (all profiles included).
Goffi <goffi@goffi.org>
parents: 1919
diff changeset
357 base.CommandBase.__init__(self, host, 'edit', use_verbose=True, help=_(u'edit an existing or new blog post'))
b111f6589da4 jp (blog): drafts are now put in a sub dir per profile + added a security which keep the last 10 drafts before removing them (all profiles included).
Goffi <goffi@goffi.org>
parents: 1919
diff changeset
358 BlogCommon.__init__(self, self.host)
2458
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
359 BlogPublishCommon.__init__(self)
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents: 2267
diff changeset
360 common.BaseEdit.__init__(self, self.host, BLOG_TMP_DIR, use_metadata=True)
1866
397ef87958b9 jp (blog): edit command, first draft:
Goffi <goffi@goffi.org>
parents: 1864
diff changeset
361
397ef87958b9 jp (blog): edit command, first draft:
Goffi <goffi@goffi.org>
parents: 1864
diff changeset
362 def add_parser_options(self):
2458
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
363 BlogPublishCommon.add_parser_options(self)
1887
16527dd5a81b blog (jp/edit): added --preview option to launch a "blog preview" in parallel
Goffi <goffi@goffi.org>
parents: 1886
diff changeset
364 self.parser.add_argument("-P", "--preview", action="store_true", help=_(u"launch a blog preview in parallel"))
2458
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
365 self.parser.add_argument("item", type=base.unicode_decoder, nargs='?', default=u'new', help=_(u"URL of the item to edit, or keyword"))
2270
07caa12be945 jp (blog, common): added --force-item option to avoid magic and use argument as actual item id:
Goffi <goffi@goffi.org>
parents: 2269
diff changeset
366 common.BaseEdit.add_parser_options(self)
1866
397ef87958b9 jp (blog): edit command, first draft:
Goffi <goffi@goffi.org>
parents: 1864
diff changeset
367
1872
df1ca137b0cb jp (blog/edit): editor arguments can now be specified on sat.conf, and default on are applied for known editors:
Goffi <goffi@goffi.org>
parents: 1871
diff changeset
368 def buildMetadataFile(self, content_file_path, mb_data=None):
1868
28b29381db75 jp (blog/edit): added metadata handling through a .json file (named like content temporary file, but with extension replaced by "_metadata.json"). Modification to this file before the end of edition will be taken into account.
Goffi <goffi@goffi.org>
parents: 1866
diff changeset
369 """Build a metadata file using json
28b29381db75 jp (blog/edit): added metadata handling through a .json file (named like content temporary file, but with extension replaced by "_metadata.json"). Modification to this file before the end of edition will be taken into account.
Goffi <goffi@goffi.org>
parents: 1866
diff changeset
370
1872
df1ca137b0cb jp (blog/edit): editor arguments can now be specified on sat.conf, and default on are applied for known editors:
Goffi <goffi@goffi.org>
parents: 1871
diff changeset
371 The file is named after content_file_path, with extension replaced by _metadata.json
df1ca137b0cb jp (blog/edit): editor arguments can now be specified on sat.conf, and default on are applied for known editors:
Goffi <goffi@goffi.org>
parents: 1871
diff changeset
372 @param content_file_path(str): path to the temporary file which will contain the body
1868
28b29381db75 jp (blog/edit): added metadata handling through a .json file (named like content temporary file, but with extension replaced by "_metadata.json"). Modification to this file before the end of edition will be taken into account.
Goffi <goffi@goffi.org>
parents: 1866
diff changeset
373 @param mb_data(dict, None): microblog metadata (for existing items)
28b29381db75 jp (blog/edit): added metadata handling through a .json file (named like content temporary file, but with extension replaced by "_metadata.json"). Modification to this file before the end of edition will be taken into account.
Goffi <goffi@goffi.org>
parents: 1866
diff changeset
374 @return (tuple[dict, str]): merged metadata put originaly in metadata file
28b29381db75 jp (blog/edit): added metadata handling through a .json file (named like content temporary file, but with extension replaced by "_metadata.json"). Modification to this file before the end of edition will be taken into account.
Goffi <goffi@goffi.org>
parents: 1866
diff changeset
375 and path to temporary metadata file
28b29381db75 jp (blog/edit): added metadata handling through a .json file (named like content temporary file, but with extension replaced by "_metadata.json"). Modification to this file before the end of edition will be taken into account.
Goffi <goffi@goffi.org>
parents: 1866
diff changeset
376 """
28b29381db75 jp (blog/edit): added metadata handling through a .json file (named like content temporary file, but with extension replaced by "_metadata.json"). Modification to this file before the end of edition will be taken into account.
Goffi <goffi@goffi.org>
parents: 1866
diff changeset
377 # we first construct metadata from edited item ones and CLI argumments
1876
1088bf7b28e7 jp (blog/edit): metadata file is reused if it already exists
Goffi <goffi@goffi.org>
parents: 1874
diff changeset
378 # or re-use the existing one if it exists
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents: 2267
diff changeset
379 meta_file_path = os.path.splitext(content_file_path)[0] + common.METADATA_SUFF
1876
1088bf7b28e7 jp (blog/edit): metadata file is reused if it already exists
Goffi <goffi@goffi.org>
parents: 1874
diff changeset
380 if os.path.exists(meta_file_path):
1088bf7b28e7 jp (blog/edit): metadata file is reused if it already exists
Goffi <goffi@goffi.org>
parents: 1874
diff changeset
381 self.disp(u"Metadata file already exists, we re-use it")
1088bf7b28e7 jp (blog/edit): metadata file is reused if it already exists
Goffi <goffi@goffi.org>
parents: 1874
diff changeset
382 try:
1088bf7b28e7 jp (blog/edit): metadata file is reused if it already exists
Goffi <goffi@goffi.org>
parents: 1874
diff changeset
383 with open(meta_file_path, 'rb') as f:
1088bf7b28e7 jp (blog/edit): metadata file is reused if it already exists
Goffi <goffi@goffi.org>
parents: 1874
diff changeset
384 mb_data = json.load(f)
1088bf7b28e7 jp (blog/edit): metadata file is reused if it already exists
Goffi <goffi@goffi.org>
parents: 1874
diff changeset
385 except (OSError, IOError, ValueError) as e:
1088bf7b28e7 jp (blog/edit): metadata file is reused if it already exists
Goffi <goffi@goffi.org>
parents: 1874
diff changeset
386 self.disp(u"Can't read existing metadata file at {path}, aborting: {reason}".format(
1088bf7b28e7 jp (blog/edit): metadata file is reused if it already exists
Goffi <goffi@goffi.org>
parents: 1874
diff changeset
387 path=meta_file_path, reason=e), error=True)
1088bf7b28e7 jp (blog/edit): metadata file is reused if it already exists
Goffi <goffi@goffi.org>
parents: 1874
diff changeset
388 self.host.quit(1)
1088bf7b28e7 jp (blog/edit): metadata file is reused if it already exists
Goffi <goffi@goffi.org>
parents: 1874
diff changeset
389 else:
1088bf7b28e7 jp (blog/edit): metadata file is reused if it already exists
Goffi <goffi@goffi.org>
parents: 1874
diff changeset
390 mb_data = {} if mb_data is None else mb_data.copy()
1088bf7b28e7 jp (blog/edit): metadata file is reused if it already exists
Goffi <goffi@goffi.org>
parents: 1874
diff changeset
391
1088bf7b28e7 jp (blog/edit): metadata file is reused if it already exists
Goffi <goffi@goffi.org>
parents: 1874
diff changeset
392 # in all cases, we want to remove unwanted keys
1868
28b29381db75 jp (blog/edit): added metadata handling through a .json file (named like content temporary file, but with extension replaced by "_metadata.json"). Modification to this file before the end of edition will be taken into account.
Goffi <goffi@goffi.org>
parents: 1866
diff changeset
393 for key in KEY_TO_REMOVE_METADATA:
28b29381db75 jp (blog/edit): added metadata handling through a .json file (named like content temporary file, but with extension replaced by "_metadata.json"). Modification to this file before the end of edition will be taken into account.
Goffi <goffi@goffi.org>
parents: 1866
diff changeset
394 try:
28b29381db75 jp (blog/edit): added metadata handling through a .json file (named like content temporary file, but with extension replaced by "_metadata.json"). Modification to this file before the end of edition will be taken into account.
Goffi <goffi@goffi.org>
parents: 1866
diff changeset
395 del mb_data[key]
28b29381db75 jp (blog/edit): added metadata handling through a .json file (named like content temporary file, but with extension replaced by "_metadata.json"). Modification to this file before the end of edition will be taken into account.
Goffi <goffi@goffi.org>
parents: 1866
diff changeset
396 except KeyError:
28b29381db75 jp (blog/edit): added metadata handling through a .json file (named like content temporary file, but with extension replaced by "_metadata.json"). Modification to this file before the end of edition will be taken into account.
Goffi <goffi@goffi.org>
parents: 1866
diff changeset
397 pass
1876
1088bf7b28e7 jp (blog/edit): metadata file is reused if it already exists
Goffi <goffi@goffi.org>
parents: 1874
diff changeset
398 # and override metadata with command-line arguments
2458
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
399 self.setMbDataFromArgs(mb_data)
1868
28b29381db75 jp (blog/edit): added metadata handling through a .json file (named like content temporary file, but with extension replaced by "_metadata.json"). Modification to this file before the end of edition will be taken into account.
Goffi <goffi@goffi.org>
parents: 1866
diff changeset
400
1876
1088bf7b28e7 jp (blog/edit): metadata file is reused if it already exists
Goffi <goffi@goffi.org>
parents: 1874
diff changeset
401 # then we create the file and write metadata there, as JSON dict
1868
28b29381db75 jp (blog/edit): added metadata handling through a .json file (named like content temporary file, but with extension replaced by "_metadata.json"). Modification to this file before the end of edition will be taken into account.
Goffi <goffi@goffi.org>
parents: 1866
diff changeset
402 # XXX: if we port jp one day on Windows, O_BINARY may need to be added here
1927
03f780b60d5d jp (blog/edit): added forgotten O_TRUNC while opening metadata file
Goffi <goffi@goffi.org>
parents: 1926
diff changeset
403 with os.fdopen(os.open(meta_file_path, os.O_RDWR | os.O_CREAT | os.O_TRUNC,0o600), 'w+b') as f:
1868
28b29381db75 jp (blog/edit): added metadata handling through a .json file (named like content temporary file, but with extension replaced by "_metadata.json"). Modification to this file before the end of edition will be taken into account.
Goffi <goffi@goffi.org>
parents: 1866
diff changeset
404 # we need to use an intermediate unicode buffer to write to the file unicode without escaping characters
28b29381db75 jp (blog/edit): added metadata handling through a .json file (named like content temporary file, but with extension replaced by "_metadata.json"). Modification to this file before the end of edition will be taken into account.
Goffi <goffi@goffi.org>
parents: 1866
diff changeset
405 unicode_dump = json.dumps(mb_data, ensure_ascii=False, indent=4, separators=(',', ': '), sort_keys=True)
28b29381db75 jp (blog/edit): added metadata handling through a .json file (named like content temporary file, but with extension replaced by "_metadata.json"). Modification to this file before the end of edition will be taken into account.
Goffi <goffi@goffi.org>
parents: 1866
diff changeset
406 f.write(unicode_dump.encode('utf-8'))
28b29381db75 jp (blog/edit): added metadata handling through a .json file (named like content temporary file, but with extension replaced by "_metadata.json"). Modification to this file before the end of edition will be taken into account.
Goffi <goffi@goffi.org>
parents: 1866
diff changeset
407
28b29381db75 jp (blog/edit): added metadata handling through a .json file (named like content temporary file, but with extension replaced by "_metadata.json"). Modification to this file before the end of edition will be taken into account.
Goffi <goffi@goffi.org>
parents: 1866
diff changeset
408 return mb_data, meta_file_path
28b29381db75 jp (blog/edit): added metadata handling through a .json file (named like content temporary file, but with extension replaced by "_metadata.json"). Modification to this file before the end of edition will be taken into account.
Goffi <goffi@goffi.org>
parents: 1866
diff changeset
409
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents: 2267
diff changeset
410 def edit(self, content_file_path, content_file_obj,
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents: 2267
diff changeset
411 mb_data=None):
1866
397ef87958b9 jp (blog): edit command, first draft:
Goffi <goffi@goffi.org>
parents: 1864
diff changeset
412 """Edit the file contening the content using editor, and publish it"""
1868
28b29381db75 jp (blog/edit): added metadata handling through a .json file (named like content temporary file, but with extension replaced by "_metadata.json"). Modification to this file before the end of edition will be taken into account.
Goffi <goffi@goffi.org>
parents: 1866
diff changeset
413 # we first create metadata file
2270
07caa12be945 jp (blog, common): added --force-item option to avoid magic and use argument as actual item id:
Goffi <goffi@goffi.org>
parents: 2269
diff changeset
414 meta_ori, meta_file_path = self.buildMetadataFile(content_file_path, mb_data)
1866
397ef87958b9 jp (blog): edit command, first draft:
Goffi <goffi@goffi.org>
parents: 1864
diff changeset
415
1887
16527dd5a81b blog (jp/edit): added --preview option to launch a "blog preview" in parallel
Goffi <goffi@goffi.org>
parents: 1886
diff changeset
416 # do we need a preview ?
16527dd5a81b blog (jp/edit): added --preview option to launch a "blog preview" in parallel
Goffi <goffi@goffi.org>
parents: 1886
diff changeset
417 if self.args.preview:
16527dd5a81b blog (jp/edit): added --preview option to launch a "blog preview" in parallel
Goffi <goffi@goffi.org>
parents: 1886
diff changeset
418 self.disp(u"Preview requested, launching it", 1)
16527dd5a81b blog (jp/edit): added --preview option to launch a "blog preview" in parallel
Goffi <goffi@goffi.org>
parents: 1886
diff changeset
419 # we redirect outputs to /dev/null to avoid console pollution in editor
16527dd5a81b blog (jp/edit): added --preview option to launch a "blog preview" in parallel
Goffi <goffi@goffi.org>
parents: 1886
diff changeset
420 # if user wants to see messages, (s)he can call "blog preview" directly
16527dd5a81b blog (jp/edit): added --preview option to launch a "blog preview" in parallel
Goffi <goffi@goffi.org>
parents: 1886
diff changeset
421 DEVNULL = open(os.devnull, 'wb')
1894
116a55865364 frontends (jp / blog): pass the profile to subprocess when using option --preview
souliane <souliane@mailoo.org>
parents: 1893
diff changeset
422 subprocess.Popen([sys.argv[0], "blog", "preview", "--inotify", "true", "-p", self.profile, content_file_path], stdout=DEVNULL, stderr=subprocess.STDOUT)
1887
16527dd5a81b blog (jp/edit): added --preview option to launch a "blog preview" in parallel
Goffi <goffi@goffi.org>
parents: 1886
diff changeset
423
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents: 2267
diff changeset
424 # we launch editor
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents: 2267
diff changeset
425 self.runEditor("blog_editor_args", content_file_path, content_file_obj, meta_file_path=meta_file_path, meta_ori=meta_ori)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents: 2267
diff changeset
426
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents: 2267
diff changeset
427 def publish(self, content, mb_data):
2458
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
428 self.setMbDataContent(content, mb_data)
1866
397ef87958b9 jp (blog): edit command, first draft:
Goffi <goffi@goffi.org>
parents: 1864
diff changeset
429
2270
07caa12be945 jp (blog, common): added --force-item option to avoid magic and use argument as actual item id:
Goffi <goffi@goffi.org>
parents: 2269
diff changeset
430 if self.pubsub_item is not None:
07caa12be945 jp (blog, common): added --force-item option to avoid magic and use argument as actual item id:
Goffi <goffi@goffi.org>
parents: 2269
diff changeset
431 mb_data['id'] = self.pubsub_item
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents: 2267
diff changeset
432
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents: 2267
diff changeset
433 self.host.bridge.mbSend(self.pubsub_service, self.pubsub_node, mb_data, self.profile)
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents: 2267
diff changeset
434 self.disp(u"Blog item published")
1866
397ef87958b9 jp (blog): edit command, first draft:
Goffi <goffi@goffi.org>
parents: 1864
diff changeset
435
2458
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
436
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents: 2267
diff changeset
437 def getTmpSuff(self):
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents: 2267
diff changeset
438 # we get current syntax to determine file extension
2325
760df3a58c24 jp (blog/edit): syntax modifications:
Goffi <goffi@goffi.org>
parents: 2284
diff changeset
439 if self.current_syntax is None:
760df3a58c24 jp (blog/edit): syntax modifications:
Goffi <goffi@goffi.org>
parents: 2284
diff changeset
440 self.current_syntax = self.host.bridge.getParamA("Syntax", "Composition", "value", self.profile)
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents: 2267
diff changeset
441 return SYNTAX_EXT.get(self.current_syntax, SYNTAX_EXT[''])
1866
397ef87958b9 jp (blog): edit command, first draft:
Goffi <goffi@goffi.org>
parents: 1864
diff changeset
442
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents: 2267
diff changeset
443 def getItemData(self, service, node, item):
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents: 2267
diff changeset
444 items = [item] if item is not None else []
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents: 2267
diff changeset
445 mb_data = self.host.bridge.mbGet(service, node, 1, items, {}, self.profile)[0][0]
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents: 2267
diff changeset
446 try:
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents: 2267
diff changeset
447 content = mb_data['content_xhtml']
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents: 2267
diff changeset
448 except KeyError:
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents: 2267
diff changeset
449 content = mb_data['content']
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents: 2267
diff changeset
450 if content:
2330
74c1dbabeec8 jp (blog/edit): pretty format XHTML before editing it
Goffi <goffi@goffi.org>
parents: 2327
diff changeset
451 content = self.host.bridge.syntaxConvert(content, 'text', SYNTAX_XHTML, False, self.profile)
74c1dbabeec8 jp (blog/edit): pretty format XHTML before editing it
Goffi <goffi@goffi.org>
parents: 2327
diff changeset
452 if content and self.current_syntax != SYNTAX_XHTML:
74c1dbabeec8 jp (blog/edit): pretty format XHTML before editing it
Goffi <goffi@goffi.org>
parents: 2327
diff changeset
453 content = self.host.bridge.syntaxConvert(content, SYNTAX_XHTML, self.current_syntax, False, self.profile)
74c1dbabeec8 jp (blog/edit): pretty format XHTML before editing it
Goffi <goffi@goffi.org>
parents: 2327
diff changeset
454 if content and self.current_syntax == SYNTAX_XHTML:
74c1dbabeec8 jp (blog/edit): pretty format XHTML before editing it
Goffi <goffi@goffi.org>
parents: 2327
diff changeset
455 try:
74c1dbabeec8 jp (blog/edit): pretty format XHTML before editing it
Goffi <goffi@goffi.org>
parents: 2327
diff changeset
456 from lxml import etree
74c1dbabeec8 jp (blog/edit): pretty format XHTML before editing it
Goffi <goffi@goffi.org>
parents: 2327
diff changeset
457 except ImportError:
74c1dbabeec8 jp (blog/edit): pretty format XHTML before editing it
Goffi <goffi@goffi.org>
parents: 2327
diff changeset
458 self.disp(_(u"You need lxml to edit pretty XHTML"))
74c1dbabeec8 jp (blog/edit): pretty format XHTML before editing it
Goffi <goffi@goffi.org>
parents: 2327
diff changeset
459 else:
74c1dbabeec8 jp (blog/edit): pretty format XHTML before editing it
Goffi <goffi@goffi.org>
parents: 2327
diff changeset
460 parser = etree.XMLParser(remove_blank_text=True)
74c1dbabeec8 jp (blog/edit): pretty format XHTML before editing it
Goffi <goffi@goffi.org>
parents: 2327
diff changeset
461 root = etree.fromstring(content, parser)
74c1dbabeec8 jp (blog/edit): pretty format XHTML before editing it
Goffi <goffi@goffi.org>
parents: 2327
diff changeset
462 content = etree.tostring(root, encoding=unicode, pretty_print=True)
74c1dbabeec8 jp (blog/edit): pretty format XHTML before editing it
Goffi <goffi@goffi.org>
parents: 2327
diff changeset
463
2280
4bc9a2c2d6c9 jp (pubsub, common): fixed last item edition (keep item id instead of creating a new one)
Goffi <goffi@goffi.org>
parents: 2273
diff changeset
464 return content, mb_data, mb_data['id']
1866
397ef87958b9 jp (blog): edit command, first draft:
Goffi <goffi@goffi.org>
parents: 1864
diff changeset
465
397ef87958b9 jp (blog): edit command, first draft:
Goffi <goffi@goffi.org>
parents: 1864
diff changeset
466 def start(self):
397ef87958b9 jp (blog): edit command, first draft:
Goffi <goffi@goffi.org>
parents: 1864
diff changeset
467 # if there are user defined extension, we use them
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents: 2267
diff changeset
468 SYNTAX_EXT.update(config.getConfig(self.sat_conf, 'jp', CONF_SYNTAX_EXT, {}))
2325
760df3a58c24 jp (blog/edit): syntax modifications:
Goffi <goffi@goffi.org>
parents: 2284
diff changeset
469 self.current_syntax = self.args.syntax
760df3a58c24 jp (blog/edit): syntax modifications:
Goffi <goffi@goffi.org>
parents: 2284
diff changeset
470 if self.current_syntax is not None:
760df3a58c24 jp (blog/edit): syntax modifications:
Goffi <goffi@goffi.org>
parents: 2284
diff changeset
471 try:
760df3a58c24 jp (blog/edit): syntax modifications:
Goffi <goffi@goffi.org>
parents: 2284
diff changeset
472 self.current_syntax = self.args.syntax = self.host.bridge.syntaxGet(self.current_syntax)
760df3a58c24 jp (blog/edit): syntax modifications:
Goffi <goffi@goffi.org>
parents: 2284
diff changeset
473 except Exception as e:
760df3a58c24 jp (blog/edit): syntax modifications:
Goffi <goffi@goffi.org>
parents: 2284
diff changeset
474 if "NotFound" in unicode(e): # FIXME: there is not good way to check bridge errors
760df3a58c24 jp (blog/edit): syntax modifications:
Goffi <goffi@goffi.org>
parents: 2284
diff changeset
475 self.parser.error(_(u"unknown syntax requested ({syntax})").format(syntax=self.args.syntax))
760df3a58c24 jp (blog/edit): syntax modifications:
Goffi <goffi@goffi.org>
parents: 2284
diff changeset
476 else:
760df3a58c24 jp (blog/edit): syntax modifications:
Goffi <goffi@goffi.org>
parents: 2284
diff changeset
477 raise e
2225
301bb52c8715 jp (blog): service and node can now be specified for edit command
Goffi <goffi@goffi.org>
parents: 2164
diff changeset
478
2270
07caa12be945 jp (blog, common): added --force-item option to avoid magic and use argument as actual item id:
Goffi <goffi@goffi.org>
parents: 2269
diff changeset
479 self.pubsub_service, self.pubsub_node, self.pubsub_item, content_file_path, content_file_obj, mb_data = self.getItemPath(self.args.item)
1925
53b51866747f jp (blog/edit): HTTP(S) and XMPP URLs can now be directly used in blog/edit command
Goffi <goffi@goffi.org>
parents: 1924
diff changeset
480
2269
606ff34d30f2 jp (blog, common): moved and improved edit code from blog:
Goffi <goffi@goffi.org>
parents: 2267
diff changeset
481 self.edit(content_file_path, content_file_obj, mb_data=mb_data)
1827
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
482
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
483
1877
a97db84c048d jp (blog): moved common method in a BlogCommon class + added "current" as an item keyword for blog/edit
Goffi <goffi@goffi.org>
parents: 1876
diff changeset
484 class Preview(base.CommandBase, BlogCommon):
1874
658824755a0c jp (blog): preview command, first draft
Goffi <goffi@goffi.org>
parents: 1873
diff changeset
485
658824755a0c jp (blog): preview command, first draft
Goffi <goffi@goffi.org>
parents: 1873
diff changeset
486 def __init__(self, host):
1921
b111f6589da4 jp (blog): drafts are now put in a sub dir per profile + added a security which keep the last 10 drafts before removing them (all profiles included).
Goffi <goffi@goffi.org>
parents: 1919
diff changeset
487 base.CommandBase.__init__(self, host, 'preview', use_verbose=True, help=_(u'preview a blog content'))
b111f6589da4 jp (blog): drafts are now put in a sub dir per profile + added a security which keep the last 10 drafts before removing them (all profiles included).
Goffi <goffi@goffi.org>
parents: 1919
diff changeset
488 BlogCommon.__init__(self, self.host)
1874
658824755a0c jp (blog): preview command, first draft
Goffi <goffi@goffi.org>
parents: 1873
diff changeset
489
658824755a0c jp (blog): preview command, first draft
Goffi <goffi@goffi.org>
parents: 1873
diff changeset
490 def add_parser_options(self):
1882
ed444e9aa078 jp (blog/preview): added inotify support, so preview can be updated each time the file is modified (actually IN_CLOSE_WRITE is used, but this may change in the future)
Goffi <goffi@goffi.org>
parents: 1881
diff changeset
491 self.parser.add_argument("--inotify", type=str, choices=('auto', 'true', 'false'), default=u'auto', help=_(u"use inotify to handle preview"))
1874
658824755a0c jp (blog): preview command, first draft
Goffi <goffi@goffi.org>
parents: 1873
diff changeset
492 self.parser.add_argument("file", type=base.unicode_decoder, nargs='?', default=u'current', help=_(u"path to the content file"))
658824755a0c jp (blog): preview command, first draft
Goffi <goffi@goffi.org>
parents: 1873
diff changeset
493
1882
ed444e9aa078 jp (blog/preview): added inotify support, so preview can be updated each time the file is modified (actually IN_CLOSE_WRITE is used, but this may change in the future)
Goffi <goffi@goffi.org>
parents: 1881
diff changeset
494 def showPreview(self):
2271
2fae89f30b8d jp (blog): minor typo fix
Goffi <goffi@goffi.org>
parents: 2270
diff changeset
495 # we implement showPreview here so we don't have to import webbrowser and urllib
1882
ed444e9aa078 jp (blog/preview): added inotify support, so preview can be updated each time the file is modified (actually IN_CLOSE_WRITE is used, but this may change in the future)
Goffi <goffi@goffi.org>
parents: 1881
diff changeset
496 # when preview is not used
ed444e9aa078 jp (blog/preview): added inotify support, so preview can be updated each time the file is modified (actually IN_CLOSE_WRITE is used, but this may change in the future)
Goffi <goffi@goffi.org>
parents: 1881
diff changeset
497 url = 'file:{}'.format(self.urllib.quote(self.preview_file_path))
ed444e9aa078 jp (blog/preview): added inotify support, so preview can be updated each time the file is modified (actually IN_CLOSE_WRITE is used, but this may change in the future)
Goffi <goffi@goffi.org>
parents: 1881
diff changeset
498 self.webbrowser.open_new_tab(url)
ed444e9aa078 jp (blog/preview): added inotify support, so preview can be updated each time the file is modified (actually IN_CLOSE_WRITE is used, but this may change in the future)
Goffi <goffi@goffi.org>
parents: 1881
diff changeset
499
1885
edd8dc8df1b9 jp (blog/preview): open and preview commands can be changed in sat.conf with "blog_preview_open_cmd" and "blog_preview_update_cmd" in [jp] section + don't convert syntax when content is empty
Goffi <goffi@goffi.org>
parents: 1883
diff changeset
500 def _launchPreviewExt(self, cmd_line, opt_name):
edd8dc8df1b9 jp (blog/preview): open and preview commands can be changed in sat.conf with "blog_preview_open_cmd" and "blog_preview_update_cmd" in [jp] section + don't convert syntax when content is empty
Goffi <goffi@goffi.org>
parents: 1883
diff changeset
501 url = 'file:{}'.format(self.urllib.quote(self.preview_file_path))
2273
5f0dbf42aa9c jp (blog, common): various fixes in common and blog:
Goffi <goffi@goffi.org>
parents: 2271
diff changeset
502 args = common.parse_args(self.host, cmd_line, url=url, preview_file=self.preview_file_path)
1885
edd8dc8df1b9 jp (blog/preview): open and preview commands can be changed in sat.conf with "blog_preview_open_cmd" and "blog_preview_update_cmd" in [jp] section + don't convert syntax when content is empty
Goffi <goffi@goffi.org>
parents: 1883
diff changeset
503 if not args:
edd8dc8df1b9 jp (blog/preview): open and preview commands can be changed in sat.conf with "blog_preview_open_cmd" and "blog_preview_update_cmd" in [jp] section + don't convert syntax when content is empty
Goffi <goffi@goffi.org>
parents: 1883
diff changeset
504 self.disp(u"Couln't find command in \"{name}\", abording".format(name=opt_name), error=True)
edd8dc8df1b9 jp (blog/preview): open and preview commands can be changed in sat.conf with "blog_preview_open_cmd" and "blog_preview_update_cmd" in [jp] section + don't convert syntax when content is empty
Goffi <goffi@goffi.org>
parents: 1883
diff changeset
505 self.host.quit(1)
edd8dc8df1b9 jp (blog/preview): open and preview commands can be changed in sat.conf with "blog_preview_open_cmd" and "blog_preview_update_cmd" in [jp] section + don't convert syntax when content is empty
Goffi <goffi@goffi.org>
parents: 1883
diff changeset
506 subprocess.Popen(args)
edd8dc8df1b9 jp (blog/preview): open and preview commands can be changed in sat.conf with "blog_preview_open_cmd" and "blog_preview_update_cmd" in [jp] section + don't convert syntax when content is empty
Goffi <goffi@goffi.org>
parents: 1883
diff changeset
507
edd8dc8df1b9 jp (blog/preview): open and preview commands can be changed in sat.conf with "blog_preview_open_cmd" and "blog_preview_update_cmd" in [jp] section + don't convert syntax when content is empty
Goffi <goffi@goffi.org>
parents: 1883
diff changeset
508 def openPreviewExt(self):
edd8dc8df1b9 jp (blog/preview): open and preview commands can be changed in sat.conf with "blog_preview_open_cmd" and "blog_preview_update_cmd" in [jp] section + don't convert syntax when content is empty
Goffi <goffi@goffi.org>
parents: 1883
diff changeset
509 self._launchPreviewExt(self.open_cb_cmd, "blog_preview_open_cmd")
edd8dc8df1b9 jp (blog/preview): open and preview commands can be changed in sat.conf with "blog_preview_open_cmd" and "blog_preview_update_cmd" in [jp] section + don't convert syntax when content is empty
Goffi <goffi@goffi.org>
parents: 1883
diff changeset
510
edd8dc8df1b9 jp (blog/preview): open and preview commands can be changed in sat.conf with "blog_preview_open_cmd" and "blog_preview_update_cmd" in [jp] section + don't convert syntax when content is empty
Goffi <goffi@goffi.org>
parents: 1883
diff changeset
511 def updatePreviewExt(self):
edd8dc8df1b9 jp (blog/preview): open and preview commands can be changed in sat.conf with "blog_preview_open_cmd" and "blog_preview_update_cmd" in [jp] section + don't convert syntax when content is empty
Goffi <goffi@goffi.org>
parents: 1883
diff changeset
512 self._launchPreviewExt(self.update_cb_cmd, "blog_preview_update_cmd")
edd8dc8df1b9 jp (blog/preview): open and preview commands can be changed in sat.conf with "blog_preview_open_cmd" and "blog_preview_update_cmd" in [jp] section + don't convert syntax when content is empty
Goffi <goffi@goffi.org>
parents: 1883
diff changeset
513
1882
ed444e9aa078 jp (blog/preview): added inotify support, so preview can be updated each time the file is modified (actually IN_CLOSE_WRITE is used, but this may change in the future)
Goffi <goffi@goffi.org>
parents: 1881
diff changeset
514 def updateContent(self):
1885
edd8dc8df1b9 jp (blog/preview): open and preview commands can be changed in sat.conf with "blog_preview_open_cmd" and "blog_preview_update_cmd" in [jp] section + don't convert syntax when content is empty
Goffi <goffi@goffi.org>
parents: 1883
diff changeset
515 with open(self.content_file_path, 'rb') as f:
1929
b603a3d516d3 jp (blog/edit): use utf-8-sig to decode content file to avoid BOM being propaged to content
Goffi <goffi@goffi.org>
parents: 1927
diff changeset
516 content = f.read().decode('utf-8-sig')
2330
74c1dbabeec8 jp (blog/edit): pretty format XHTML before editing it
Goffi <goffi@goffi.org>
parents: 2327
diff changeset
517 if content and self.syntax != SYNTAX_XHTML:
1882
ed444e9aa078 jp (blog/preview): added inotify support, so preview can be updated each time the file is modified (actually IN_CLOSE_WRITE is used, but this may change in the future)
Goffi <goffi@goffi.org>
parents: 1881
diff changeset
518 # we use safe=True because we want to have a preview as close as possible to what the
ed444e9aa078 jp (blog/preview): added inotify support, so preview can be updated each time the file is modified (actually IN_CLOSE_WRITE is used, but this may change in the future)
Goffi <goffi@goffi.org>
parents: 1881
diff changeset
519 # people will see
2330
74c1dbabeec8 jp (blog/edit): pretty format XHTML before editing it
Goffi <goffi@goffi.org>
parents: 2327
diff changeset
520 content = self.host.bridge.syntaxConvert(content, self.syntax, SYNTAX_XHTML, True, self.profile)
1882
ed444e9aa078 jp (blog/preview): added inotify support, so preview can be updated each time the file is modified (actually IN_CLOSE_WRITE is used, but this may change in the future)
Goffi <goffi@goffi.org>
parents: 1881
diff changeset
521
1877
a97db84c048d jp (blog): moved common method in a BlogCommon class + added "current" as an item keyword for blog/edit
Goffi <goffi@goffi.org>
parents: 1876
diff changeset
522 xhtml = (u'<html xmlns="http://www.w3.org/1999/xhtml">' +
a97db84c048d jp (blog): moved common method in a BlogCommon class + added "current" as an item keyword for blog/edit
Goffi <goffi@goffi.org>
parents: 1876
diff changeset
523 u'<head><meta http-equiv="Content-Type" content="text/html;charset=utf-8" /></head>'+
a97db84c048d jp (blog): moved common method in a BlogCommon class + added "current" as an item keyword for blog/edit
Goffi <goffi@goffi.org>
parents: 1876
diff changeset
524 '<body>{}</body>' +
1885
edd8dc8df1b9 jp (blog/preview): open and preview commands can be changed in sat.conf with "blog_preview_open_cmd" and "blog_preview_update_cmd" in [jp] section + don't convert syntax when content is empty
Goffi <goffi@goffi.org>
parents: 1883
diff changeset
525 u'</html>').format(content)
1882
ed444e9aa078 jp (blog/preview): added inotify support, so preview can be updated each time the file is modified (actually IN_CLOSE_WRITE is used, but this may change in the future)
Goffi <goffi@goffi.org>
parents: 1881
diff changeset
526
ed444e9aa078 jp (blog/preview): added inotify support, so preview can be updated each time the file is modified (actually IN_CLOSE_WRITE is used, but this may change in the future)
Goffi <goffi@goffi.org>
parents: 1881
diff changeset
527 with open(self.preview_file_path, 'wb') as f:
ed444e9aa078 jp (blog/preview): added inotify support, so preview can be updated each time the file is modified (actually IN_CLOSE_WRITE is used, but this may change in the future)
Goffi <goffi@goffi.org>
parents: 1881
diff changeset
528 f.write(xhtml.encode('utf-8'))
1877
a97db84c048d jp (blog): moved common method in a BlogCommon class + added "current" as an item keyword for blog/edit
Goffi <goffi@goffi.org>
parents: 1876
diff changeset
529
1874
658824755a0c jp (blog): preview command, first draft
Goffi <goffi@goffi.org>
parents: 1873
diff changeset
530 def start(self):
1882
ed444e9aa078 jp (blog/preview): added inotify support, so preview can be updated each time the file is modified (actually IN_CLOSE_WRITE is used, but this may change in the future)
Goffi <goffi@goffi.org>
parents: 1881
diff changeset
531 import webbrowser
ed444e9aa078 jp (blog/preview): added inotify support, so preview can be updated each time the file is modified (actually IN_CLOSE_WRITE is used, but this may change in the future)
Goffi <goffi@goffi.org>
parents: 1881
diff changeset
532 import urllib
ed444e9aa078 jp (blog/preview): added inotify support, so preview can be updated each time the file is modified (actually IN_CLOSE_WRITE is used, but this may change in the future)
Goffi <goffi@goffi.org>
parents: 1881
diff changeset
533 self.webbrowser, self.urllib = webbrowser, urllib
ed444e9aa078 jp (blog/preview): added inotify support, so preview can be updated each time the file is modified (actually IN_CLOSE_WRITE is used, but this may change in the future)
Goffi <goffi@goffi.org>
parents: 1881
diff changeset
534
ed444e9aa078 jp (blog/preview): added inotify support, so preview can be updated each time the file is modified (actually IN_CLOSE_WRITE is used, but this may change in the future)
Goffi <goffi@goffi.org>
parents: 1881
diff changeset
535 if self.args.inotify != 'false':
ed444e9aa078 jp (blog/preview): added inotify support, so preview can be updated each time the file is modified (actually IN_CLOSE_WRITE is used, but this may change in the future)
Goffi <goffi@goffi.org>
parents: 1881
diff changeset
536 try:
ed444e9aa078 jp (blog/preview): added inotify support, so preview can be updated each time the file is modified (actually IN_CLOSE_WRITE is used, but this may change in the future)
Goffi <goffi@goffi.org>
parents: 1881
diff changeset
537 import inotify.adapters
ed444e9aa078 jp (blog/preview): added inotify support, so preview can be updated each time the file is modified (actually IN_CLOSE_WRITE is used, but this may change in the future)
Goffi <goffi@goffi.org>
parents: 1881
diff changeset
538 import inotify.constants
1886
f3db27508b31 jp (blog/preview): inotify improvments:
Goffi <goffi@goffi.org>
parents: 1885
diff changeset
539 from inotify.calls import InotifyError
1882
ed444e9aa078 jp (blog/preview): added inotify support, so preview can be updated each time the file is modified (actually IN_CLOSE_WRITE is used, but this may change in the future)
Goffi <goffi@goffi.org>
parents: 1881
diff changeset
540 except ImportError:
ed444e9aa078 jp (blog/preview): added inotify support, so preview can be updated each time the file is modified (actually IN_CLOSE_WRITE is used, but this may change in the future)
Goffi <goffi@goffi.org>
parents: 1881
diff changeset
541 if self.args.inotify == 'auto':
ed444e9aa078 jp (blog/preview): added inotify support, so preview can be updated each time the file is modified (actually IN_CLOSE_WRITE is used, but this may change in the future)
Goffi <goffi@goffi.org>
parents: 1881
diff changeset
542 inotify = None
ed444e9aa078 jp (blog/preview): added inotify support, so preview can be updated each time the file is modified (actually IN_CLOSE_WRITE is used, but this may change in the future)
Goffi <goffi@goffi.org>
parents: 1881
diff changeset
543 self.disp(u'inotify module not found, deactivating feature. You can install it with {install}'.format(install=INOTIFY_INSTALL))
ed444e9aa078 jp (blog/preview): added inotify support, so preview can be updated each time the file is modified (actually IN_CLOSE_WRITE is used, but this may change in the future)
Goffi <goffi@goffi.org>
parents: 1881
diff changeset
544 else:
ed444e9aa078 jp (blog/preview): added inotify support, so preview can be updated each time the file is modified (actually IN_CLOSE_WRITE is used, but this may change in the future)
Goffi <goffi@goffi.org>
parents: 1881
diff changeset
545 self.disp(u"inotify not found, can't activate the feature! Please install it with {install}".format(install=INOTIFY_INSTALL), error=True)
ed444e9aa078 jp (blog/preview): added inotify support, so preview can be updated each time the file is modified (actually IN_CLOSE_WRITE is used, but this may change in the future)
Goffi <goffi@goffi.org>
parents: 1881
diff changeset
546 self.host.quit(1)
ed444e9aa078 jp (blog/preview): added inotify support, so preview can be updated each time the file is modified (actually IN_CLOSE_WRITE is used, but this may change in the future)
Goffi <goffi@goffi.org>
parents: 1881
diff changeset
547 else:
ed444e9aa078 jp (blog/preview): added inotify support, so preview can be updated each time the file is modified (actually IN_CLOSE_WRITE is used, but this may change in the future)
Goffi <goffi@goffi.org>
parents: 1881
diff changeset
548 # we deactivate logging in inotify, which is quite annoying
ed444e9aa078 jp (blog/preview): added inotify support, so preview can be updated each time the file is modified (actually IN_CLOSE_WRITE is used, but this may change in the future)
Goffi <goffi@goffi.org>
parents: 1881
diff changeset
549 try:
ed444e9aa078 jp (blog/preview): added inotify support, so preview can be updated each time the file is modified (actually IN_CLOSE_WRITE is used, but this may change in the future)
Goffi <goffi@goffi.org>
parents: 1881
diff changeset
550 inotify.adapters._LOGGER.setLevel(40)
ed444e9aa078 jp (blog/preview): added inotify support, so preview can be updated each time the file is modified (actually IN_CLOSE_WRITE is used, but this may change in the future)
Goffi <goffi@goffi.org>
parents: 1881
diff changeset
551 except AttributeError:
ed444e9aa078 jp (blog/preview): added inotify support, so preview can be updated each time the file is modified (actually IN_CLOSE_WRITE is used, but this may change in the future)
Goffi <goffi@goffi.org>
parents: 1881
diff changeset
552 self.disp(u"Logger doesn't exists, inotify may have chanded", error=True)
ed444e9aa078 jp (blog/preview): added inotify support, so preview can be updated each time the file is modified (actually IN_CLOSE_WRITE is used, but this may change in the future)
Goffi <goffi@goffi.org>
parents: 1881
diff changeset
553 else:
ed444e9aa078 jp (blog/preview): added inotify support, so preview can be updated each time the file is modified (actually IN_CLOSE_WRITE is used, but this may change in the future)
Goffi <goffi@goffi.org>
parents: 1881
diff changeset
554 inotify=None
ed444e9aa078 jp (blog/preview): added inotify support, so preview can be updated each time the file is modified (actually IN_CLOSE_WRITE is used, but this may change in the future)
Goffi <goffi@goffi.org>
parents: 1881
diff changeset
555
1874
658824755a0c jp (blog): preview command, first draft
Goffi <goffi@goffi.org>
parents: 1873
diff changeset
556 sat_conf = config.parseMainConf()
1877
a97db84c048d jp (blog): moved common method in a BlogCommon class + added "current" as an item keyword for blog/edit
Goffi <goffi@goffi.org>
parents: 1876
diff changeset
557 SYNTAX_EXT.update(config.getConfig(sat_conf, 'jp', CONF_SYNTAX_EXT, {}))
1874
658824755a0c jp (blog): preview command, first draft
Goffi <goffi@goffi.org>
parents: 1873
diff changeset
558
1885
edd8dc8df1b9 jp (blog/preview): open and preview commands can be changed in sat.conf with "blog_preview_open_cmd" and "blog_preview_update_cmd" in [jp] section + don't convert syntax when content is empty
Goffi <goffi@goffi.org>
parents: 1883
diff changeset
559 try:
edd8dc8df1b9 jp (blog/preview): open and preview commands can be changed in sat.conf with "blog_preview_open_cmd" and "blog_preview_update_cmd" in [jp] section + don't convert syntax when content is empty
Goffi <goffi@goffi.org>
parents: 1883
diff changeset
560 self.open_cb_cmd = config.getConfig(sat_conf, 'jp', "blog_preview_open_cmd", Exception)
edd8dc8df1b9 jp (blog/preview): open and preview commands can be changed in sat.conf with "blog_preview_open_cmd" and "blog_preview_update_cmd" in [jp] section + don't convert syntax when content is empty
Goffi <goffi@goffi.org>
parents: 1883
diff changeset
561 except (NoOptionError, NoSectionError):
edd8dc8df1b9 jp (blog/preview): open and preview commands can be changed in sat.conf with "blog_preview_open_cmd" and "blog_preview_update_cmd" in [jp] section + don't convert syntax when content is empty
Goffi <goffi@goffi.org>
parents: 1883
diff changeset
562 self.open_cb_cmd = None
edd8dc8df1b9 jp (blog/preview): open and preview commands can be changed in sat.conf with "blog_preview_open_cmd" and "blog_preview_update_cmd" in [jp] section + don't convert syntax when content is empty
Goffi <goffi@goffi.org>
parents: 1883
diff changeset
563 open_cb = self.showPreview
edd8dc8df1b9 jp (blog/preview): open and preview commands can be changed in sat.conf with "blog_preview_open_cmd" and "blog_preview_update_cmd" in [jp] section + don't convert syntax when content is empty
Goffi <goffi@goffi.org>
parents: 1883
diff changeset
564 else:
edd8dc8df1b9 jp (blog/preview): open and preview commands can be changed in sat.conf with "blog_preview_open_cmd" and "blog_preview_update_cmd" in [jp] section + don't convert syntax when content is empty
Goffi <goffi@goffi.org>
parents: 1883
diff changeset
565 open_cb = self.openPreviewExt
edd8dc8df1b9 jp (blog/preview): open and preview commands can be changed in sat.conf with "blog_preview_open_cmd" and "blog_preview_update_cmd" in [jp] section + don't convert syntax when content is empty
Goffi <goffi@goffi.org>
parents: 1883
diff changeset
566
edd8dc8df1b9 jp (blog/preview): open and preview commands can be changed in sat.conf with "blog_preview_open_cmd" and "blog_preview_update_cmd" in [jp] section + don't convert syntax when content is empty
Goffi <goffi@goffi.org>
parents: 1883
diff changeset
567 self.update_cb_cmd = config.getConfig(sat_conf, 'jp', "blog_preview_update_cmd", self.open_cb_cmd)
edd8dc8df1b9 jp (blog/preview): open and preview commands can be changed in sat.conf with "blog_preview_open_cmd" and "blog_preview_update_cmd" in [jp] section + don't convert syntax when content is empty
Goffi <goffi@goffi.org>
parents: 1883
diff changeset
568 if self.update_cb_cmd is None:
edd8dc8df1b9 jp (blog/preview): open and preview commands can be changed in sat.conf with "blog_preview_open_cmd" and "blog_preview_update_cmd" in [jp] section + don't convert syntax when content is empty
Goffi <goffi@goffi.org>
parents: 1883
diff changeset
569 update_cb = self.showPreview
edd8dc8df1b9 jp (blog/preview): open and preview commands can be changed in sat.conf with "blog_preview_open_cmd" and "blog_preview_update_cmd" in [jp] section + don't convert syntax when content is empty
Goffi <goffi@goffi.org>
parents: 1883
diff changeset
570 else:
edd8dc8df1b9 jp (blog/preview): open and preview commands can be changed in sat.conf with "blog_preview_open_cmd" and "blog_preview_update_cmd" in [jp] section + don't convert syntax when content is empty
Goffi <goffi@goffi.org>
parents: 1883
diff changeset
571 update_cb = self.updatePreviewExt
1882
ed444e9aa078 jp (blog/preview): added inotify support, so preview can be updated each time the file is modified (actually IN_CLOSE_WRITE is used, but this may change in the future)
Goffi <goffi@goffi.org>
parents: 1881
diff changeset
572
1874
658824755a0c jp (blog): preview command, first draft
Goffi <goffi@goffi.org>
parents: 1873
diff changeset
573 # which file do we need to edit?
658824755a0c jp (blog): preview command, first draft
Goffi <goffi@goffi.org>
parents: 1873
diff changeset
574 if self.args.file == 'current':
1921
b111f6589da4 jp (blog): drafts are now put in a sub dir per profile + added a security which keep the last 10 drafts before removing them (all profiles included).
Goffi <goffi@goffi.org>
parents: 1919
diff changeset
575 self.content_file_path = self.getCurrentFile(sat_conf, self.profile)
1874
658824755a0c jp (blog): preview command, first draft
Goffi <goffi@goffi.org>
parents: 1873
diff changeset
576 else:
1885
edd8dc8df1b9 jp (blog/preview): open and preview commands can be changed in sat.conf with "blog_preview_open_cmd" and "blog_preview_update_cmd" in [jp] section + don't convert syntax when content is empty
Goffi <goffi@goffi.org>
parents: 1883
diff changeset
577 self.content_file_path = os.path.abspath(self.args.file)
1874
658824755a0c jp (blog): preview command, first draft
Goffi <goffi@goffi.org>
parents: 1873
diff changeset
578
1885
edd8dc8df1b9 jp (blog/preview): open and preview commands can be changed in sat.conf with "blog_preview_open_cmd" and "blog_preview_update_cmd" in [jp] section + don't convert syntax when content is empty
Goffi <goffi@goffi.org>
parents: 1883
diff changeset
579 self.syntax = self.guessSyntaxFromPath(sat_conf, self.content_file_path)
1882
ed444e9aa078 jp (blog/preview): added inotify support, so preview can be updated each time the file is modified (actually IN_CLOSE_WRITE is used, but this may change in the future)
Goffi <goffi@goffi.org>
parents: 1881
diff changeset
580
1874
658824755a0c jp (blog): preview command, first draft
Goffi <goffi@goffi.org>
parents: 1873
diff changeset
581
1877
a97db84c048d jp (blog): moved common method in a BlogCommon class + added "current" as an item keyword for blog/edit
Goffi <goffi@goffi.org>
parents: 1876
diff changeset
582 # at this point the syntax is converted, we can display the preview
1882
ed444e9aa078 jp (blog/preview): added inotify support, so preview can be updated each time the file is modified (actually IN_CLOSE_WRITE is used, but this may change in the future)
Goffi <goffi@goffi.org>
parents: 1881
diff changeset
583 preview_file = tempfile.NamedTemporaryFile(suffix='.xhtml', delete=False)
ed444e9aa078 jp (blog/preview): added inotify support, so preview can be updated each time the file is modified (actually IN_CLOSE_WRITE is used, but this may change in the future)
Goffi <goffi@goffi.org>
parents: 1881
diff changeset
584 self.preview_file_path = preview_file.name
ed444e9aa078 jp (blog/preview): added inotify support, so preview can be updated each time the file is modified (actually IN_CLOSE_WRITE is used, but this may change in the future)
Goffi <goffi@goffi.org>
parents: 1881
diff changeset
585 preview_file.close()
ed444e9aa078 jp (blog/preview): added inotify support, so preview can be updated each time the file is modified (actually IN_CLOSE_WRITE is used, but this may change in the future)
Goffi <goffi@goffi.org>
parents: 1881
diff changeset
586 self.updateContent()
1877
a97db84c048d jp (blog): moved common method in a BlogCommon class + added "current" as an item keyword for blog/edit
Goffi <goffi@goffi.org>
parents: 1876
diff changeset
587
1882
ed444e9aa078 jp (blog/preview): added inotify support, so preview can be updated each time the file is modified (actually IN_CLOSE_WRITE is used, but this may change in the future)
Goffi <goffi@goffi.org>
parents: 1881
diff changeset
588 if inotify is None:
1874
658824755a0c jp (blog): preview command, first draft
Goffi <goffi@goffi.org>
parents: 1873
diff changeset
589 # XXX: we don't delete file automatically because browser need it (and webbrowser.open can return before it is read)
1882
ed444e9aa078 jp (blog/preview): added inotify support, so preview can be updated each time the file is modified (actually IN_CLOSE_WRITE is used, but this may change in the future)
Goffi <goffi@goffi.org>
parents: 1881
diff changeset
590 self.disp(u'temporary file created at {}\nthis file will NOT BE DELETED AUTOMATICALLY, please delete it yourself when you have finished'.format(self.preview_file_path))
ed444e9aa078 jp (blog/preview): added inotify support, so preview can be updated each time the file is modified (actually IN_CLOSE_WRITE is used, but this may change in the future)
Goffi <goffi@goffi.org>
parents: 1881
diff changeset
591 open_cb()
ed444e9aa078 jp (blog/preview): added inotify support, so preview can be updated each time the file is modified (actually IN_CLOSE_WRITE is used, but this may change in the future)
Goffi <goffi@goffi.org>
parents: 1881
diff changeset
592 else:
ed444e9aa078 jp (blog/preview): added inotify support, so preview can be updated each time the file is modified (actually IN_CLOSE_WRITE is used, but this may change in the future)
Goffi <goffi@goffi.org>
parents: 1881
diff changeset
593 open_cb()
ed444e9aa078 jp (blog/preview): added inotify support, so preview can be updated each time the file is modified (actually IN_CLOSE_WRITE is used, but this may change in the future)
Goffi <goffi@goffi.org>
parents: 1881
diff changeset
594 i = inotify.adapters.Inotify(block_duration_s=60) # no need for 1 s duraction, inotify drive actions here
1886
f3db27508b31 jp (blog/preview): inotify improvments:
Goffi <goffi@goffi.org>
parents: 1885
diff changeset
595
f3db27508b31 jp (blog/preview): inotify improvments:
Goffi <goffi@goffi.org>
parents: 1885
diff changeset
596 def add_watch():
f3db27508b31 jp (blog/preview): inotify improvments:
Goffi <goffi@goffi.org>
parents: 1885
diff changeset
597 i.add_watch(self.content_file_path, mask=inotify.constants.IN_CLOSE_WRITE |
1893
4f252b72b193 jp (blog/preview): change watch for IN_MOVE_SELF event, needed at least for Emacs
Goffi <goffi@goffi.org>
parents: 1888
diff changeset
598 inotify.constants.IN_DELETE_SELF |
4f252b72b193 jp (blog/preview): change watch for IN_MOVE_SELF event, needed at least for Emacs
Goffi <goffi@goffi.org>
parents: 1888
diff changeset
599 inotify.constants.IN_MOVE_SELF)
1886
f3db27508b31 jp (blog/preview): inotify improvments:
Goffi <goffi@goffi.org>
parents: 1885
diff changeset
600 add_watch()
f3db27508b31 jp (blog/preview): inotify improvments:
Goffi <goffi@goffi.org>
parents: 1885
diff changeset
601
1882
ed444e9aa078 jp (blog/preview): added inotify support, so preview can be updated each time the file is modified (actually IN_CLOSE_WRITE is used, but this may change in the future)
Goffi <goffi@goffi.org>
parents: 1881
diff changeset
602 try:
ed444e9aa078 jp (blog/preview): added inotify support, so preview can be updated each time the file is modified (actually IN_CLOSE_WRITE is used, but this may change in the future)
Goffi <goffi@goffi.org>
parents: 1881
diff changeset
603 for event in i.event_gen():
ed444e9aa078 jp (blog/preview): added inotify support, so preview can be updated each time the file is modified (actually IN_CLOSE_WRITE is used, but this may change in the future)
Goffi <goffi@goffi.org>
parents: 1881
diff changeset
604 if event is not None:
ed444e9aa078 jp (blog/preview): added inotify support, so preview can be updated each time the file is modified (actually IN_CLOSE_WRITE is used, but this may change in the future)
Goffi <goffi@goffi.org>
parents: 1881
diff changeset
605 self.disp(u"Content updated", 1)
1893
4f252b72b193 jp (blog/preview): change watch for IN_MOVE_SELF event, needed at least for Emacs
Goffi <goffi@goffi.org>
parents: 1888
diff changeset
606 if {"IN_DELETE_SELF", "IN_MOVE_SELF"}.intersection(event[1]):
4f252b72b193 jp (blog/preview): change watch for IN_MOVE_SELF event, needed at least for Emacs
Goffi <goffi@goffi.org>
parents: 1888
diff changeset
607 self.disp(u"{} event catched, changing the watch".format(", ".join(event[1])), 2)
4f252b72b193 jp (blog/preview): change watch for IN_MOVE_SELF event, needed at least for Emacs
Goffi <goffi@goffi.org>
parents: 1888
diff changeset
608 try:
4f252b72b193 jp (blog/preview): change watch for IN_MOVE_SELF event, needed at least for Emacs
Goffi <goffi@goffi.org>
parents: 1888
diff changeset
609 add_watch()
4f252b72b193 jp (blog/preview): change watch for IN_MOVE_SELF event, needed at least for Emacs
Goffi <goffi@goffi.org>
parents: 1888
diff changeset
610 except InotifyError:
4f252b72b193 jp (blog/preview): change watch for IN_MOVE_SELF event, needed at least for Emacs
Goffi <goffi@goffi.org>
parents: 1888
diff changeset
611 # if the new file is not here yet we can have an error
4f252b72b193 jp (blog/preview): change watch for IN_MOVE_SELF event, needed at least for Emacs
Goffi <goffi@goffi.org>
parents: 1888
diff changeset
612 # as a workaround, we do a little rest
4f252b72b193 jp (blog/preview): change watch for IN_MOVE_SELF event, needed at least for Emacs
Goffi <goffi@goffi.org>
parents: 1888
diff changeset
613 time.sleep(1)
4f252b72b193 jp (blog/preview): change watch for IN_MOVE_SELF event, needed at least for Emacs
Goffi <goffi@goffi.org>
parents: 1888
diff changeset
614 add_watch()
1882
ed444e9aa078 jp (blog/preview): added inotify support, so preview can be updated each time the file is modified (actually IN_CLOSE_WRITE is used, but this may change in the future)
Goffi <goffi@goffi.org>
parents: 1881
diff changeset
615 self.updateContent()
ed444e9aa078 jp (blog/preview): added inotify support, so preview can be updated each time the file is modified (actually IN_CLOSE_WRITE is used, but this may change in the future)
Goffi <goffi@goffi.org>
parents: 1881
diff changeset
616 update_cb()
1886
f3db27508b31 jp (blog/preview): inotify improvments:
Goffi <goffi@goffi.org>
parents: 1885
diff changeset
617 except InotifyError:
f3db27508b31 jp (blog/preview): inotify improvments:
Goffi <goffi@goffi.org>
parents: 1885
diff changeset
618 self.disp(u"Can't catch inotify events, as the file been deleted?", error=True)
1882
ed444e9aa078 jp (blog/preview): added inotify support, so preview can be updated each time the file is modified (actually IN_CLOSE_WRITE is used, but this may change in the future)
Goffi <goffi@goffi.org>
parents: 1881
diff changeset
619 finally:
ed444e9aa078 jp (blog/preview): added inotify support, so preview can be updated each time the file is modified (actually IN_CLOSE_WRITE is used, but this may change in the future)
Goffi <goffi@goffi.org>
parents: 1881
diff changeset
620 os.unlink(self.preview_file_path)
1886
f3db27508b31 jp (blog/preview): inotify improvments:
Goffi <goffi@goffi.org>
parents: 1885
diff changeset
621 try:
f3db27508b31 jp (blog/preview): inotify improvments:
Goffi <goffi@goffi.org>
parents: 1885
diff changeset
622 i.remove_watch(self.content_file_path)
f3db27508b31 jp (blog/preview): inotify improvments:
Goffi <goffi@goffi.org>
parents: 1885
diff changeset
623 except InotifyError:
f3db27508b31 jp (blog/preview): inotify improvments:
Goffi <goffi@goffi.org>
parents: 1885
diff changeset
624 pass
1874
658824755a0c jp (blog): preview command, first draft
Goffi <goffi@goffi.org>
parents: 1873
diff changeset
625
658824755a0c jp (blog): preview command, first draft
Goffi <goffi@goffi.org>
parents: 1873
diff changeset
626
1840
9eabf7fadfdd frontends (jp): onActionNew displays xmlui message if no meta_type is defined and xmlui is defined
souliane <souliane@mailoo.org>
parents: 1839
diff changeset
627 class Import(base.CommandAnswering):
1827
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
628 def __init__(self, host):
1834
6209de5e3e25 jp (blog): import now show progression + value to add to sat.conf for URLs redirection
Goffi <goffi@goffi.org>
parents: 1827
diff changeset
629 super(Import, self).__init__(host, 'import', use_progress=True, help=_(u'import an external blog'))
1864
96ba685162f6 jp: all commands now use the new start method and set need_loop in __init__ when needed
Goffi <goffi@goffi.org>
parents: 1840
diff changeset
630 self.need_loop=True
1827
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
631
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
632 def add_parser_options(self):
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
633 self.parser.add_argument("importer", type=base.unicode_decoder, nargs='?', help=_(u"importer name, nothing to display importers list"))
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
634 self.parser.add_argument('--host', type=base.unicode_decoder, help=_(u"original blog host"))
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
635 self.parser.add_argument('--no-images-upload', action='store_true', help=_(u"do *NOT* upload images (default: do upload images)"))
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
636 self.parser.add_argument('--upload-ignore-host', help=_(u"do not upload images from this host (default: upload all images)"))
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
637 self.parser.add_argument("--ignore-tls-errors", action="store_true", help=_("ignore invalide TLS certificate for uploads"))
1839
cdecf553e051 frontends (jp/blog), plugin blog_import: fixes:
souliane <souliane@mailoo.org>
parents: 1834
diff changeset
638 self.parser.add_argument('-o', '--option', action='append', nargs=2, default=[], metavar=(u'NAME', u'VALUE'),
1827
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
639 help=_(u"importer specific options (see importer description)"))
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
640 self.parser.add_argument('--service', type=base.unicode_decoder, default=u'', metavar=u'PUBSUB_SERVICE',
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
641 help=_(u"PubSub service where the items must be uploaded (default: server)"))
2370
2c2b826b0bb3 plugin import: node can now be specified + added a "session" dict to keep import session data:
Goffi <goffi@goffi.org>
parents: 2331
diff changeset
642 self.parser.add_argument('-n', '--node', type=base.unicode_decoder, default=u'', metavar=u'PUBSUB_NODE',
2c2b826b0bb3 plugin import: node can now be specified + added a "session" dict to keep import session data:
Goffi <goffi@goffi.org>
parents: 2331
diff changeset
643 help=_(u"PubSub node where the items must be uploaded (default: tickets' defaults)"))
1827
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
644 self.parser.add_argument("location", type=base.unicode_decoder, nargs='?',
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
645 help=_(u"importer data location (see importer description), nothing to show importer description"))
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
646
1834
6209de5e3e25 jp (blog): import now show progression + value to add to sat.conf for URLs redirection
Goffi <goffi@goffi.org>
parents: 1827
diff changeset
647 def onProgressStarted(self, metadata):
6209de5e3e25 jp (blog): import now show progression + value to add to sat.conf for URLs redirection
Goffi <goffi@goffi.org>
parents: 1827
diff changeset
648 self.disp(_(u'Blog upload started'),2)
6209de5e3e25 jp (blog): import now show progression + value to add to sat.conf for URLs redirection
Goffi <goffi@goffi.org>
parents: 1827
diff changeset
649
6209de5e3e25 jp (blog): import now show progression + value to add to sat.conf for URLs redirection
Goffi <goffi@goffi.org>
parents: 1827
diff changeset
650 def onProgressFinished(self, metadata):
6209de5e3e25 jp (blog): import now show progression + value to add to sat.conf for URLs redirection
Goffi <goffi@goffi.org>
parents: 1827
diff changeset
651 self.disp(_(u'Blog uploaded successfully'),2)
6209de5e3e25 jp (blog): import now show progression + value to add to sat.conf for URLs redirection
Goffi <goffi@goffi.org>
parents: 1827
diff changeset
652 redirections = {k[len(URL_REDIRECT_PREFIX):]:v for k,v in metadata.iteritems()
6209de5e3e25 jp (blog): import now show progression + value to add to sat.conf for URLs redirection
Goffi <goffi@goffi.org>
parents: 1827
diff changeset
653 if k.startswith(URL_REDIRECT_PREFIX)}
6209de5e3e25 jp (blog): import now show progression + value to add to sat.conf for URLs redirection
Goffi <goffi@goffi.org>
parents: 1827
diff changeset
654 if redirections:
6209de5e3e25 jp (blog): import now show progression + value to add to sat.conf for URLs redirection
Goffi <goffi@goffi.org>
parents: 1827
diff changeset
655 conf = u'\n'.join([
6209de5e3e25 jp (blog): import now show progression + value to add to sat.conf for URLs redirection
Goffi <goffi@goffi.org>
parents: 1827
diff changeset
656 u'url_redirections_profile = {}'.format(self.profile),
6209de5e3e25 jp (blog): import now show progression + value to add to sat.conf for URLs redirection
Goffi <goffi@goffi.org>
parents: 1827
diff changeset
657 u"url_redirections_dict = {}".format(
6209de5e3e25 jp (blog): import now show progression + value to add to sat.conf for URLs redirection
Goffi <goffi@goffi.org>
parents: 1827
diff changeset
658 # we need to add ' ' before each new line and to double each '%' for ConfigParser
6209de5e3e25 jp (blog): import now show progression + value to add to sat.conf for URLs redirection
Goffi <goffi@goffi.org>
parents: 1827
diff changeset
659 u'\n '.join(json.dumps(redirections, indent=1, separators=(',',': ')).replace(u'%', u'%%').split(u'\n'))),
6209de5e3e25 jp (blog): import now show progression + value to add to sat.conf for URLs redirection
Goffi <goffi@goffi.org>
parents: 1827
diff changeset
660 ])
6209de5e3e25 jp (blog): import now show progression + value to add to sat.conf for URLs redirection
Goffi <goffi@goffi.org>
parents: 1827
diff changeset
661 self.disp(_(u'\nTo redirect old URLs to new ones, put the following lines in your sat.conf file, in [libervia] section:\n\n{conf}'.format(conf=conf)))
6209de5e3e25 jp (blog): import now show progression + value to add to sat.conf for URLs redirection
Goffi <goffi@goffi.org>
parents: 1827
diff changeset
662
6209de5e3e25 jp (blog): import now show progression + value to add to sat.conf for URLs redirection
Goffi <goffi@goffi.org>
parents: 1827
diff changeset
663 def onProgressError(self, error_msg):
6209de5e3e25 jp (blog): import now show progression + value to add to sat.conf for URLs redirection
Goffi <goffi@goffi.org>
parents: 1827
diff changeset
664 self.disp(_(u'Error while uploading blog: {}').format(error_msg),error=True)
6209de5e3e25 jp (blog): import now show progression + value to add to sat.conf for URLs redirection
Goffi <goffi@goffi.org>
parents: 1827
diff changeset
665
6209de5e3e25 jp (blog): import now show progression + value to add to sat.conf for URLs redirection
Goffi <goffi@goffi.org>
parents: 1827
diff changeset
666 def error(self, failure):
6209de5e3e25 jp (blog): import now show progression + value to add to sat.conf for URLs redirection
Goffi <goffi@goffi.org>
parents: 1827
diff changeset
667 self.disp(_("Error while trying to upload a blog: {reason}").format(reason=failure), error=True)
6209de5e3e25 jp (blog): import now show progression + value to add to sat.conf for URLs redirection
Goffi <goffi@goffi.org>
parents: 1827
diff changeset
668 self.host.quit(1)
6209de5e3e25 jp (blog): import now show progression + value to add to sat.conf for URLs redirection
Goffi <goffi@goffi.org>
parents: 1827
diff changeset
669
1864
96ba685162f6 jp: all commands now use the new start method and set need_loop in __init__ when needed
Goffi <goffi@goffi.org>
parents: 1840
diff changeset
670 def start(self):
1827
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
671 if self.args.location is None:
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
672 for name in ('option', 'service', 'no_images_upload'):
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
673 if getattr(self.args, name):
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
674 self.parser.error(_(u"{name} argument can't be used without location argument").format(name=name))
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
675 if self.args.importer is None:
2161
62dfa6e02f54 jp (base, blog, output(std)): fixed bad unicode handling in stdout, use of jp.disp instead of simple print
Goffi <goffi@goffi.org>
parents: 2158
diff changeset
676 self.disp(u'\n'.join([u'{}: {}'.format(name, desc) for name, desc in self.host.bridge.blogImportList()]))
1827
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
677 else:
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
678 try:
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
679 short_desc, long_desc = self.host.bridge.blogImportDesc(self.args.importer)
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
680 except Exception as e:
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
681 msg = [l for l in unicode(e).split('\n') if l][-1] # we only keep the last line
2161
62dfa6e02f54 jp (base, blog, output(std)): fixed bad unicode handling in stdout, use of jp.disp instead of simple print
Goffi <goffi@goffi.org>
parents: 2158
diff changeset
682 self.disp(msg)
1827
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
683 self.host.quit(1)
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
684 else:
2161
62dfa6e02f54 jp (base, blog, output(std)): fixed bad unicode handling in stdout, use of jp.disp instead of simple print
Goffi <goffi@goffi.org>
parents: 2158
diff changeset
685 self.disp(u"{name}: {short_desc}\n\n{long_desc}".format(name=self.args.importer, short_desc=short_desc, long_desc=long_desc))
1827
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
686 self.host.quit()
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
687 else:
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
688 # we have a location, an import is requested
1839
cdecf553e051 frontends (jp/blog), plugin blog_import: fixes:
souliane <souliane@mailoo.org>
parents: 1834
diff changeset
689 options = {key: value for key, value in self.args.option}
1827
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
690 if self.args.host:
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
691 options['host'] = self.args.host
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
692 if self.args.ignore_tls_errors:
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
693 options['ignore_tls_errors'] = C.BOOL_TRUE
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
694 if self.args.no_images_upload:
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
695 options['upload_images'] = C.BOOL_FALSE
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
696 if self.args.upload_ignore_host:
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
697 self.parser.error(u"upload-ignore-host option can't be used when no-images-upload is set")
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
698 elif self.args.upload_ignore_host:
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
699 options['upload_ignore_host'] = self.args.upload_ignore_host
1834
6209de5e3e25 jp (blog): import now show progression + value to add to sat.conf for URLs redirection
Goffi <goffi@goffi.org>
parents: 1827
diff changeset
700 def gotId(id_):
6209de5e3e25 jp (blog): import now show progression + value to add to sat.conf for URLs redirection
Goffi <goffi@goffi.org>
parents: 1827
diff changeset
701 self.progress_id = id_
2370
2c2b826b0bb3 plugin import: node can now be specified + added a "session" dict to keep import session data:
Goffi <goffi@goffi.org>
parents: 2331
diff changeset
702 self.host.bridge.blogImport(self.args.importer, self.args.location, options, self.args.service, self.args.node, self.profile,
1834
6209de5e3e25 jp (blog): import now show progression + value to add to sat.conf for URLs redirection
Goffi <goffi@goffi.org>
parents: 1827
diff changeset
703 callback=gotId, errback=self.error)
1827
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
704
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
705
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
706 class Blog(base.CommandBase):
2458
4841ad6a5db4 jp (blog): added "set" command to publish content from stdin without editing
Goffi <goffi@goffi.org>
parents: 2414
diff changeset
707 subcommands = (Set, Get, Edit, Preview, Import)
1827
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
708
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
709 def __init__(self, host):
74014a9cc203 jp: added a blog/import command to handle new blog import plugin
Goffi <goffi@goffi.org>
parents:
diff changeset
710 super(Blog, self).__init__(host, 'blog', use_profile=False, help=_('blog/microblog management'))