From 79af56af9b253601d87f6b8c3c6c18643a004e1f Mon Sep 17 00:00:00 2001 From: Peter Molnar Date: Fri, 25 Oct 2019 09:43:50 +0100 Subject: [PATCH] - mastodon publish added besides "ordinary" fed.brid.gy (curiosity, for now) - micropub moved to local from zapier - end of zapier-as-service for micropub experiment; it's too restricted for this purpose, mainly because timeouts on other remote services, such as bookmarks -> wallabag - added unlinked worldmap view for of posts as early experiment - added fediverse "stats" - inlined JSON-LD - the sidecar json file is useless the way it was - u-photo/u-featured is now out of e-content - fixed accidentally swapp lon-lat to lat-lon - added rel-licence to figures for encapsulated licence (future use) - re-added twitter, added mastodon in footer --- Pipfile | 6 +- Pipfile.lock | 118 +++++++++---------- assets/icomoon/mastodon.svg | 5 + nasg.py | 202 +++++++++++++++++++++++++++++---- settings.py | 19 ++-- templates/Micropub.j2.php | 181 +++++++++++++++++++++++++++++ templates/Singular.j2.html | 27 +++-- templates/WebImage.j2.html | 3 +- templates/WorldMap.j2.html | 25 ++++ templates/base.j2.html | 29 ++++- templates/meta-article.j2.html | 12 +- templates/style.css | 22 +++- templates/symbols.svg | 149 +----------------------- 13 files changed, 543 insertions(+), 255 deletions(-) create mode 100644 assets/icomoon/mastodon.svg create mode 100644 templates/Micropub.j2.php create mode 100644 templates/WorldMap.j2.html diff --git a/Pipfile b/Pipfile index 82c548a..d0a95db 100644 --- a/Pipfile +++ b/Pipfile @@ -4,15 +4,15 @@ verify_ssl = true name = "pypi" [packages] -wand = "*" +Wand = "*" unicode-slugify = "*" requests = "*" python-frontmatter = "*" langdetect = "*" -jinja2 = "*" +Jinja2 = "*" feedgen = "*" filetype = "*" -arrow = "==0.14.2" +arrow = "*" [dev-packages] diff --git a/Pipfile.lock b/Pipfile.lock index 0c2186c..9452906 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "51fd7fc20bd922d7404b46cdf8aa2e1c7119900b44c6e2ba639cff49633632e3" + "sha256": "8c4e0b49bc91f0a4ffa5031290053dfa5fcca8957e3f7378577137e3a8cda540" }, "pipfile-spec": 6, "requires": { @@ -18,18 +18,18 @@ "default": { "arrow": { "hashes": [ - "sha256:03404b624e89ac5e4fc19c52045fa0f3203419fd4dd64f6e8958c522580a574a", - "sha256:41be7ea4c53c2cf57bf30f2d614f60c411160133f7a0a8c49111c30fb7e725b5" + "sha256:10257c5daba1a88db34afa284823382f4963feca7733b9107956bed041aff24f", + "sha256:c2325911fcd79972cf493cfd957072f9644af8ad25456201ae1ede3316576eb4" ], "index": "pypi", - "version": "==0.14.2" + "version": "==0.15.2" }, "certifi": { "hashes": [ - "sha256:046832c04d4e752f37383b628bc601a7ea7211496b4638f6514d0e5b9acc4939", - "sha256:945e3ba63a0b9f577b1395204e13c3a231f9bc0223888be653286534e5873695" + "sha256:e4f3620cfea4f83eedc95b24abd9cd56f3c4b146dd0177e83a21b4eb49e21e50", + "sha256:fd7c7c74727ddcf00e9acd26bba8da604ffec95bf1c2144e67aff7a8b50e6cef" ], - "version": "==2019.6.16" + "version": "==2019.9.11" }, "chardet": { "hashes": [ @@ -40,10 +40,10 @@ }, "feedgen": { "hashes": [ - "sha256:82c9e29884e137c3e3e7959a02f142d1f7a46cd387d572e9e40150112a27604f" + "sha256:26557304284007a3c2d772c376a48c0a8ec8e24371c4471455ea89cf568fa114" ], "index": "pypi", - "version": "==0.7.0" + "version": "==0.8.0" }, "filetype": { "hashes": [ @@ -53,14 +53,6 @@ "index": "pypi", "version": "==1.0.5" }, - "gumbo": { - "hashes": [ - "sha256:48e9dac2a872a9e2677b63c0bb7a39a76051c703abf30fff4df60664dfda52f4", - "sha256:e8c5504479a535ae7683c6bfba787ea37aa2fe77ae3e40943595a8adebb4d508" - ], - "index": "pypi", - "version": "==0.10.0" - }, "idna": { "hashes": [ "sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407", @@ -70,11 +62,11 @@ }, "jinja2": { "hashes": [ - "sha256:065c4f02ebe7f7cf559e49ee5a95fb800a9e4528727aec6f24402a5374c65013", - "sha256:14dd6caf1527abb21f08f86c784eac40853ba93edb79552aa1e4b8aef1b61c7b" + "sha256:74320bb91f31270f9551d46522e33af46a80c3d619f4a4bf42b3164d30b5911f", + "sha256:9fe95f19286cfefaa917656583d020be14e7859c6b0252588391e47db34527de" ], "index": "pypi", - "version": "==2.10.1" + "version": "==2.10.3" }, "langdetect": { "hashes": [ @@ -85,32 +77,30 @@ }, "lxml": { "hashes": [ - "sha256:06c7616601430aa140a69f97e3116308fffe0848f543b639a5ec2e8920ae72fd", - "sha256:177202792f9842374a8077735c69c41a4282183f7851443d2beb8ee310720819", - "sha256:19317ad721ceb9e39847d11131903931e2794e447d4751ebb0d9236f1b349ff2", - "sha256:36d206e62f3e5dbaafd4ec692b67157e271f5da7fd925fda8515da675eace50d", - "sha256:387115b066c797c85f9861a9613abf50046a15aac16759bc92d04f94acfad082", - "sha256:3ce1c49d4b4a7bc75fb12acb3a6247bb7a91fe420542e6d671ba9187d12a12c2", - "sha256:4d2a5a7d6b0dbb8c37dab66a8ce09a8761409c044017721c21718659fa3365a1", - "sha256:58d0a1b33364d1253a88d18df6c0b2676a1746d27c969dc9e32d143a3701dda5", - "sha256:62a651c618b846b88fdcae0533ec23f185bb322d6c1845733f3123e8980c1d1b", - "sha256:69ff21064e7debc9b1b1e2eee8c2d686d042d4257186d70b338206a80c5bc5ea", - "sha256:7060453eba9ba59d821625c6af6a266bd68277dce6577f754d1eb9116c094266", - "sha256:7d26b36a9c4bce53b9cfe42e67849ae3c5c23558bc08363e53ffd6d94f4ff4d2", - "sha256:83b427ad2bfa0b9705e02a83d8d607d2c2f01889eb138168e462a3a052c42368", - "sha256:923d03c84534078386cf50193057aae98fa94cace8ea7580b74754493fda73ad", - "sha256:b773715609649a1a180025213f67ffdeb5a4878c784293ada300ee95a1f3257b", - "sha256:baff149c174e9108d4a2fee192c496711be85534eab63adb122f93e70aa35431", - "sha256:bca9d118b1014b4c2d19319b10a3ebed508ff649396ce1855e1c96528d9b2fa9", - "sha256:ce580c28845581535dc6000fc7c35fdadf8bea7ccb57d6321b044508e9ba0685", - "sha256:d34923a569e70224d88e6682490e24c842907ba2c948c5fd26185413cbe0cd96", - "sha256:dd9f0e531a049d8b35ec5e6c68a37f1ba6ec3a591415e6804cbdf652793d15d7", - "sha256:ecb805cbfe9102f3fd3d2ef16dfe5ae9e2d7a7dfbba92f4ff1e16ac9784dbfb0", - "sha256:ede9aad2197a0202caff35d417b671f5f91a3631477441076082a17c94edd846", - "sha256:ef2d1fc370400e0aa755aab0b20cf4f1d0e934e7fd5244f3dd4869078e4942b9", - "sha256:f2fec194a49bfaef42a548ee657362af5c7a640da757f6f452a35da7dd9f923c" + "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.3.4" + "version": "==4.4.1" }, "markupsafe": { "hashes": [ @@ -162,19 +152,21 @@ }, "pyyaml": { "hashes": [ - "sha256:57acc1d8533cbe51f6662a55434f0dbecfa2b9eaf115bede8f6fd00115a0c0d3", - "sha256:588c94b3d16b76cfed8e0be54932e5729cc185caffaa5a451e7ad2f7ed8b4043", - "sha256:68c8dd247f29f9a0d09375c9c6b8fdc64b60810ebf07ba4cdd64ceee3a58c7b7", - "sha256:70d9818f1c9cd5c48bb87804f2efc8692f1023dac7f1a1a5c61d454043c1d265", - "sha256:86a93cccd50f8c125286e637328ff4eef108400dd7089b46a7be3445eecfa391", - "sha256:a0f329125a926876f647c9fa0ef32801587a12328b4a3c741270464e3e4fa778", - "sha256:a3c252ab0fa1bb0d5a3f6449a4826732f3eb6c0270925548cac342bc9b22c225", - "sha256:b4bb4d3f5e232425e25dda21c070ce05168a786ac9eda43768ab7f3ac2770955", - "sha256:cd0618c5ba5bda5f4039b9398bb7fb6a317bb8298218c3de25c47c4740e4b95e", - "sha256:ceacb9e5f8474dcf45b940578591c7f3d960e82f926c707788a570b51ba59190", - "sha256:fe6a88094b64132c4bb3b631412e90032e8cfe9745a58370462240b8cb7553cd" + "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.1" + "version": "==5.1.2" }, "requests": { "hashes": [ @@ -207,18 +199,18 @@ }, "urllib3": { "hashes": [ - "sha256:b246607a25ac80bedac05c6f282e3cdaf3afb65420fd024ac94435cabe6e18d1", - "sha256:dbe59173209418ae49d485b87d1681aefa36252ee85884c31346debd19463232" + "sha256:3de946ffbed6e6746608990594d08faac602528ac7015ac28d33cee6a45b7398", + "sha256:9a107b99a5393caf59c7aa3c1249c16e6879447533d0887f4336dde834c7be86" ], - "version": "==1.25.3" + "version": "==1.25.6" }, "wand": { "hashes": [ - "sha256:c52d647a34205f9b3948baae739db461a7379a04818548fe8042b5ce751ea6ea", - "sha256:e2e08e19a37c61e85eaa307fe319889af46fe4cac6c23e3ae668b96be3e497ff" + "sha256:13a96818a2f89e7684704ba3bfc20bdb21a15e08736c3fdf74035eeaeefd7873", + "sha256:8cfa30a71a3c65efd1d90678790297fec287300715ebcdf17e119fe075148dd0" ], "index": "pypi", - "version": "==0.5.4" + "version": "==0.5.7" } }, "develop": {} diff --git a/assets/icomoon/mastodon.svg b/assets/icomoon/mastodon.svg new file mode 100644 index 0000000..73d2882 --- /dev/null +++ b/assets/icomoon/mastodon.svg @@ -0,0 +1,5 @@ + + +mastodon + + diff --git a/nasg.py b/nasg.py index ca27f40..8e8ce99 100644 --- a/nasg.py +++ b/nasg.py @@ -252,6 +252,71 @@ class Gone(object): ) +class FediverseStats(object): + def __init__(self, postcount=0, commentcount=0): + self.postcount = postcount + self.commentcount = commentcount + self.nodeinfo_json = "nodeinfo.json" + + async def render(self): + writepath( + os.path.join( + settings.paths.build, ".well-known", "nodeinfo" + ), + json.dumps(self.metanodeinfo, indent=4, ensure_ascii=False), + ) + writepath( + os.path.join( + settings.paths.build, ".well-known", self.nodeinfo_json + ), + json.dumps(self.nodeinfo, indent=4, ensure_ascii=False), + ) + + @property + def metanodeinfo(self): + return { + "links": [ + { + "href": f"{settings.site.url}/.well-known/{self.nodeinfo_json}", + "rel": "http://nodeinfo.diaspora.software/ns/schema/2.0", + } + ] + } + + @property + def nodeinfo(self): + return { + "metadata": { + "nodeName": settings.site.name, + "software": { + "homepage": "https://github.com/petermolnar/nasg", + "github": "https://github.com/petermolnar/nasg", + "follow": f"{settings.site.url}", + }, + }, + "openRegistrations": False, + "protocols": ["webmention", "activitypub"], + "services": { + "inbound": [], + "outbound": ["github", "flickr"], + }, + "software": { + "name": "nasg", + "version": "6.6" + }, + "usage": { + "localPosts": self.postcount, + "localComments": self.commentcount, + "users": { + "total": 1, + "activeHalfyear": 1, + "activeMonth": 1, + }, + }, + "version": "2.0", + } + + class Redirect(Gone): """ Redirect object for entries that moved @@ -328,7 +393,10 @@ class MarkdownDoc(object): c = self.content if hasattr(self, "images") and len(self.images): for match, img in self.images.items(): - c = c.replace(match, str(img)) + if self.is_photo: + c = c.replace(match, "") + else: + c = c.replace(match, str(img)) c = str(PandocMD2HTML(c)) c = RE_PRECODE.sub( '
', c
@@ -453,17 +521,19 @@ class WebImage(object):
             "caption": self.caption,
             "headline": self.title,
             "representativeOfPage": False,
+            # "text": str(self)
         }
         for k, v in self.exif.items():
             r["exifData"].append(
                 {"@type": "PropertyValue", "name": k, "value": v}
             )
         if self.is_photo:
+            licence = settings.licence["_default"]
             r.update(
                 {
                     "creator": settings.author,
                     "copyrightHolder": settings.author,
-                    "license": settings.licence["_default"],
+                    "license": f"https://spdx.org/licenses/{licence}.html",
                 }
             )
         if self.is_mainimg:
@@ -483,12 +553,12 @@ class WebImage(object):
                                 {
                                     "@context": "http://schema.org",
                                     "@type": "GeoCoordinates",
-                                    "latitude": self.exif[
-                                        "GPSLatitude"
-                                    ],
-                                    "longitude": self.exif[
-                                        "GPSLongitude"
-                                    ],
+                                    "latitude": round(
+                                        self.exif["GPSLatitude"], 4
+                                    ),
+                                    "longitude": round(
+                                        self.exif["GPSLongitude"], 4
+                                    ),
                                 }
                             ),
                         }
@@ -1000,6 +1070,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")
         if self.is_photo:
             urls.append("https://brid.gy/publish/flickr")
         return urls
@@ -1134,7 +1205,9 @@ class Singular(MarkdownDoc):
         if len(self.images):
             r["image"] = []
             for img in list(self.images.values()):
-                r["image"].append(img.jsonld)
+                imgld = img.jsonld
+                imgld["text"] = str(img)
+                r["image"].append(imgld)
 
         if self.is_reply:
             r.update(
@@ -1158,7 +1231,7 @@ class Singular(MarkdownDoc):
                 {
                     "@context": "http://schema.org",
                     "@type": "InteractAction",
-                    "url": url,
+                    "target": url,
                 }
             )
 
@@ -1300,14 +1373,6 @@ class Singular(MarkdownDoc):
         )
         del g
 
-        j = settings.site.copy()
-        j.update({"mainEntity": self.jsonld})
-        writepath(
-            os.path.join(self.renderdir, settings.filenames.json),
-            json.dumps(j, indent=4, ensure_ascii=False),
-        )
-        del j
-
 
 class Home(Singular):
     def __init__(self, fpath):
@@ -1578,6 +1643,89 @@ class IndexPHP(PHPFile):
         writepath(self.renderfile, r)
 
 
+class Micropub(PHPFile):
+    @property
+    def renderfile(self):
+        return os.path.join(settings.paths.get("build"), "micropub.php")
+
+    @property
+    def templatefile(self):
+        return "%s.j2.php" % (self.__class__.__name__)
+
+    async def _render(self):
+        r = J2.get_template(self.templatefile).render(
+            {
+                "wallabag": keys.wallabag,
+                "site": settings.site,
+            }
+        )
+        writepath(self.renderfile, r)
+
+class WorldMap(object):
+    def __init__(self):
+        self.data = {}
+        self.mtime = 0
+
+    def add(self, post):
+        if not post.is_photo:
+            return
+        if not post.photo.jsonld.locationCreated:
+            return
+
+        lat = post.photo.jsonld.locationCreated.geo.latitude
+        lon = post.photo.jsonld.locationCreated.geo.longitude
+        k = (lat, lon)
+        content = f'


{post.title}

' + # d = {"latitude": nlat, "longitude": nlon, "popup": content} + if k in self.data: + self.data[k].append(content) + else: + self.data[k] = [content] + self.mtime = max(post.dt.timestamp, self.mtime) + + @property + def exists(self): + if settings.args.get("force"): + return False + if not os.path.exists(self.renderfile): + return False + if mtime(self.renderfile) >= self.mtime: + return True + return False + + @property + def renderfile(self): + return os.path.join( + settings.paths.get("build"), settings.filenames.worldmap + ) + + @property + def template(self): + return "%s.j2.html" % (self.__class__.__name__) + + @property + def tmplvars(self): + return { + "token": keys.mapbox, + "site": settings.site, + "menu": settings.menu, + "meta": settings.meta, + "site": settings.site, + "geo": self.data, + } + + async def render(self): + if self.exists: + return + logger.info( + "rendering %s to %s", self.__class__, self.renderfile + ) + writepath( + self.renderfile, + J2.get_template(self.template).render(self.tmplvars), + ) + + class Category(dict): def __init__(self, name=""): self.name = name @@ -1863,7 +2011,8 @@ class Category(dict): fe.link( href=post.url, rel="alternate", type="text/html" ) - fe.content(src=post.url, type="text/html") + # fe.content(src=post.url, type="text/html") + fe.content(post.html_content, type="html") if len(post.summary): fe.summary(post.summary) fg.add_entry(fe) @@ -2343,7 +2492,6 @@ class WebmentionIO(object): webmention.get("source"), ) - fdir = glob.glob( os.path.join(settings.paths.get("content"), "*", slug) ) @@ -2371,8 +2519,7 @@ class WebmentionIO(object): author = webmention.get("data", {}).get("author", None) if not author: logger.error( - "missing author info on webmention: %s", - webmention, + "missing author info on webmention: %s", webmention ) return meta = { @@ -2434,6 +2581,9 @@ def make(): categories = {} frontposts = Category() home = Home(settings.paths.get("home")) + worldmap = WorldMap() + postcount = 0 + commentcount = 0 for e in glob.glob(os.path.join(content, "*", "*.url")): post = Redirect(e) @@ -2446,6 +2596,9 @@ def make(): ): post = Singular(e) if not post.is_future: + postcount = postcount + 1 + commentcount = commentcount + len(post.comments) + worldmap.add(post) for i in post.to_ping: outbox.append(i) if not ( @@ -2518,6 +2671,11 @@ def make(): queue.put(frontposts.render_feeds()) queue.put(home.render()) + queue.put(worldmap.render()) + fediversemockery = FediverseStats(postcount, commentcount) + queue.put(fediversemockery.render()) + micropub = Micropub() + queue.put(micropub.render()) queue.run() # copy static files diff --git a/settings.py b/settings.py index ce5f4cc..f9318aa 100644 --- a/settings.py +++ b/settings.py @@ -72,6 +72,7 @@ site = nameddict( "https://wa.me/447592011721", "https://t.me/petermolnar", "https://twitter.com/petermolnar", + "https://mastodon.social/@petermolnar" ], "follows": "https://petermolnar.net/following.opml", }, @@ -93,29 +94,32 @@ site = nameddict( "@type": "SearchAction", "target": "https://petermolnar.net/search.php?q={q}", "query-input": "required name=q", - "url": "https://petermolnar.net/search.php", }, { "@context": "http://schema.org", "@type": "FollowAction", - "url": "https://petermolnar.net/follow/", "name": "follow", + "target": "https://petermolnar.net/follow/", }, { "@context": "http://schema.org", "@type": "DonateAction", "description": "Monzo", "name": "monzo", - "url": "https://monzo.me/petermolnar/", "recipient": author, + "target": "https://monzo.me/petermolnar/", + "price": "3", + "priceCurrency": "GBP" }, { "@context": "http://schema.org", "@type": "DonateAction", "description": "Paypal", "name": "paypal", - "url": "https://paypal.me/petermolnar/", "recipient": author, + "target": "https://paypal.me/petermolnar/", + "price": "3", + "priceCurrency": "GBP" }, ], } @@ -147,12 +151,12 @@ menu = nameddict( meta = nameddict( { "webmention": "https://webmention.io/petermolnar.net/webmention", - #"pingback": "https://webmention.io/petermolnar.net/xmlrpc", + "pingback": "https://webmention.io/petermolnar.net/xmlrpc", "hub": "https://petermolnar.superfeedr.com/", "authorization_endpoint": "https://indieauth.com/auth", "token_endpoint": "https://tokens.indieauth.com/token", - "micropub": "https://hooks.zapier.com/hooks/catch/3982452/o3hpw1x/", - #'microsub': 'https://aperture.p3k.io/microsub/83' + "micropub": "https://petermolnar.net/micropub.php", + "microsub": "https://aperture.p3k.io/microsub/83" } ) @@ -184,6 +188,7 @@ filenames = nameddict( "html": "index.html", "gopher": "gophermap", "sitemap": "sitemap.txt", + "worldmap": "map.html" } ) diff --git a/templates/Micropub.j2.php b/templates/Micropub.j2.php new file mode 100644 index 0000000..a2c0257 --- /dev/null +++ b/templates/Micropub.j2.php @@ -0,0 +1,181 @@ + "{{ wallabag["client_id"] }}", + "client_secret" => "{{ wallabag["client_secret"] }}", + "username" => "{{ wallabag["username"] }}", + "password" => "{{ wallabag["password"] }}", + "grant_type" => "password" + ); + + $request = curl_init(); + curl_setopt($request, CURLOPT_URL, "{$wallabag_url}/oauth/v2/token"); + curl_setopt($request, CURLOPT_POST, 1); + curl_setopt($request, CURLOPT_POSTFIELDS,http_build_query($data)); + curl_setopt($request, CURLOPT_RETURNTRANSFER, 1); + $response = curl_exec($request); + curl_close($request); + + try { + $wallabag_token = json_decode($response, true); + } catch (Exception $e) { + remoteerror("failed to parse response from wallabag: " . $response); + } + + if (! isset($wallabag_token['access_token']) ) { + remoteerror("failed to obtain access token from wallabag: " . $response); + } + + $data = array( + "url" => $url, + "archive" => 1 + ); + $headers = array( + 'Content-Type: application/x-www-form-urlencoded', + "Authorization: Bearer ". $wallabag_token["access_token"] + ); + $request = curl_init(); + curl_setopt($request, CURLOPT_URL, "{$wallabag_url}/api/entries"); + curl_setopt($request, CURLOPT_POST, 1); + curl_setopt($request, CURLOPT_POSTFIELDS,http_build_query($data)); + curl_setopt($request, CURLOPT_HTTPHEADER, $headers); + curl_setopt($request, CURLOPT_RETURNTRANSFER, 1); + $response = curl_exec($request); + curl_close($request); + try { + $is_saved = json_decode($response, true); + accepted(); + } catch (Exception $e) { + remoteerror("failed to parse response to save from wallabag: " . $response); + } +} + +if (!empty($_GET)) { + if ( ! isset($_GET['q']) ) { + badrequest('please POST a micropub request'); + } + if ( isset($_GET['q']['config']) ) { + httpok(json_encode(array('tags' => array()))); + } + if(isset($_GET['q']['syndicate-to'])) { + httpok(json_encode(array('syndicate-to' => array()))); + } + badrequest('please POST a micropub request'); +} + + +$raw = file_get_contents("php://input"); +try { + $decoded = json_decode($raw, true); +} catch (Exception $e) { + _syslog('failed to decode JSON, trying decoding form data'); + try { + parse_str($raw, $decoded); + } + catch (Exception $e) { + _syslog('failed to decoding form data as well'); + badrequest('invalid POST contents'); + } +} + +$token = ''; +if (isset($decoded['access_token'])) { + $token = $decoded['access_token']; + unset($decoded['access_token']); +} +elseif (isset($_SERVER['HTTP_AUTHORIZATION'])) { + $token = trim(str_replace('Bearer', '', $_SERVER['HTTP_AUTHORIZATION'])); +} + +if (empty($token)) { + unauthorized('missing token'); +} +else { + verify_token($token); +} + +$source_url = ''; +if(isset($decoded["properties"]) && isset($decoded["properties"]["like-of"])) { + $source_url = $decoded["properties"]["like-of"]; +} +elseif(isset($decoded["like-of"])) { + $source_url = $decoded["like-of"]; +} + +/* deal with like: forward it to wallabag */ +if(!empty($source_url)) { + save_to_wallabag($source_url); +} + +notimplemented(); diff --git a/templates/Singular.j2.html b/templates/Singular.j2.html index a6134a5..7a008a0 100644 --- a/templates/Singular.j2.html +++ b/templates/Singular.j2.html @@ -7,7 +7,6 @@ {% block meta %} - @@ -33,7 +32,9 @@ - + {% if post['@type'] == 'TechArticle' %} @@ -27,7 +28,7 @@ - + {% block meta %}{% endblock %} @@ -58,7 +59,7 @@
{% for action in site.potentialAction %} {% if 'SearchAction' == action['@type'] %} -