diff --git a/README.md b/README.md
index d728b97..ee5e6a6 100644
--- a/README.md
+++ b/README.md
@@ -1,17 +1,36 @@
-# NASG (Not Another Static Generator)
+# NASG (Not Another Static Generator...)
This is a tiny static site generator, written in Python, to scratch my own itches.
-It is most probably not suitable for anyone else.
+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;
-- writing a proper plugin to existing generators - Pelican, Nicola, etc - might have taken longer and I wanted to extend my Python knowledge
+- 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;
+- 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
Don't expect anything fancy: my Python Fu has much to learn.
+## Install
+
+### External dependencies
+
+PHP is in order to use [XRay](https://github.com/aaronpk/XRay/)
+
+```
+apt-get install pandoc exiftool php7.0-bcmath php7.0-bz2 php7.0-cli php7.0-common php7.0-curl php7.0-gd php7.0-imap php7.0-intl php7.0-json php7.0-mbstring php7.0-mcrypt php7.0-mysql php7.0-odbc php7.0-opcache php7.0-readline php7.0-sqlite3 php7.0-xml php7.0-zip python3 python3-pip python3-dev
+```
+
+Get XRay:
+```
+mkdir /usr/local/lib/php
+cd /usr/local/lib/php
+wget https://github.com/aaronpk/XRay/releases/download/v1.3.1/xray-app.zip
+unzip xray-app.zip
+rm xray-app.zip
+```
+
## How content is organized
The directory structure of the "source" is something like this:
diff --git a/__init__.py b/__init__.py
index efad603..e5a0d9b 100644
--- a/__init__.py
+++ b/__init__.py
@@ -1,3 +1 @@
#!/usr/bin/env python3
-
-__version__ = '2.0.0'
diff --git a/nasg.py b/nasg.py
index 684cd06..3766e04 100644
--- a/nasg.py
+++ b/nasg.py
@@ -13,7 +13,6 @@ import asyncio
from math import ceil
import csv
import sqlite3
-import magic
import frontmatter
import arrow
@@ -191,7 +190,6 @@ class Category(NoDupeContainer):
@property
def title(self):
- # TODO proper title
return self.name
@property
@@ -311,26 +309,37 @@ class Singular(object):
def init_extras(self):
- self.process_webmentions()
+ self.receive_webmentions()
c = self.comments
-
- # TODO this should be async
- def process_webmentions(self):
+ # note: due to SQLite locking, this will not be async for now
+ def receive_webmentions(self):
wdb = shared.WebmentionQueue()
queued = wdb.get_queued(self.url)
for incoming in queued:
wm = Webmention(
- incoming.get('id'),
incoming.get('source'),
incoming.get('target'),
incoming.get('dt')
)
- wm.run()
-
+ 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
+ wdb = shared.WebmentionQueue()
+ id = wdb.queue(self.url, self.is_reply)
+ wm = Webmention(
+ self.url,
+ self.is_reply
+ )
+ wm.send()
+ wdb.entry_done(id)
+ wdb.finish()
+
@property
def redirects(self):
r = self.meta.get('redirect', [])
@@ -523,9 +532,6 @@ class Singular(object):
im.title = title
im.cssclass = css
body = body.replace(shortcode, str(im))
-
- # TODO if multiple meta images, inline all except the first
- # which will be added at the HTML stage or as enclosure to the feed
return body
@property
@@ -558,16 +564,6 @@ class Singular(object):
def shortslug(self):
return shared.baseN(self.pubtime)
- @property
- def enclosure(self):
- if not self.photo:
- return {}
- return {
- 'length': os.path.getsize(self.photo.fpath),
- 'url': self.photo.href,
- 'mime': magic.Magic(mime=True).from_file(self.photo.fpath),
- }
-
@property
def tmplvars(self):
# very simple caching because we might use this 4 times:
@@ -584,13 +580,11 @@ class Singular(object):
'slug': self.fname,
'shortslug': self.shortslug,
'licence': self.licence,
- #'sourceurl': self.sourceurl,
'is_reply': self.is_reply,
'age': int(self.published.format('YYYY')) - int(arrow.utcnow().format('YYYY')),
'summary': self.summary,
'replies': self.replies,
'reactions': self.reactions,
- 'enclosure': self.enclosure,
}
return self._tmplvars
@@ -1049,10 +1043,9 @@ class Comment(object):
class Webmention(object):
- def __init__ (self, id, source, target, dt):
+ def __init__ (self, source, target, dt=arrow.utcnow().timestamp):
self.source = source
self.target = target
- self.id = id
self.dt = arrow.get(dt).to('utc')
logging.info(
"processing webmention %s => %s",
@@ -1071,7 +1064,26 @@ class Webmention(object):
f.write(frontmatter.dumps(fm))
return
- def run(self):
+ def send(self):
+ rels = shared.XRay(self.source).set_discover().parse()
+ endpoint = False
+ if 'rels' not in rels:
+ return
+ for k in rels.get('rels').keys():
+ if 'webmention' in k:
+ endpoint = rels.get('rels').get(k)
+ break
+ if not endpoint:
+ return
+ requests.post(
+ self.target,
+ data = {
+ 'source': self.source,
+ 'target': self.target
+ }
+ )
+
+ def receive(self):
self._fetch()
if 'data' not in self._source:
return
@@ -1131,7 +1143,6 @@ class Webmention(object):
self.fname
)
-
def setup():
""" parse input parameters and add them as params section to config """
parser = argparse.ArgumentParser(description='Parameters for NASG')
@@ -1281,8 +1292,6 @@ def build():
tasks.append(task)
# TODO: send webmentions to any url
- # TODO: comments
- # TODO: ping websub?
# do all the things!
w = asyncio.wait(tasks)
diff --git a/setup.py b/setup.py
index f5faa46..e3e648c 100644
--- a/setup.py
+++ b/setup.py
@@ -1,16 +1,25 @@
from setuptools import setup, find_packages
-from . import __version__
setup(
- version=__version__,
+ version='2.0.0',
name="nasg",
author="Peter Molnar",
author_email="hello@petermolnar.eu",
description="Not Another Static Generator - a static generator",
long_description=open('README.md').read(),
packages=['nasg'],
- install_requires=['arrow', 'Jinja2', 'langdetect', 'requests', 'requests-oauthlib', 'sanic', 'unicode-slugify', 'Wand', 'emoji', 'html5lib', 'BeautifulSoup'],
+ install_requires=[
+ 'arrow',
+ 'Jinja2',
+ 'langdetect',
+ 'requests',
+ 'requests-oauthlib',
+ 'sanic',
+ 'unicode-slugify',
+ 'Wand',
+ 'emoji',
+ ],
url='https://github.com/petermolnar/nasg',
- license=open('LICENCE').read(),
+ license=open('./LICENSE').read(),
include_package_data=True,
)
diff --git a/shared.py b/shared.py
index e9878eb..8b116ba 100644
--- a/shared.py
+++ b/shared.py
@@ -7,7 +7,6 @@ import subprocess
import json
import sqlite3
import requests
-
from slugify import slugify
import jinja2
@@ -28,21 +27,48 @@ class CMDLine(object):
class XRay(CMDLine):
- xraypath = '/usr/local/lib/php/xray'
+ cmd_prefix = 'chdir("/usr/local/lib/php/xray"); include("vendor/autoload.php"); $xray = new p3k\XRay();'
def __init__(self, url):
super().__init__('php')
self.url = url
-
- def parse(self):
- cmd = (
+ self.target = ''
+ self.cmd = (
self.executable,
'-r',
- '''chdir("%s"); include("vendor/autoload.php"); $xray = new p3k\XRay(); echo(json_encode($xray->parse("%s")));''' % (self.xraypath, self.url)
+ '%s; echo(json_encode($xray->parse("%s")));' % (
+ self.cmd_prefix,
+ self.url
+ )
)
+
+ def set_receive(self, target):
+ self.cmd = (
+ self.executable,
+ '-r',
+ '%s; echo(json_encode($xray->parse("%s")));' % (
+ self.cmd_prefix,
+ self.url,
+ target
+ )
+ )
+ return self
+
+ def set_discover(self):
+ self.cmd = (
+ self.executable,
+ '-r',
+ '%s; echo(json_encode($xray->rels("%s")));' % (
+ self.cmd_prefix,
+ self.url,
+ )
+ )
+ return self
+
+ def parse(self):
logging.debug('pulling %s with XRay', self.url)
p = subprocess.Popen(
- cmd,
+ self.cmd,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
@@ -54,7 +80,6 @@ class XRay(CMDLine):
return json.loads(stdout.decode('utf-8').strip())
-
class Pandoc(CMDLine):
""" Pandoc command line call with piped in- and output """
@@ -439,7 +464,9 @@ class WebmentionQueue(object):
target
)
)
+ r = cursor.lastrowid
self.db.commit()
+ return r
def get_queued(self, fname=None):
logging.debug('getting queued webmentions for %s', fname)
diff --git a/templates/Category_feed.html b/templates/Category_feed.html
index cd29a3a..5c5a92a 100644
--- a/templates/Category_feed.html
+++ b/templates/Category_feed.html
@@ -19,13 +19,6 @@
{%- if post.tags %}{% for tname in post.tags %}
{{ tname }}>
{% endfor %}{% endif -%}
-{%- if post.rssenclosure %}
-
-{% endif -%}
{% endfor %}