v2.1.0 - changing version numbering - automated webmentions sending
Peter Molnar hello@petermolnar.eu
Thu, 29 Mar 2018 16:07:53 +0000
M
README.md
→
README.md
@@ -5,7 +5,7 @@ It is most probably not suitable for anyone else, but feel free to use it for ideas. Keep in mind that the project is licenced under GPL.
## Why not [insert static generator here]? -- DRY - Don't Repeat Yourself - is good, so instead of sidefiles for images, I'm using XMP metadata, which most of the ones availabe don't handle well; +- I'm using embedded XMP metadata in photos, which most of the ones availabe don't handle well; - writing plugins to existing generators - Pelican, Nicola, etc - might have taken longer and I wanted to extend my Python knowledge - I wanted to use the best available utilities for some tasks, like `Pandoc` and `exiftool` instead of Python libraries trying to achive the same - I needed to handle webmentions and comments
M
nasg.py
→
nasg.py
@@ -3,16 +3,16 @@ # -*- coding: utf-8 -*-
# vim: set fileencoding=utf-8 : __author__ = "Peter Molnar" -__copyright__ = "Copyright 2017, Peter Molnar" +__copyright__ = "Copyright 2017-2018, Peter Molnar" __license__ = "GPLv3" -__version__ = "2.0" +__version__ = "2.1.0" __maintainer__ = "Peter Molnar" __email__ = "hello@petermolnar.eu" __status__ = "Production" """ silo archiver module of NASG - Copyright (C) 2017 Peter Molnar + Copyright (C) 2017-2018 Peter Molnar This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by@@ -241,7 +241,6 @@ self.name
) ) ) - @property def url(self):@@ -280,7 +279,6 @@ logging.debug('writing file %s', path)
out.write(content) os.utime(path, (self.mtime, self.mtime)) - async def render(self): if self.is_altrender: self.render_onepage()@@ -490,21 +488,33 @@ wm.receive()
wdb.entry_done(incoming.get('id')) wdb.finish() - # note: due to SQLite locking, this will not be async for now - def send_webmentions(self): - if not self.is_reply: - return + def queue_webmentions(self): wdb = shared.WebmentionQueue() - wid = wdb.queue(self.url, self.is_reply) - wm = Webmention( - self.url, - self.is_reply - ) - wm.send() - wdb.entry_done(wid) + for target in self.urls_to_ping: + if not wdb.exists(self.url, target, self.published): + wdb.queue(self.url, target) + else: + logging.debug("not queueing - webmention already queued from %s to %s", self.url, target) wdb.finish() @property + def urls_to_ping(self): + urls = [x.strip() for x in shared.REGEX.get('urls').findall(self.content)] + if self.is_reply: + urls.append(self.is_reply) + for url in self.syndicate: + urls.append(url) + r = {} + for link in urls: + parsed = urlparse(link) + if parsed.netloc in shared.config.get('site', 'domains'): + continue + if link in r: + continue + r.update({link: True}) + return r.keys() + + @property def redirects(self): r = self.meta.get('redirect', []) r.append(self.shortslug)@@ -684,7 +694,7 @@ return shared.REGEX['mdimg'].findall(self.content)
@property def url(self): - return "%s/%s" % (shared.config.get('site', 'url'), self.fname) + return "%s/%s/" % (shared.config.get('site', 'url'), self.fname) @property def body(self):@@ -732,7 +742,7 @@ return shared.baseN(self.pubtime)
@property def syndicate(self): - urls = [] + urls = self.meta.get('syndicate', []) if self.photo and self.photo.is_photo: urls.append("https://brid.gy/publish/flickr") return urls@@ -1300,27 +1310,42 @@ fm = frontmatter.loads('')
fm.content = self.content fm.metadata = self.meta with open(self.fpath, 'wt') as f: + logging.info("Saving webmention to %s", self.fpath) f.write(frontmatter.dumps(fm)) return def send(self): - rels = shared.XRay(self.source).set_discover().parse() + rels = shared.XRay(self.target).set_discover().parse() endpoint = False if 'rels' not in rels: - return + logging.debug("no rel found for %s", self.target) + return True for k in rels.get('rels').keys(): if 'webmention' in k: - endpoint = rels.get('rels').get(k) + endpoint = rels.get('rels').get(k).pop() break if not endpoint: - return - requests.post( + logging.debug("no endpoint found for %s", self.target) + return True + logging.info( + "Sending webmention to endpoint: %s, source: %s, target: %s", + endpoint, + self.source, self.target, - data={ - 'source': self.source, - 'target': self.target - } ) + try: + p = requests.post( + endpoint, + data={ + 'source': self.source, + 'target': self.target + } + ) + if p.status_code == requests.codes.ok: + return True + except Exception as e: + logging.error("sending webmention failed: %s", e) + return False def receive(self): self._fetch()@@ -1464,6 +1489,7 @@
for f, post in content: logging.info("PARSING %s", f) post.init_extras() + post.queue_webmentions() # add to sitemap sitemap.update({ post.url: post.mtime })@@ -1525,16 +1551,23 @@ for name, c in collector_categories:
if not c.is_uptodate or shared.config.getboolean('params', 'force'): worker.append(c.render()) - # TODO move ping to separate function and add it as a task - # TODO separate an aiohttpworker? - # add magic.php rendering worker.append(magic.render()) - - # TODO: send webmentions # do all the things! worker.run() + + # send webmentions - this is synchronous due to the SQLite locking + wdb = shared.WebmentionQueue() + for out in wdb.get_outbox(): + wm = Webmention( + out.get('source'), + out.get('target'), + out.get('dt') + ) + if wm.send(): + wdb.entry_done(out.get('id')) + wdb.finish() # copy static logging.info('copying static files')
M
router.py
→
router.py
@@ -3,16 +3,16 @@ # -*- coding: utf-8 -*-
# vim: set fileencoding=utf-8 : __author__ = "Peter Molnar" -__copyright__ = "Copyright 2017, Peter Molnar" +__copyright__ = "Copyright 2017-2018, Peter Molnar" __license__ = "GPLv3" -__version__ = "2.0" +__version__ = "2.1.0" __maintainer__ = "Peter Molnar" __email__ = "hello@petermolnar.eu" __status__ = "Production" """ silo archiver module of NASG - Copyright (C) 2017 Peter Molnar + Copyright (C) 2017-2018 Peter Molnar This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by@@ -39,21 +39,10 @@ import envelope
import socket if __name__ == '__main__': - #logging_format = "[%(asctime)s] %(process)d-%(levelname)s " - #logging_format += "%(module)s::%(funcName)s():l%(lineno)d: " - #logging_format += "%(message)s" - - #logging.basicConfig( - #format=logging_format, - #level=logging.DEBUG - #) - #log = logging.getLogger() - # log_config=None prevents creation of access_log and error_log files # since I'm running this from systemctl it already goes into syslog app = Sanic('router') - #app = Sanic('router', log_config=None) - # this is ok to be read-only + # this is read only this way! sdb = shared.SearchDB() @app.route("/oauth1", methods=["GET"])