comparison sat/plugins/plugin_blog_import.py @ 4037:524856bd7b19

massive refactoring to switch from camelCase to snake_case: historically, Libervia (SàT before) was using camelCase as allowed by PEP8 when using a pre-PEP8 code, to use the same coding style as in Twisted. However, snake_case is more readable and it's better to follow PEP8 best practices, so it has been decided to move on full snake_case. Because Libervia has a huge codebase, this ended with a ugly mix of camelCase and snake_case. To fix that, this patch does a big refactoring by renaming every function and method (including bridge) that are not coming from Twisted or Wokkel, to use fully snake_case. This is a massive change, and may result in some bugs.
author Goffi <goffi@goffi.org>
date Sat, 08 Apr 2023 13:54:42 +0200
parents 0ff265725489
children
comparison
equal deleted inserted replaced
4036:c4464d7ae97b 4037:524856bd7b19
59 BOOL_OPTIONS = (OPT_UPLOAD_IMAGES, OPT_IGNORE_TLS) 59 BOOL_OPTIONS = (OPT_UPLOAD_IMAGES, OPT_IGNORE_TLS)
60 JSON_OPTIONS = () 60 JSON_OPTIONS = ()
61 OPT_DEFAULTS = {OPT_UPLOAD_IMAGES: True, OPT_IGNORE_TLS: False} 61 OPT_DEFAULTS = {OPT_UPLOAD_IMAGES: True, OPT_IGNORE_TLS: False}
62 62
63 def __init__(self, host): 63 def __init__(self, host):
64 log.info(_("plugin Blog Import initialization")) 64 log.info(_("plugin Blog import initialization"))
65 self.host = host 65 self.host = host
66 self._u = host.plugins["UPLOAD"] 66 self._u = host.plugins["UPLOAD"]
67 self._p = host.plugins["XEP-0060"] 67 self._p = host.plugins["XEP-0060"]
68 self._m = host.plugins["XEP-0277"] 68 self._m = host.plugins["XEP-0277"]
69 self._s = self.host.plugins["TEXT_SYNTAXES"] 69 self._s = self.host.plugins["TEXT_SYNTAXES"]
70 host.plugins["IMPORT"].initialize(self, "blog") 70 host.plugins["IMPORT"].initialize(self, "blog")
71 71
72 def importItem( 72 def import_item(
73 self, client, item_import_data, session, options, return_data, service, node 73 self, client, item_import_data, session, options, return_data, service, node
74 ): 74 ):
75 """importItem specialized for blog import 75 """import_item specialized for blog import
76 76
77 @param item_import_data(dict): 77 @param item_import_data(dict):
78 * mandatory keys: 78 * mandatory keys:
79 'blog' (dict): microblog data of the blog post (cf. http://wiki.goffi.org/wiki/Bridge_API_-_Microblogging/en) 79 'blog' (dict): microblog data of the blog post (cf. http://wiki.goffi.org/wiki/Bridge_API_-_Microblogging/en)
80 the importer MUST NOT create node or call XEP-0277 plugin itself 80 the importer MUST NOT create node or call XEP-0277 plugin itself
114 # so the user can redirect its former blog urls 114 # so the user can redirect its former blog urls
115 old_uri = item_import_data["url"] 115 old_uri = item_import_data["url"]
116 except KeyError: 116 except KeyError:
117 pass 117 pass
118 else: 118 else:
119 new_uri = return_data[URL_REDIRECT_PREFIX + old_uri] = self._p.getNodeURI( 119 new_uri = return_data[URL_REDIRECT_PREFIX + old_uri] = self._p.get_node_uri(
120 service if service is not None else client.jid.userhostJID(), 120 service if service is not None else client.jid.userhostJID(),
121 node or self._m.namespace, 121 node or self._m.namespace,
122 item_id, 122 item_id,
123 ) 123 )
124 log.info("url link from {old} to {new}".format(old=old_uri, new=new_uri)) 124 log.info("url link from {old} to {new}".format(old=old_uri, new=new_uri))
125 125
126 return mb_data 126 return mb_data
127 127
128 @defer.inlineCallbacks 128 @defer.inlineCallbacks
129 def importSubItems(self, client, item_import_data, mb_data, session, options): 129 def import_sub_items(self, client, item_import_data, mb_data, session, options):
130 # comments data 130 # comments data
131 if len(item_import_data["comments"]) != 1: 131 if len(item_import_data["comments"]) != 1:
132 raise NotImplementedError("can't manage multiple comment links") 132 raise NotImplementedError("can't manage multiple comment links")
133 allow_comments = C.bool(mb_data.get("allow_comments", C.BOOL_FALSE)) 133 allow_comments = C.bool(mb_data.get("allow_comments", C.BOOL_FALSE))
134 if allow_comments: 134 if allow_comments:
135 comments_service = yield self._m.getCommentsService(client) 135 comments_service = yield self._m.get_comments_service(client)
136 comments_node = self._m.getCommentsNode(mb_data["id"]) 136 comments_node = self._m.get_comments_node(mb_data["id"])
137 mb_data["comments_service"] = comments_service.full() 137 mb_data["comments_service"] = comments_service.full()
138 mb_data["comments_node"] = comments_node 138 mb_data["comments_node"] = comments_node
139 recurse_kwargs = { 139 recurse_kwargs = {
140 "items_import_data": item_import_data["comments"][0], 140 "items_import_data": item_import_data["comments"][0],
141 "service": comments_service, 141 "service": comments_service,
147 raise exceptions.DataError( 147 raise exceptions.DataError(
148 "allow_comments set to False, but comments are there" 148 "allow_comments set to False, but comments are there"
149 ) 149 )
150 defer.returnValue(None) 150 defer.returnValue(None)
151 151
152 def publishItem(self, client, mb_data, service, node, session): 152 def publish_item(self, client, mb_data, service, node, session):
153 log.debug( 153 log.debug(
154 "uploading item [{id}]: {title}".format( 154 "uploading item [{id}]: {title}".format(
155 id=mb_data["id"], title=mb_data.get("title", "") 155 id=mb_data["id"], title=mb_data.get("title", "")
156 ) 156 )
157 ) 157 )
158 return self._m.send(client, mb_data, service, node) 158 return self._m.send(client, mb_data, service, node)
159 159
160 @defer.inlineCallbacks 160 @defer.inlineCallbacks
161 def itemFilters(self, client, mb_data, session, options): 161 def item_filters(self, client, mb_data, session, options):
162 """Apply filters according to options 162 """Apply filters according to options
163 163
164 modify mb_data in place 164 modify mb_data in place
165 @param posts_data(list[dict]): data as returned by importer callback 165 @param posts_data(list[dict]): data as returned by importer callback
166 @param options(dict): dict as given in [blogImport] 166 @param options(dict): dict as given in [blogImport]
186 prefix=prefix 186 prefix=prefix
187 ) 187 )
188 ) 188 )
189 # we convert rich syntax to XHTML here, so we can handle filters easily 189 # we convert rich syntax to XHTML here, so we can handle filters easily
190 converted = yield self._s.convert( 190 converted = yield self._s.convert(
191 rich, self._s.getCurrentSyntax(client.profile), safe=False 191 rich, self._s.get_current_syntax(client.profile), safe=False
192 ) 192 )
193 mb_data["{}_xhtml".format(prefix)] = converted 193 mb_data["{}_xhtml".format(prefix)] = converted
194 del mb_data["{}_rich".format(prefix)] 194 del mb_data["{}_rich".format(prefix)]
195 195
196 try: 196 try:
218 top_elt = xml_tools.ElementParser()( 218 top_elt = xml_tools.ElementParser()(
219 mb_data["content_xhtml"], namespace=C.NS_XHTML 219 mb_data["content_xhtml"], namespace=C.NS_XHTML
220 ) 220 )
221 except domish.ParserError: 221 except domish.ParserError:
222 # we clean the xml and try again our luck 222 # we clean the xml and try again our luck
223 cleaned = yield self._s.cleanXHTML(mb_data["content_xhtml"]) 223 cleaned = yield self._s.clean_xhtml(mb_data["content_xhtml"])
224 top_elt = xml_tools.ElementParser()(cleaned, namespace=C.NS_XHTML) 224 top_elt = xml_tools.ElementParser()(cleaned, namespace=C.NS_XHTML)
225 opt_host = options.get(OPT_HOST) 225 opt_host = options.get(OPT_HOST)
226 if opt_host: 226 if opt_host:
227 # we normalise the domain 227 # we normalise the domain
228 parsed_host = urllib.parse.urlsplit(opt_host) 228 parsed_host = urllib.parse.urlsplit(opt_host)
237 ) 237 )
238 238
239 tmp_dir = tempfile.mkdtemp() 239 tmp_dir = tempfile.mkdtemp()
240 try: 240 try:
241 # TODO: would be nice to also update the hyperlinks to these images, e.g. when you have <a href="{url}"><img src="{url}"></a> 241 # TODO: would be nice to also update the hyperlinks to these images, e.g. when you have <a href="{url}"><img src="{url}"></a>
242 for img_elt in xml_tools.findAll(top_elt, names=["img"]): 242 for img_elt in xml_tools.find_all(top_elt, names=["img"]):
243 yield self.imgFilters(client, img_elt, options, opt_host, tmp_dir) 243 yield self.img_filters(client, img_elt, options, opt_host, tmp_dir)
244 finally: 244 finally:
245 os.rmdir(tmp_dir) # XXX: tmp_dir should be empty, or something went wrong 245 os.rmdir(tmp_dir) # XXX: tmp_dir should be empty, or something went wrong
246 246
247 # we now replace the content with filtered one 247 # we now replace the content with filtered one
248 mb_data["content_xhtml"] = top_elt.toXml() 248 mb_data["content_xhtml"] = top_elt.toXml()
249 249
250 @defer.inlineCallbacks 250 @defer.inlineCallbacks
251 def imgFilters(self, client, img_elt, options, opt_host, tmp_dir): 251 def img_filters(self, client, img_elt, options, opt_host, tmp_dir):
252 """Filters handling images 252 """Filters handling images
253 253
254 url without host are fixed (if possible) 254 url without host are fixed (if possible)
255 according to options, images are uploaded to XMPP server 255 according to options, images are uploaded to XMPP server
256 @param img_elt(domish.Element): <img/> element to handle 256 @param img_elt(domish.Element): <img/> element to handle