diff --git a/.gitignore b/.gitignore
index feafb1a..3dc1533 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,3 +6,4 @@ lib
gcloud.json
tests/.Exif.tests.jpg.json
post-run.sh
+.venv
diff --git a/Pipfile b/Pipfile
deleted file mode 100644
index d0a95db..0000000
--- a/Pipfile
+++ /dev/null
@@ -1,20 +0,0 @@
-[[source]]
-url = "https://pypi.python.org/simple"
-verify_ssl = true
-name = "pypi"
-
-[packages]
-Wand = "*"
-unicode-slugify = "*"
-requests = "*"
-python-frontmatter = "*"
-langdetect = "*"
-Jinja2 = "*"
-feedgen = "*"
-filetype = "*"
-arrow = "*"
-
-[dev-packages]
-
-[requires]
-python_version = "3.7"
diff --git a/Pipfile.lock b/Pipfile.lock
deleted file mode 100644
index 9452906..0000000
--- a/Pipfile.lock
+++ /dev/null
@@ -1,217 +0,0 @@
-{
- "_meta": {
- "hash": {
- "sha256": "8c4e0b49bc91f0a4ffa5031290053dfa5fcca8957e3f7378577137e3a8cda540"
- },
- "pipfile-spec": 6,
- "requires": {
- "python_version": "3.7"
- },
- "sources": [
- {
- "name": "pypi",
- "url": "https://pypi.python.org/simple",
- "verify_ssl": true
- }
- ]
- },
- "default": {
- "arrow": {
- "hashes": [
- "sha256:10257c5daba1a88db34afa284823382f4963feca7733b9107956bed041aff24f",
- "sha256:c2325911fcd79972cf493cfd957072f9644af8ad25456201ae1ede3316576eb4"
- ],
- "index": "pypi",
- "version": "==0.15.2"
- },
- "certifi": {
- "hashes": [
- "sha256:e4f3620cfea4f83eedc95b24abd9cd56f3c4b146dd0177e83a21b4eb49e21e50",
- "sha256:fd7c7c74727ddcf00e9acd26bba8da604ffec95bf1c2144e67aff7a8b50e6cef"
- ],
- "version": "==2019.9.11"
- },
- "chardet": {
- "hashes": [
- "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae",
- "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"
- ],
- "version": "==3.0.4"
- },
- "feedgen": {
- "hashes": [
- "sha256:26557304284007a3c2d772c376a48c0a8ec8e24371c4471455ea89cf568fa114"
- ],
- "index": "pypi",
- "version": "==0.8.0"
- },
- "filetype": {
- "hashes": [
- "sha256:17a3b885f19034da29640b083d767e0f13c2dcb5dcc267945c8b6e5a5a9013c7",
- "sha256:4967124d982a71700d94a08c49c4926423500e79382a92070f5ab248d44fe461"
- ],
- "index": "pypi",
- "version": "==1.0.5"
- },
- "idna": {
- "hashes": [
- "sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407",
- "sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c"
- ],
- "version": "==2.8"
- },
- "jinja2": {
- "hashes": [
- "sha256:74320bb91f31270f9551d46522e33af46a80c3d619f4a4bf42b3164d30b5911f",
- "sha256:9fe95f19286cfefaa917656583d020be14e7859c6b0252588391e47db34527de"
- ],
- "index": "pypi",
- "version": "==2.10.3"
- },
- "langdetect": {
- "hashes": [
- "sha256:91a170d5f0ade380db809b3ba67f08e95fe6c6c8641f96d67a51ff7e98a9bf30"
- ],
- "index": "pypi",
- "version": "==1.0.7"
- },
- "lxml": {
- "hashes": [
- "sha256:02ca7bf899da57084041bb0f6095333e4d239948ad3169443f454add9f4e9cb4",
- "sha256:096b82c5e0ea27ce9138bcbb205313343ee66a6e132f25c5ed67e2c8d960a1bc",
- "sha256:0a920ff98cf1aac310470c644bc23b326402d3ef667ddafecb024e1713d485f1",
- "sha256:17cae1730a782858a6e2758fd20dd0ef7567916c47757b694a06ffafdec20046",
- "sha256:17e3950add54c882e032527795c625929613adbd2ce5162b94667334458b5a36",
- "sha256:1f4f214337f6ee5825bf90a65d04d70aab05526c08191ab888cb5149501923c5",
- "sha256:2e8f77db25b0a96af679e64ff9bf9dddb27d379c9900c3272f3041c4d1327c9d",
- "sha256:4dffd405390a45ecb95ab5ab1c1b847553c18b0ef8ed01e10c1c8b1a76452916",
- "sha256:6b899931a5648862c7b88c795eddff7588fb585e81cecce20f8d9da16eff96e0",
- "sha256:726c17f3e0d7a7200718c9a890ccfeab391c9133e363a577a44717c85c71db27",
- "sha256:760c12276fee05c36f95f8040180abc7fbebb9e5011447a97cdc289b5d6ab6fc",
- "sha256:796685d3969815a633827c818863ee199440696b0961e200b011d79b9394bbe7",
- "sha256:891fe897b49abb7db470c55664b198b1095e4943b9f82b7dcab317a19116cd38",
- "sha256:a471628e20f03dcdfde00770eeaf9c77811f0c331c8805219ca7b87ac17576c5",
- "sha256:a63b4fd3e2cabdcc9d918ed280bdde3e8e9641e04f3c59a2a3109644a07b9832",
- "sha256:b0b84408d4eabc6de9dd1e1e0bc63e7731e890c0b378a62443e5741cfd0ae90a",
- "sha256:be78485e5d5f3684e875dab60f40cddace2f5b2a8f7fede412358ab3214c3a6f",
- "sha256:c27eaed872185f047bb7f7da2d21a7d8913457678c9a100a50db6da890bc28b9",
- "sha256:c81cb40bff373ab7a7446d6bbca0190bccc5be3448b47b51d729e37799bb5692",
- "sha256:d11874b3c33ee441059464711cd365b89fa1a9cf19ae75b0c189b01fbf735b84",
- "sha256:e9c028b5897901361d81a4718d1db217b716424a0283afe9d6735fe0caf70f79",
- "sha256:fe489d486cd00b739be826e8c1be188ddb74c7a1ca784d93d06fda882a6a1681"
- ],
- "version": "==4.4.1"
- },
- "markupsafe": {
- "hashes": [
- "sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473",
- "sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161",
- "sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235",
- "sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5",
- "sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff",
- "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b",
- "sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1",
- "sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e",
- "sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183",
- "sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66",
- "sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1",
- "sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1",
- "sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e",
- "sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b",
- "sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905",
- "sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735",
- "sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d",
- "sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e",
- "sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d",
- "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c",
- "sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21",
- "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2",
- "sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5",
- "sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b",
- "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6",
- "sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f",
- "sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f",
- "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7"
- ],
- "version": "==1.1.1"
- },
- "python-dateutil": {
- "hashes": [
- "sha256:7e6584c74aeed623791615e26efd690f29817a27c73085b78e4bad02493df2fb",
- "sha256:c89805f6f4d64db21ed966fda138f8a5ed7a4fdbc1a8ee329ce1b74e3c74da9e"
- ],
- "version": "==2.8.0"
- },
- "python-frontmatter": {
- "hashes": [
- "sha256:13a61749910f2e1968c011103406429abc79c41d52b69adfb07f702ae2df32cc",
- "sha256:cec75b2afd1a06cf5b03cfd9c5173365d3dc14379526389a9742ff35846df771"
- ],
- "index": "pypi",
- "version": "==0.4.5"
- },
- "pyyaml": {
- "hashes": [
- "sha256:0113bc0ec2ad727182326b61326afa3d1d8280ae1122493553fd6f4397f33df9",
- "sha256:01adf0b6c6f61bd11af6e10ca52b7d4057dd0be0343eb9283c878cf3af56aee4",
- "sha256:5124373960b0b3f4aa7df1707e63e9f109b5263eca5976c66e08b1c552d4eaf8",
- "sha256:5ca4f10adbddae56d824b2c09668e91219bb178a1eee1faa56af6f99f11bf696",
- "sha256:7907be34ffa3c5a32b60b95f4d95ea25361c951383a894fec31be7252b2b6f34",
- "sha256:7ec9b2a4ed5cad025c2278a1e6a19c011c80a3caaac804fd2d329e9cc2c287c9",
- "sha256:87ae4c829bb25b9fe99cf71fbb2140c448f534e24c998cc60f39ae4f94396a73",
- "sha256:9de9919becc9cc2ff03637872a440195ac4241c80536632fffeb6a1e25a74299",
- "sha256:a5a85b10e450c66b49f98846937e8cfca1db3127a9d5d1e31ca45c3d0bef4c5b",
- "sha256:b0997827b4f6a7c286c01c5f60384d218dca4ed7d9efa945c3e1aa623d5709ae",
- "sha256:b631ef96d3222e62861443cc89d6563ba3eeb816eeb96b2629345ab795e53681",
- "sha256:bf47c0607522fdbca6c9e817a6e81b08491de50f3766a7a0e6a5be7905961b41",
- "sha256:f81025eddd0327c7d4cfe9b62cf33190e1e736cc6e97502b3ec425f574b3e7a8"
- ],
- "version": "==5.1.2"
- },
- "requests": {
- "hashes": [
- "sha256:11e007a8a2aa0323f5a921e9e6a2d7e4e67d9877e85773fba9ba6419025cbeb4",
- "sha256:9cf5292fcd0f598c671cfc1e0d7d1a7f13bb8085e9a590f48c010551dc6c4b31"
- ],
- "index": "pypi",
- "version": "==2.22.0"
- },
- "six": {
- "hashes": [
- "sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c",
- "sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73"
- ],
- "version": "==1.12.0"
- },
- "unicode-slugify": {
- "hashes": [
- "sha256:34cf3afefa6480efe705a4fc0eaeeaf7f49754aec322ba3e8b2f27dc1cbcf650"
- ],
- "index": "pypi",
- "version": "==0.1.3"
- },
- "unidecode": {
- "hashes": [
- "sha256:1d7a042116536098d05d599ef2b8616759f02985c85b4fef50c78a5aaf10822a",
- "sha256:2b6aab710c2a1647e928e36d69c21e76b453cd455f4e2621000e54b2a9b8cce8"
- ],
- "version": "==1.1.1"
- },
- "urllib3": {
- "hashes": [
- "sha256:3de946ffbed6e6746608990594d08faac602528ac7015ac28d33cee6a45b7398",
- "sha256:9a107b99a5393caf59c7aa3c1249c16e6879447533d0887f4336dde834c7be86"
- ],
- "version": "==1.25.6"
- },
- "wand": {
- "hashes": [
- "sha256:13a96818a2f89e7684704ba3bfc20bdb21a15e08736c3fdf74035eeaeefd7873",
- "sha256:8cfa30a71a3c65efd1d90678790297fec287300715ebcdf17e119fe075148dd0"
- ],
- "index": "pypi",
- "version": "==0.5.7"
- }
- },
- "develop": {}
-}
diff --git a/nasg.py b/nasg.py
index 8e8ce99..9577baf 100644
--- a/nasg.py
+++ b/nasg.py
@@ -15,6 +15,8 @@ import sqlite3
import json
from shutil import copy2 as cp
+from shutil import rmtree
+from shutil import copyfileobj
from urllib.parse import urlparse
from collections import namedtuple
import logging
@@ -243,13 +245,16 @@ class Gone(object):
async def render(self):
if self.exists:
+ os.remove(self.renderfile)
+ os.rmdir(self.renderdir)
+ # rmtree(self.renderdir)
return
- logger.info(
- "rendering %s to %s", self.__class__, self.renderfile
- )
- writepath(
- self.renderfile, J2.get_template(self.template).render()
- )
+ # logger.info(
+ # "rendering %s to %s", self.__class__, self.renderfile
+ # )
+ # writepath(
+ # self.renderfile, J2.get_template(self.template).render()
+ # )
class FediverseStats(object):
@@ -293,12 +298,13 @@ class FediverseStats(object):
"github": "https://github.com/petermolnar/nasg",
"follow": f"{settings.site.url}",
},
+ "email": "webmaster@petermolnar.net"
},
"openRegistrations": False,
- "protocols": ["webmention", "activitypub"],
+ "protocols": ["activitypub"],
"services": {
"inbound": [],
- "outbound": ["github", "flickr"],
+ "outbound": [],
},
"software": {
"name": "nasg",
@@ -1070,7 +1076,7 @@ class Singular(MarkdownDoc):
urls = self.meta.get("syndicate", [])
if not self.is_page:
urls.append("https://fed.brid.gy/")
- urls.append("https://brid.gy/publish/mastodon")
+ #urls.append("https://brid.gy/publish/mastodon")
if self.is_photo:
urls.append("https://brid.gy/publish/flickr")
return urls
@@ -1297,24 +1303,50 @@ class Singular(MarkdownDoc):
".copy",
".cache",
]
+ include = [
+ "map.png"
+ ]
files = glob.glob(
os.path.join(os.path.dirname(self.fpath), "*.*")
)
for f in files:
- fname, fext = os.path.splitext(f)
- if fext.lower() in exclude:
+ fname = os.path.basename(f)
+ fbasename, fext = os.path.splitext(fname)
+ if fext.lower() in exclude and fname.lower() not in include:
continue
t = os.path.join(
settings.paths.get("build"),
self.name,
- os.path.basename(f),
+ fname
)
if os.path.exists(t) and mtime(f) <= mtime(t):
continue
logger.info("copying '%s' to '%s'", f, t)
cp(f, t)
+ async def render_map(self):
+ if not self.is_photo:
+ return
+
+ if "locationCreated" not in self.photo.jsonld:
+ return
+
+ style = settings.mapbox.style
+ size = settings.mapbox.size
+ lat = round(float(self.photo.jsonld["locationCreated"]["geo"]["latitude"]), 3)
+ lon = round(float(self.photo.jsonld["locationCreated"]["geo"]["longitude"]), 3)
+ token = keys.mapbox.get("private")
+ mapfpath = os.path.join(self.dirpath, "map.png")
+ if os.path.exists(mapfpath):
+ return
+
+ url = f"https://api.mapbox.com/styles/v1/mapbox/{style}/static/pin-s({lon},{lat})/{lon},{lat},11,20/{size}?access_token={token}"
+ logger.info("requesting map for %s with URL %s", self.name, url)
+ with requests.get(url, stream=True) as r:
+ with open(mapfpath, 'wb') as f:
+ copyfileobj(r.raw, f)
+
@property
def has_archive(self):
return len(
@@ -1345,6 +1377,7 @@ class Singular(MarkdownDoc):
async def render(self):
await self.get_from_archiveorg()
+ await self.render_map()
if self.exists:
return True
@@ -1644,6 +1677,20 @@ class IndexPHP(PHPFile):
class Micropub(PHPFile):
+ def __init__(self):
+ self.collected_tags = {}
+
+ @property
+ def tags(self):
+ return list(self.collected_tags.keys())
+
+ def add_tag(self, tag):
+ self.add_tags([tag])
+
+ def add_tags(self, tags):
+ for tag in tags:
+ self.collected_tags.update({tag: True})
+
@property
def renderfile(self):
return os.path.join(settings.paths.get("build"), "micropub.php")
@@ -1657,6 +1704,8 @@ class Micropub(PHPFile):
{
"wallabag": keys.wallabag,
"site": settings.site,
+ "paths": settings.paths,
+ "tags": { "tags": self.tags }
}
)
writepath(self.renderfile, r)
@@ -1706,7 +1755,7 @@ class WorldMap(object):
@property
def tmplvars(self):
return {
- "token": keys.mapbox,
+ "token": keys.mapbox.get(settings.site.name),
"site": settings.site,
"menu": settings.menu,
"meta": settings.meta,
@@ -2563,11 +2612,13 @@ def make():
start = int(round(time.time() * 1000))
last = 0
+ # get incoming webmentions
if not (
settings.args.get("offline") or settings.args.get("noservices")
):
incoming = WebmentionIO()
incoming.run()
+ # TODO get queued micropub posts?
queue = AQ()
outbox = []
@@ -2584,6 +2635,7 @@ def make():
worldmap = WorldMap()
postcount = 0
commentcount = 0
+ micropub = Micropub()
for e in glob.glob(os.path.join(content, "*", "*.url")):
post = Redirect(e)
@@ -2606,6 +2658,7 @@ def make():
or settings.args.get("noservices")
):
queue.put(i.backfill_syndication())
+ micropub.add_tags(post.tags)
for i in post.images.values():
queue.put(i.downsize())
@@ -2669,13 +2722,23 @@ def make():
home.add(category, category.get(category.sortedkeys[0]))
queue.put(category.render())
+ # RSS and ATOM feeds
queue.put(frontposts.render_feeds())
+
+ # home
queue.put(home.render())
+
+ # worldmap for photos
queue.put(worldmap.render())
+
+ # fediverse stats
fediversemockery = FediverseStats(postcount, commentcount)
queue.put(fediversemockery.render())
- micropub = Micropub()
+
+ # micropub handler PHP
queue.put(micropub.render())
+
+ # render all the things!
queue.run()
# copy static files
@@ -2695,15 +2758,7 @@ def make():
try:
logger.info("starting syncing")
os.system(
- "rsync -avuhH --delete-after %s/ %s/"
- % (
- settings.paths.get("build"),
- "%s/%s"
- % (
- settings.syncserver,
- settings.paths.get("remotewww"),
- ),
- )
+ f"rsync -avuhH --delete-after {settings.paths.build}/ {settings.syncserver}:{settings.paths.remotewww}"
)
logger.info("syncing finished")
except Exception as e:
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..a1ebfa1
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,20 @@
+arrow==0.15.4
+certifi==2019.11.28
+chardet==3.0.4
+feedgen==0.8.0
+filetype==1.0.5
+idna==2.8
+Jinja2==2.10.3
+langdetect==1.0.7
+lxml==4.4.2
+MarkupSafe==1.1.1
+pkg-resources==0.0.0
+python-dateutil==2.8.1
+python-frontmatter==0.5.0
+PyYAML==5.2
+requests==2.22.0
+six==1.13.0
+unicode-slugify==0.1.3
+Unidecode==1.1.1
+urllib3==1.25.7
+Wand==0.5.8
diff --git a/settings.py b/settings.py
index f9318aa..e49439e 100644
--- a/settings.py
+++ b/settings.py
@@ -18,7 +18,7 @@ class nameddict(dict):
base = os.path.abspath(os.path.expanduser("~/Projects/petermolnar.net"))
-syncserver = "liveserver:/web/petermolnar.net"
+syncserver = "liveserver"
pagination = 42
notinfeed = ["note"]
@@ -73,6 +73,7 @@ site = nameddict(
"https://t.me/petermolnar",
"https://twitter.com/petermolnar",
"https://mastodon.social/@petermolnar"
+ "https://www.flickr.com/people/petermolnareu/"
],
"follows": "https://petermolnar.net/following.opml",
},
@@ -168,9 +169,8 @@ paths = nameddict(
base, "nasg", "templates", "watermark.png"
),
"build": os.path.join(base, "www"),
- "queue": os.path.join(base, "queue"),
- "remotewww": "web",
- "remotequeue": "queue",
+ "remotewww": "/web/petermolnar.net/web",
+ "remotequeue": "/web/petermolnar.net/queue",
"micropub": os.path.join(base, "content", "note"),
"home": os.path.join(base, "content", "home", "index.md"),
"category": "category",
@@ -210,6 +210,11 @@ photo = nameddict(
}
)
+mapbox = nameddict({
+ "style": "outdoors-v11",
+ "size": "720x480"
+})
+
rewrites = {
"^/(?:sysadmin|it|linux-tech-coding|sysadmin-blog)/?(page.*)?$": "category/article/",
"^/(?:fotography|photoblog)/?(page.*)?$": "/category/photo/",
diff --git a/templates/Home.j2.html b/templates/Home.j2.html
index 6c700ca..ee79d13 100644
--- a/templates/Home.j2.html
+++ b/templates/Home.j2.html
@@ -15,14 +15,16 @@
{% block content %}
Latest entries
{% for category, post in posts %}
- in:
@@ -30,7 +32,7 @@
{% include 'meta-article.j2.html' %}
+ {% endfor %}