- unlinked map view
- fediverse stats - micropub things
This commit is contained in:
parent
79af56af9b
commit
71a54c6317
13 changed files with 181 additions and 343 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -6,3 +6,4 @@ lib
|
||||||
gcloud.json
|
gcloud.json
|
||||||
tests/.Exif.tests.jpg.json
|
tests/.Exif.tests.jpg.json
|
||||||
post-run.sh
|
post-run.sh
|
||||||
|
.venv
|
||||||
|
|
20
Pipfile
20
Pipfile
|
@ -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"
|
|
217
Pipfile.lock
generated
217
Pipfile.lock
generated
|
@ -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": {}
|
|
||||||
}
|
|
101
nasg.py
101
nasg.py
|
@ -15,6 +15,8 @@ import sqlite3
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from shutil import copy2 as cp
|
from shutil import copy2 as cp
|
||||||
|
from shutil import rmtree
|
||||||
|
from shutil import copyfileobj
|
||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
import logging
|
import logging
|
||||||
|
@ -243,13 +245,16 @@ class Gone(object):
|
||||||
|
|
||||||
async def render(self):
|
async def render(self):
|
||||||
if self.exists:
|
if self.exists:
|
||||||
|
os.remove(self.renderfile)
|
||||||
|
os.rmdir(self.renderdir)
|
||||||
|
# rmtree(self.renderdir)
|
||||||
return
|
return
|
||||||
logger.info(
|
# logger.info(
|
||||||
"rendering %s to %s", self.__class__, self.renderfile
|
# "rendering %s to %s", self.__class__, self.renderfile
|
||||||
)
|
# )
|
||||||
writepath(
|
# writepath(
|
||||||
self.renderfile, J2.get_template(self.template).render()
|
# self.renderfile, J2.get_template(self.template).render()
|
||||||
)
|
# )
|
||||||
|
|
||||||
|
|
||||||
class FediverseStats(object):
|
class FediverseStats(object):
|
||||||
|
@ -293,12 +298,13 @@ class FediverseStats(object):
|
||||||
"github": "https://github.com/petermolnar/nasg",
|
"github": "https://github.com/petermolnar/nasg",
|
||||||
"follow": f"{settings.site.url}",
|
"follow": f"{settings.site.url}",
|
||||||
},
|
},
|
||||||
|
"email": "webmaster@petermolnar.net"
|
||||||
},
|
},
|
||||||
"openRegistrations": False,
|
"openRegistrations": False,
|
||||||
"protocols": ["webmention", "activitypub"],
|
"protocols": ["activitypub"],
|
||||||
"services": {
|
"services": {
|
||||||
"inbound": [],
|
"inbound": [],
|
||||||
"outbound": ["github", "flickr"],
|
"outbound": [],
|
||||||
},
|
},
|
||||||
"software": {
|
"software": {
|
||||||
"name": "nasg",
|
"name": "nasg",
|
||||||
|
@ -1070,7 +1076,7 @@ class Singular(MarkdownDoc):
|
||||||
urls = self.meta.get("syndicate", [])
|
urls = self.meta.get("syndicate", [])
|
||||||
if not self.is_page:
|
if not self.is_page:
|
||||||
urls.append("https://fed.brid.gy/")
|
urls.append("https://fed.brid.gy/")
|
||||||
urls.append("https://brid.gy/publish/mastodon")
|
#urls.append("https://brid.gy/publish/mastodon")
|
||||||
if self.is_photo:
|
if self.is_photo:
|
||||||
urls.append("https://brid.gy/publish/flickr")
|
urls.append("https://brid.gy/publish/flickr")
|
||||||
return urls
|
return urls
|
||||||
|
@ -1297,24 +1303,50 @@ class Singular(MarkdownDoc):
|
||||||
".copy",
|
".copy",
|
||||||
".cache",
|
".cache",
|
||||||
]
|
]
|
||||||
|
include = [
|
||||||
|
"map.png"
|
||||||
|
]
|
||||||
files = glob.glob(
|
files = glob.glob(
|
||||||
os.path.join(os.path.dirname(self.fpath), "*.*")
|
os.path.join(os.path.dirname(self.fpath), "*.*")
|
||||||
)
|
)
|
||||||
for f in files:
|
for f in files:
|
||||||
fname, fext = os.path.splitext(f)
|
fname = os.path.basename(f)
|
||||||
if fext.lower() in exclude:
|
fbasename, fext = os.path.splitext(fname)
|
||||||
|
if fext.lower() in exclude and fname.lower() not in include:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
t = os.path.join(
|
t = os.path.join(
|
||||||
settings.paths.get("build"),
|
settings.paths.get("build"),
|
||||||
self.name,
|
self.name,
|
||||||
os.path.basename(f),
|
fname
|
||||||
)
|
)
|
||||||
if os.path.exists(t) and mtime(f) <= mtime(t):
|
if os.path.exists(t) and mtime(f) <= mtime(t):
|
||||||
continue
|
continue
|
||||||
logger.info("copying '%s' to '%s'", f, t)
|
logger.info("copying '%s' to '%s'", f, t)
|
||||||
cp(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
|
@property
|
||||||
def has_archive(self):
|
def has_archive(self):
|
||||||
return len(
|
return len(
|
||||||
|
@ -1345,6 +1377,7 @@ class Singular(MarkdownDoc):
|
||||||
|
|
||||||
async def render(self):
|
async def render(self):
|
||||||
await self.get_from_archiveorg()
|
await self.get_from_archiveorg()
|
||||||
|
await self.render_map()
|
||||||
|
|
||||||
if self.exists:
|
if self.exists:
|
||||||
return True
|
return True
|
||||||
|
@ -1644,6 +1677,20 @@ class IndexPHP(PHPFile):
|
||||||
|
|
||||||
|
|
||||||
class Micropub(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
|
@property
|
||||||
def renderfile(self):
|
def renderfile(self):
|
||||||
return os.path.join(settings.paths.get("build"), "micropub.php")
|
return os.path.join(settings.paths.get("build"), "micropub.php")
|
||||||
|
@ -1657,6 +1704,8 @@ class Micropub(PHPFile):
|
||||||
{
|
{
|
||||||
"wallabag": keys.wallabag,
|
"wallabag": keys.wallabag,
|
||||||
"site": settings.site,
|
"site": settings.site,
|
||||||
|
"paths": settings.paths,
|
||||||
|
"tags": { "tags": self.tags }
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
writepath(self.renderfile, r)
|
writepath(self.renderfile, r)
|
||||||
|
@ -1706,7 +1755,7 @@ class WorldMap(object):
|
||||||
@property
|
@property
|
||||||
def tmplvars(self):
|
def tmplvars(self):
|
||||||
return {
|
return {
|
||||||
"token": keys.mapbox,
|
"token": keys.mapbox.get(settings.site.name),
|
||||||
"site": settings.site,
|
"site": settings.site,
|
||||||
"menu": settings.menu,
|
"menu": settings.menu,
|
||||||
"meta": settings.meta,
|
"meta": settings.meta,
|
||||||
|
@ -2563,11 +2612,13 @@ def make():
|
||||||
start = int(round(time.time() * 1000))
|
start = int(round(time.time() * 1000))
|
||||||
last = 0
|
last = 0
|
||||||
|
|
||||||
|
# get incoming webmentions
|
||||||
if not (
|
if not (
|
||||||
settings.args.get("offline") or settings.args.get("noservices")
|
settings.args.get("offline") or settings.args.get("noservices")
|
||||||
):
|
):
|
||||||
incoming = WebmentionIO()
|
incoming = WebmentionIO()
|
||||||
incoming.run()
|
incoming.run()
|
||||||
|
# TODO get queued micropub posts?
|
||||||
|
|
||||||
queue = AQ()
|
queue = AQ()
|
||||||
outbox = []
|
outbox = []
|
||||||
|
@ -2584,6 +2635,7 @@ def make():
|
||||||
worldmap = WorldMap()
|
worldmap = WorldMap()
|
||||||
postcount = 0
|
postcount = 0
|
||||||
commentcount = 0
|
commentcount = 0
|
||||||
|
micropub = Micropub()
|
||||||
|
|
||||||
for e in glob.glob(os.path.join(content, "*", "*.url")):
|
for e in glob.glob(os.path.join(content, "*", "*.url")):
|
||||||
post = Redirect(e)
|
post = Redirect(e)
|
||||||
|
@ -2606,6 +2658,7 @@ def make():
|
||||||
or settings.args.get("noservices")
|
or settings.args.get("noservices")
|
||||||
):
|
):
|
||||||
queue.put(i.backfill_syndication())
|
queue.put(i.backfill_syndication())
|
||||||
|
micropub.add_tags(post.tags)
|
||||||
|
|
||||||
for i in post.images.values():
|
for i in post.images.values():
|
||||||
queue.put(i.downsize())
|
queue.put(i.downsize())
|
||||||
|
@ -2669,13 +2722,23 @@ def make():
|
||||||
home.add(category, category.get(category.sortedkeys[0]))
|
home.add(category, category.get(category.sortedkeys[0]))
|
||||||
queue.put(category.render())
|
queue.put(category.render())
|
||||||
|
|
||||||
|
# RSS and ATOM feeds
|
||||||
queue.put(frontposts.render_feeds())
|
queue.put(frontposts.render_feeds())
|
||||||
|
|
||||||
|
# home
|
||||||
queue.put(home.render())
|
queue.put(home.render())
|
||||||
|
|
||||||
|
# worldmap for photos
|
||||||
queue.put(worldmap.render())
|
queue.put(worldmap.render())
|
||||||
|
|
||||||
|
# fediverse stats
|
||||||
fediversemockery = FediverseStats(postcount, commentcount)
|
fediversemockery = FediverseStats(postcount, commentcount)
|
||||||
queue.put(fediversemockery.render())
|
queue.put(fediversemockery.render())
|
||||||
micropub = Micropub()
|
|
||||||
|
# micropub handler PHP
|
||||||
queue.put(micropub.render())
|
queue.put(micropub.render())
|
||||||
|
|
||||||
|
# render all the things!
|
||||||
queue.run()
|
queue.run()
|
||||||
|
|
||||||
# copy static files
|
# copy static files
|
||||||
|
@ -2695,15 +2758,7 @@ def make():
|
||||||
try:
|
try:
|
||||||
logger.info("starting syncing")
|
logger.info("starting syncing")
|
||||||
os.system(
|
os.system(
|
||||||
"rsync -avuhH --delete-after %s/ %s/"
|
f"rsync -avuhH --delete-after {settings.paths.build}/ {settings.syncserver}:{settings.paths.remotewww}"
|
||||||
% (
|
|
||||||
settings.paths.get("build"),
|
|
||||||
"%s/%s"
|
|
||||||
% (
|
|
||||||
settings.syncserver,
|
|
||||||
settings.paths.get("remotewww"),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
logger.info("syncing finished")
|
logger.info("syncing finished")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|
20
requirements.txt
Normal file
20
requirements.txt
Normal file
|
@ -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
|
13
settings.py
13
settings.py
|
@ -18,7 +18,7 @@ class nameddict(dict):
|
||||||
|
|
||||||
|
|
||||||
base = os.path.abspath(os.path.expanduser("~/Projects/petermolnar.net"))
|
base = os.path.abspath(os.path.expanduser("~/Projects/petermolnar.net"))
|
||||||
syncserver = "liveserver:/web/petermolnar.net"
|
syncserver = "liveserver"
|
||||||
|
|
||||||
pagination = 42
|
pagination = 42
|
||||||
notinfeed = ["note"]
|
notinfeed = ["note"]
|
||||||
|
@ -73,6 +73,7 @@ site = nameddict(
|
||||||
"https://t.me/petermolnar",
|
"https://t.me/petermolnar",
|
||||||
"https://twitter.com/petermolnar",
|
"https://twitter.com/petermolnar",
|
||||||
"https://mastodon.social/@petermolnar"
|
"https://mastodon.social/@petermolnar"
|
||||||
|
"https://www.flickr.com/people/petermolnareu/"
|
||||||
],
|
],
|
||||||
"follows": "https://petermolnar.net/following.opml",
|
"follows": "https://petermolnar.net/following.opml",
|
||||||
},
|
},
|
||||||
|
@ -168,9 +169,8 @@ paths = nameddict(
|
||||||
base, "nasg", "templates", "watermark.png"
|
base, "nasg", "templates", "watermark.png"
|
||||||
),
|
),
|
||||||
"build": os.path.join(base, "www"),
|
"build": os.path.join(base, "www"),
|
||||||
"queue": os.path.join(base, "queue"),
|
"remotewww": "/web/petermolnar.net/web",
|
||||||
"remotewww": "web",
|
"remotequeue": "/web/petermolnar.net/queue",
|
||||||
"remotequeue": "queue",
|
|
||||||
"micropub": os.path.join(base, "content", "note"),
|
"micropub": os.path.join(base, "content", "note"),
|
||||||
"home": os.path.join(base, "content", "home", "index.md"),
|
"home": os.path.join(base, "content", "home", "index.md"),
|
||||||
"category": "category",
|
"category": "category",
|
||||||
|
@ -210,6 +210,11 @@ photo = nameddict(
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
mapbox = nameddict({
|
||||||
|
"style": "outdoors-v11",
|
||||||
|
"size": "720x480"
|
||||||
|
})
|
||||||
|
|
||||||
rewrites = {
|
rewrites = {
|
||||||
"^/(?:sysadmin|it|linux-tech-coding|sysadmin-blog)/?(page.*)?$": "category/article/",
|
"^/(?:sysadmin|it|linux-tech-coding|sysadmin-blog)/?(page.*)?$": "category/article/",
|
||||||
"^/(?:fotography|photoblog)/?(page.*)?$": "/category/photo/",
|
"^/(?:fotography|photoblog)/?(page.*)?$": "/category/photo/",
|
||||||
|
|
|
@ -15,14 +15,16 @@
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<main id="main" class="h-feed hatom">
|
<main id="main" class="h-feed hatom">
|
||||||
<section class="intro">
|
<section id="intro">
|
||||||
<div>
|
<div>
|
||||||
{{ post.text }}
|
{{ post.text }}
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
{% set isFrontPage = 1 %}
|
||||||
|
<section id="latest">
|
||||||
|
<h1>Latest entries</h1>
|
||||||
{% for category, post in posts %}
|
{% for category, post in posts %}
|
||||||
<section id="home">
|
|
||||||
<h2>in:
|
<h2>in:
|
||||||
<a href="{{ category.url|relurl(baseurl) }}">
|
<a href="{{ category.url|relurl(baseurl) }}">
|
||||||
<svg width="16" height="16"><use xlink:href="#icon-{{ category.name }}" /></svg>
|
<svg width="16" height="16"><use xlink:href="#icon-{{ category.name }}" /></svg>
|
||||||
|
@ -30,7 +32,7 @@
|
||||||
</a>
|
</a>
|
||||||
</h2>
|
</h2>
|
||||||
{% include 'meta-article.j2.html' %}
|
{% include 'meta-article.j2.html' %}
|
||||||
|
{% endfor %}
|
||||||
</section>
|
</section>
|
||||||
{% endfor %}
|
|
||||||
</main>
|
</main>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -121,12 +121,21 @@ function save_to_wallabag($url) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function maybe_array_pop($x) {
|
||||||
|
if(is_array($x)) {
|
||||||
|
return array_pop($x);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return $x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!empty($_GET)) {
|
if (!empty($_GET)) {
|
||||||
if ( ! isset($_GET['q']) ) {
|
if ( ! isset($_GET['q']) ) {
|
||||||
badrequest('please POST a micropub request');
|
badrequest('please POST a micropub request');
|
||||||
}
|
}
|
||||||
if ( isset($_GET['q']['config']) ) {
|
if ( isset($_GET['q']['config']) ) {
|
||||||
httpok(json_encode(array('tags' => array())));
|
httpok('{{tags|tojson(indent=4)}}');
|
||||||
}
|
}
|
||||||
if(isset($_GET['q']['syndicate-to'])) {
|
if(isset($_GET['q']['syndicate-to'])) {
|
||||||
httpok(json_encode(array('syndicate-to' => array())));
|
httpok(json_encode(array('syndicate-to' => array())));
|
||||||
|
@ -134,12 +143,14 @@ if (!empty($_GET)) {
|
||||||
badrequest('please POST a micropub request');
|
badrequest('please POST a micropub request');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
$raw = file_get_contents("php://input");
|
$raw = file_get_contents("php://input");
|
||||||
|
$decoded = 'null';
|
||||||
try {
|
try {
|
||||||
$decoded = json_decode($raw, true);
|
$decoded = json_decode($raw, true);
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
_syslog('failed to decode JSON, trying decoding form data');
|
_syslog('failed to decode JSON, trying decoding form data');
|
||||||
|
}
|
||||||
|
if($decoded == 'null' or empty($decoded)) {
|
||||||
try {
|
try {
|
||||||
parse_str($raw, $decoded);
|
parse_str($raw, $decoded);
|
||||||
}
|
}
|
||||||
|
@ -165,17 +176,31 @@ else {
|
||||||
verify_token($token);
|
verify_token($token);
|
||||||
}
|
}
|
||||||
|
|
||||||
$source_url = '';
|
/* likes and bookmarks */
|
||||||
|
$bookmark_url = '';
|
||||||
if(isset($decoded["properties"]) && isset($decoded["properties"]["like-of"])) {
|
if(isset($decoded["properties"]) && isset($decoded["properties"]["like-of"])) {
|
||||||
$source_url = $decoded["properties"]["like-of"];
|
$bookmark_url = maybe_array_pop($decoded["properties"]["like-of"]);
|
||||||
}
|
}
|
||||||
elseif(isset($decoded["like-of"])) {
|
elseif(isset($decoded["like-of"])) {
|
||||||
$source_url = $decoded["like-of"];
|
$bookmark_url = maybe_array_pop($decoded["like-of"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* deal with like: forward it to wallabag */
|
if(!empty($bookmark_url)) {
|
||||||
if(!empty($source_url)) {
|
save_to_wallabag($bookmark_url);
|
||||||
save_to_wallabag($source_url);
|
accepted();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* save everything else into the queue for now */
|
||||||
|
$t = microtime(true);
|
||||||
|
$fpath = "/web/petermolnar.net/queue/{$t}.json";
|
||||||
|
if(!is_dir(dirname($fpath))) {
|
||||||
|
mkdir(dirname($fpath), 0755, true);
|
||||||
|
}
|
||||||
|
$c = json_encode($decoded, JSON_PRETTY_PRINT);
|
||||||
|
if (file_put_contents($fpath, $c)) {
|
||||||
|
accepted();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* fallback to not implemented */
|
||||||
notimplemented();
|
notimplemented();
|
||||||
|
|
|
@ -136,7 +136,6 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<div class="e-content entry-content">
|
<div class="e-content entry-content">
|
||||||
{{ post.text|relurl(baseurl) }}
|
{{ post.text|relurl(baseurl) }}
|
||||||
</div>
|
</div>
|
||||||
|
@ -214,7 +213,7 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if post['@type'] == 'Photograph' %}
|
{% if post['@type'] == 'Photograph' %}
|
||||||
{% if post.image[0].locationCreated %}
|
{% if post.image[0].locationCreated %}
|
||||||
from the location
|
photographed at the location of
|
||||||
<a class="h-geo" href="https://www.openstreetmap.org/#map=14/{{ post.image[0].locationCreated.geo.longitude }}/{{ post.image[0].locationCreated.geo.latitude }}">
|
<a class="h-geo" href="https://www.openstreetmap.org/#map=14/{{ post.image[0].locationCreated.geo.longitude }}/{{ post.image[0].locationCreated.geo.latitude }}">
|
||||||
<span class="p-latitude">{{ post.image[0].locationCreated.geo.latitude }}</span>,
|
<span class="p-latitude">{{ post.image[0].locationCreated.geo.latitude }}</span>,
|
||||||
<span class="p-longitude">{{ post.image[0].locationCreated.geo.longitude }}</span>
|
<span class="p-longitude">{{ post.image[0].locationCreated.geo.longitude }}</span>
|
||||||
|
|
|
@ -134,11 +134,11 @@
|
||||||
twitter
|
twitter
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{% elif 'mastodon' in url %}
|
{% elif 'flickr' in url %}
|
||||||
<li>
|
<li>
|
||||||
<a rel="me" href="{{ url }}">
|
<a rel="me" href="{{ url }}">
|
||||||
<svg width="16" height="16"><use xlink:href="#icon-mastodon.social" /></svg>
|
<svg width="16" height="16"><use xlink:href="#icon-www.flickr.com" /></svg>
|
||||||
mastodon
|
flickr
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
|
@ -1,11 +1,4 @@
|
||||||
{% if 'Photograph' == post['@type'] and post.image[0].width > post.image[0].height %}
|
<article class="h-entry hentry" lang="{{ post.inLanguage }}">
|
||||||
{% set flexval_raw = post.image[0].width / post.image[0].height %}
|
|
||||||
{% else %}
|
|
||||||
{% set flexval_raw = 1 %}
|
|
||||||
{% endif %}
|
|
||||||
{% set flexval = flexval_raw|round|int %}
|
|
||||||
|
|
||||||
<article class="h-entry hentry" style="flex-grow: {{ flexval }}" lang="{{ post.inLanguage }}">
|
|
||||||
<header class="entry-header">
|
<header class="entry-header">
|
||||||
<h3 class="p-name entry-title">
|
<h3 class="p-name entry-title">
|
||||||
{% if post.mentions %}
|
{% if post.mentions %}
|
||||||
|
@ -31,16 +24,12 @@
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
{% if post.description|length %}
|
{% if post.description|length %}
|
||||||
<section class="e-summary entry-summary">
|
{% set summary = post.description %}
|
||||||
{{ post.description|relurl(baseurl) }}
|
|
||||||
<span class="more">
|
|
||||||
<a href="{{ post.url|relurl(baseurl) }}">
|
|
||||||
{% if post.inLanguage == 'hu' %}Tovább »{% else %}Continue »{% endif %}
|
|
||||||
</a>
|
|
||||||
</span>
|
|
||||||
</section>
|
|
||||||
{% else %}
|
{% else %}
|
||||||
<section>
|
{% set summary = post.text|truncate(255) %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if post['@type'] == 'Photograph' %}
|
||||||
{% if post.image|length %}
|
{% if post.image|length %}
|
||||||
{% for image in post.image %}
|
{% for image in post.image %}
|
||||||
{% if image.representativeOfPage %}
|
{% if image.representativeOfPage %}
|
||||||
|
@ -48,12 +37,15 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<div class="e-content entry-content">
|
|
||||||
{{ post.text|relurl(baseurl) }}
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
<div class="e-summary entry-summary">
|
||||||
|
{{ summary|relurl(baseurl) }}
|
||||||
|
<span class="more">
|
||||||
|
<a href="{{ post.url|relurl(baseurl) }}">
|
||||||
|
{% if post.inLanguage == 'hu' %}Tovább »{% else %}Continue »{% endif %}
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
<footer class="entry-footer" aria-hidden="true" hidden="hidden">
|
<footer class="entry-footer" aria-hidden="true" hidden="hidden">
|
||||||
Published at
|
Published at
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
|
||||||
* {
|
* {
|
||||||
-webkit-box-sizing: border-box;
|
-webkit-box-sizing: border-box;
|
||||||
-moz-box-sizing: border-box;
|
-moz-box-sizing: border-box;
|
||||||
|
@ -355,12 +356,26 @@ li p {
|
||||||
|
|
||||||
padding: 1em;
|
padding: 1em;
|
||||||
margin:1em 0;
|
margin:1em 0;
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.h-feed .h-entry h3 {
|
.h-feed .h-entry h3 {
|
||||||
margin:0;
|
margin:0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
.h-feed .h-entry {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.h-feed .e-summary {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 4em;
|
||||||
|
background-color: rgba(0, 0, 0, 0.7);
|
||||||
|
padding: 0 1em 1em 1em;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
#syndication {
|
#syndication {
|
||||||
display: block;
|
display: block;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
|
@ -412,40 +427,3 @@ li p {
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media all and (min-width: 70em) {
|
|
||||||
#main.photo {
|
|
||||||
max-width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#main.photo {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
align-items:stretch;
|
|
||||||
}
|
|
||||||
|
|
||||||
#main.photo article {
|
|
||||||
flex: 1 1 30em;
|
|
||||||
margin: 0.2em;
|
|
||||||
max-width: 70em;
|
|
||||||
}
|
|
||||||
|
|
||||||
#main.photo article h3 {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
#main.photo article section p,
|
|
||||||
#main.photo article section section,
|
|
||||||
#main.photo article h3 {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
#main.photo article * > img {
|
|
||||||
height: 20em;
|
|
||||||
max-width: 100%;
|
|
||||||
min-width: 100%;
|
|
||||||
object-fit:contain;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
|
@ -32,9 +32,7 @@ function setTheme(e) {
|
||||||
localStorage.removeItem(STORAGE_KEY);
|
localStorage.removeItem(STORAGE_KEY);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(confirm("I\'ll need to store your choice in your browser, in a place called localStorage.\n\nAre you OK with this?")) {
|
localStorage.setItem(STORAGE_KEY, mode);
|
||||||
localStorage.setItem(STORAGE_KEY, mode);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
autoTheme(mql);
|
autoTheme(mql);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue