- relative urls!
- got rid of bleach and reacji detection, nobody is using it - removed google vision and google text classification - 410 for ^/tag and ^/comment - 80x15 SVG bottom banners - better code syntax hightlight CSS
This commit is contained in:
parent
f47ed93fa0
commit
9a5c4708d2
18 changed files with 555 additions and 328 deletions
27
Pipfile
27
Pipfile
|
@ -1,22 +1,19 @@
|
|||
[[source]]
|
||||
name = "pypi"
|
||||
url = "https://pypi.org/simple"
|
||||
url = "https://pypi.python.org/simple"
|
||||
verify_ssl = true
|
||||
name = "pypi"
|
||||
|
||||
[packages]
|
||||
wand = "*"
|
||||
arrow = "*"
|
||||
unicode-slugify = "*"
|
||||
requests = "*"
|
||||
python-frontmatter = "*"
|
||||
langdetect = "*"
|
||||
jinja2 = "*"
|
||||
feedgen = "*"
|
||||
|
||||
[dev-packages]
|
||||
|
||||
[packages]
|
||||
arrow = "*"
|
||||
bleach = "*"
|
||||
emoji = "*"
|
||||
feedgen = "*"
|
||||
langdetect = "*"
|
||||
requests = "*"
|
||||
unicode-slugify = "*"
|
||||
Jinja2 = "*"
|
||||
Wand = "*"
|
||||
pyyaml = "*"
|
||||
python-frontmatter = "*"
|
||||
|
||||
[requires]
|
||||
python_version = "3.7"
|
||||
|
|
91
Pipfile.lock
generated
91
Pipfile.lock
generated
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "61a7889c295e0054b0526ddb11e48b5f8297c57bc7ce3196e9d49c602146e208"
|
||||
"sha256": "da45b393e04bad2e1be92dde0f79ba517e3cb90e0db5f76afdc3754f638b38bf"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
|
@ -10,7 +10,7 @@
|
|||
"sources": [
|
||||
{
|
||||
"name": "pypi",
|
||||
"url": "https://pypi.org/simple",
|
||||
"url": "https://pypi.python.org/simple",
|
||||
"verify_ssl": true
|
||||
}
|
||||
]
|
||||
|
@ -18,18 +18,11 @@
|
|||
"default": {
|
||||
"arrow": {
|
||||
"hashes": [
|
||||
"sha256:9cb4a910256ed536751cd5728673bfb53e6f0026e240466f90c2a92c0b79c895"
|
||||
"sha256:3397e5448952e18e1295bf047014659effa5ae8da6a5371d37ff0ddc46fa6872",
|
||||
"sha256:6f54d9f016c0b7811fac9fb8c2c7fa7421d80c54dbdd75ffb12913c55db60b8a"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.13.0"
|
||||
},
|
||||
"bleach": {
|
||||
"hashes": [
|
||||
"sha256:213336e49e102af26d9cde77dd2d0397afabc5a6bf2fed985dc35b5d1e285a16",
|
||||
"sha256:3fdf7f77adcf649c9911387df51254b813185e32b2c6619f690b593a617e19fa"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==3.1.0"
|
||||
"version": "==0.13.1"
|
||||
},
|
||||
"certifi": {
|
||||
"hashes": [
|
||||
|
@ -45,14 +38,6 @@
|
|||
],
|
||||
"version": "==3.0.4"
|
||||
},
|
||||
"emoji": {
|
||||
"hashes": [
|
||||
"sha256:1e959336dafc7a5ed2c0256ee587bbd38a7187d772141f0b5ba42de9e08599a8",
|
||||
"sha256:a9e9c08be9907c0042212c86dfbea0f61f78e9897d4df41a1d6307017763ad3e"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.5.1"
|
||||
},
|
||||
"feedgen": {
|
||||
"hashes": [
|
||||
"sha256:82c9e29884e137c3e3e7959a02f142d1f7a46cd387d572e9e40150112a27604f"
|
||||
|
@ -84,34 +69,34 @@
|
|||
},
|
||||
"lxml": {
|
||||
"hashes": [
|
||||
"sha256:0dd6589fa75d369ba06d2b5f38dae107f76ea127f212f6a7bee134f6df2d1d21",
|
||||
"sha256:1afbac344aa68c29e81ab56c1a9411c3663157b5aee5065b7fa030b398d4f7e0",
|
||||
"sha256:1baad9d073692421ad5dbbd81430aba6c7f5fdc347f03537ae046ddf2c9b2297",
|
||||
"sha256:1d8736421a2358becd3edf20260e41a06a0bf08a560480d3a5734a6bcbacf591",
|
||||
"sha256:1e1d9bddc5afaddf0de76246d3f2152f961697ad7439c559f179002682c45801",
|
||||
"sha256:1f179dc8b2643715f020f4d119d5529b02cd794c1c8f305868b73b8674d2a03f",
|
||||
"sha256:241fb7bdf97cb1df1edfa8f0bcdfd80525d4023dac4523a241907c8b2f44e541",
|
||||
"sha256:2f9765ee5acd3dbdcdc0d0c79309e01f7c16bc8d39b49250bf88de7b46daaf58",
|
||||
"sha256:312e1e1b1c3ce0c67e0b8105317323e12807955e8186872affb667dbd67971f6",
|
||||
"sha256:3273db1a8055ca70257fd3691c6d2c216544e1a70b673543e15cc077d8e9c730",
|
||||
"sha256:34dfaa8c02891f9a246b17a732ca3e99c5e42802416628e740a5d1cb2f50ff49",
|
||||
"sha256:3aa3f5288af349a0f3a96448ebf2e57e17332d99f4f30b02093b7948bd9f94cc",
|
||||
"sha256:51102e160b9d83c1cc435162d90b8e3c8c93b28d18d87b60c56522d332d26879",
|
||||
"sha256:56115fc2e2a4140e8994eb9585119a1ae9223b506826089a3ba753a62bd194a6",
|
||||
"sha256:69d83de14dbe8fe51dccfd36f88bf0b40f5debeac763edf9f8325180190eba6e",
|
||||
"sha256:99fdce94aeaa3ccbdfcb1e23b34273605c5853aa92ec23d84c84765178662c6c",
|
||||
"sha256:a7c0cd5b8a20f3093ee4a67374ccb3b8a126743b15a4d759e2a1bf098faac2b2",
|
||||
"sha256:abe12886554634ed95416a46701a917784cb2b4c77bfacac6916681d49bbf83d",
|
||||
"sha256:b4f67b5183bd5f9bafaeb76ad119e977ba570d2b0e61202f534ac9b5c33b4485",
|
||||
"sha256:bdd7c1658475cc1b867b36d5c4ed4bc316be8d3368abe03d348ba906a1f83b0e",
|
||||
"sha256:c6f24149a19f611a415a51b9bc5f17b6c2f698e0d6b41ffb3fa9f24d35d05d73",
|
||||
"sha256:d1e111b3ab98613115a208c1017f266478b0ab224a67bc8eac670fa0bad7d488",
|
||||
"sha256:d6520aa965773bbab6cb7a791d5895b00d02cf9adc93ac2bf4edb9ac1a6addc5",
|
||||
"sha256:dd185cde2ccad7b649593b0cda72021bc8a91667417001dbaf24cd746ecb7c11",
|
||||
"sha256:de2e5b0828a9d285f909b5d2e9d43f1cf6cf21fe65bc7660bdaa1780c7b58298",
|
||||
"sha256:f726444b8e909c4f41b4fde416e1071cf28fa84634bfb4befdf400933b6463af"
|
||||
"sha256:0537eee4902e8bf4f41bfee8133f7edf96533dd175930a12086d6a40d62376b2",
|
||||
"sha256:0562ec748abd230ab87d73384e08fa784f9b9cee89e28696087d2d22c052cc27",
|
||||
"sha256:09e91831e749fbf0f24608694e4573be0ef51430229450c39c83176cc2e2d353",
|
||||
"sha256:1ae4c0722fc70c0d4fba43ae33c2885f705e96dce1db41f75ae14a2d2749b428",
|
||||
"sha256:1c630c083d782cbaf1f7f37f6cac87bda9cff643cf2803a5f180f30d97955cef",
|
||||
"sha256:2fe74e3836bd8c0fa7467ffae05545233c7f37de1eb765cacfda15ad20c6574a",
|
||||
"sha256:37af783c2667ead34a811037bda56a0b142ac8438f7ed29ae93f82ddb812fbd6",
|
||||
"sha256:3f2d9eafbb0b24a33f56acd16f39fc935756524dcb3172892721c54713964c70",
|
||||
"sha256:47d8365a8ef14097aa4c65730689be51851b4ade677285a3b2daa03b37893e26",
|
||||
"sha256:510e904079bc56ea784677348e151e1156040dbfb736f1d8ea4b9e6d0ab2d9f4",
|
||||
"sha256:58d0851da422bba31c7f652a7e9335313cf94a641aa6d73b8f3c67602f75b593",
|
||||
"sha256:7940d5c2185ffb989203dacbb28e6ae88b4f1bb25d04e17f94b0edd82232bcbd",
|
||||
"sha256:7cf39bb3a905579836f7a8f3a45320d9eb22f16ab0c1e112efb940ced4d057a5",
|
||||
"sha256:9563a23c1456c0ab550c087833bc13fcc61013a66c6420921d5b70550ea312bf",
|
||||
"sha256:95b392952935947e0786a90b75cc33388549dcb19af716b525dae65b186138fc",
|
||||
"sha256:983129f3fd3cef5c3cf067adcca56e30a169656c00fcc6c648629dbb850b27fa",
|
||||
"sha256:a0b75b1f1854771844c647c464533def3e0a899dd094a85d1d4ed72ecaaee93d",
|
||||
"sha256:b5db89cc0ef624f3a81214b7961a99f443b8c91e88188376b6b322fd10d5b118",
|
||||
"sha256:c0a7751ba1a4bfbe7831920d98cee3ce748007eab8dfda74593d44079568219a",
|
||||
"sha256:c0c5a7d4aafcc30c9b6d8613a362567e32e5f5b708dc41bc3a81dac56f8af8bb",
|
||||
"sha256:d4d63d85eacc6cb37b459b16061e1f100d154bee89dc8d8f9a6128a5a538e92e",
|
||||
"sha256:da5e7e941d6e71c9c9a717c93725cda0708c2474f532e3680ac5e39ec57d224d",
|
||||
"sha256:dccad2b3c583f036f43f80ac99ee212c2fa9a45151358d55f13004d095e683b2",
|
||||
"sha256:df46307d39f2aeaafa1d25309b8a8d11738b73e9861f72d4d0a092528f498baa",
|
||||
"sha256:e70b5e1cb48828ddd2818f99b1662cb9226dc6f57d07fc75485405c77da17436",
|
||||
"sha256:ea825562b8cd057cbc9810d496b8b5dec37a1e2fc7b27bc7c1e72ce94462a09a"
|
||||
],
|
||||
"version": "==4.3.0"
|
||||
"version": "==4.3.1"
|
||||
},
|
||||
"markupsafe": {
|
||||
"hashes": [
|
||||
|
@ -175,7 +160,6 @@
|
|||
"sha256:e01d3203230e1786cd91ccfdc8f8454c8069c91bee3962ad93b87a4b2860f537",
|
||||
"sha256:e170a9e6fcfd19021dd29845af83bb79236068bf5fd4df3327c1be18182b2531"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==3.13"
|
||||
},
|
||||
"requests": {
|
||||
|
@ -216,17 +200,10 @@
|
|||
},
|
||||
"wand": {
|
||||
"hashes": [
|
||||
"sha256:3e59e4bda9ef9d643d90e881cc950c8eee1508ec2cde1c150a1cbd5a12c1c007",
|
||||
"sha256:52763dbf65d00cf98d7bc910b49329eea15896249c5555d47e169f2b6efbe166"
|
||||
"sha256:7d6b8dc9d4eaccc430b9c86e6b749013220c994970a3f39e902b397e2fa732c3",
|
||||
"sha256:cc0b5c9cd50fecd10dc8888b739dd5984c6f8085d2954f34903b83ca39a91236"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.5.0"
|
||||
},
|
||||
"webencodings": {
|
||||
"hashes": [
|
||||
"sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78",
|
||||
"sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"
|
||||
],
|
||||
"version": "==0.5.1"
|
||||
}
|
||||
},
|
||||
|
|
18
assets/cc-button.svg
Normal file
18
assets/cc-button.svg
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="80" height="15" version="1.1" viewBox="0 0 80 15" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect y="0" width="80" height="15"/>
|
||||
<rect x="1" y="1" width="78" height="13" fill="#fff"/>
|
||||
<rect x="2" y="2" width="76" height="11"/>
|
||||
<path d="m42 5h1v1h1v1h1v-1h1v-1h1v5h-1v-3h-1v1h-1v-1h-1v3h-1z" fill="#fff"/>
|
||||
<path d="m31 5h2v1h1v1h-1v-1h-2v3h2v-1h1v1h-1v1h-2v-1h-1v-3h1z" fill="#fff"/>
|
||||
<path d="m37 5v1h2v-1zm2 1v3h1v-3zm0 3h-2v1h2zm-2 0v-3h-1v3z" fill="#fff"/>
|
||||
<path d="m57 5v1h2v-1zm2 1v3h1v-3zm0 3h-2v1h2zm-2 0v-3h-1v3z" fill="#fff"/>
|
||||
<path d="m49 5h1v1h1v1h1v-1h1v-1h1v5h-1v-3h-1v1h-1v-1h-1v3h-1z" fill="#fff"/>
|
||||
<path d="m70 5h3v1h-3v1h2v1h1v1h-1v1h-3v-1h3v-1h-2v-1h-1v-1h1" fill="#fff"/>
|
||||
<path d="m62 5h1v1h1v1h1v1h1v-3h1v5h-1v-1h-1v-1h-1v-1h-1v3h-1z" fill="#fff"/>
|
||||
<path d="m2 2v11h19.891a8.5136 8.5 0 0 0 2.1088-5.5898 8.5136 8.5 0 0 0-1.9563-5.4102h-13.119z" fill="#abb1aa"/>
|
||||
<path d="m6.0195 2a8.5 8.5 0 0 0-2.0195 5.5 8.5 8.5 0 0 0 2.0312 5.5h12.949a8.5 8.5 0 0 0 2.0195-5.5 8.5 8.5 0 0 0-2.0312-5.5z"/>
|
||||
<circle cx="12.5" cy="7.5" r="6.5" fill="#feffff"/>
|
||||
<path d="m9 5h2v1h1v1h-1v-1h-2v3h2v-1h1v1h-1v1h-2v-1h-1v-3h1z"/>
|
||||
<path d="m14 5h2v1h1v1h-1v-1h-2v3h2v-1h1v1h-1v1h-2v-1h-1v-3h1z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
27
assets/indieweb-button.svg
Normal file
27
assets/indieweb-button.svg
Normal file
|
@ -0,0 +1,27 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="80" height="15" version="1.1" viewBox="0 0 80 15" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="80" height="15" fill="#666"/>
|
||||
<rect x="1" y="1" width="78" height="13" fill="#fff"/>
|
||||
<path d="m3 4v2h7v-2h-7zm0 3v4h7v-4h-7z" fill="#fc0d1b"/>
|
||||
<path d="m11 4v2h1v-2h-1zm1 2v3h1v-3h-1zm1 0h1v3h1v2h2v-2h1v-3h1v-2h-6v2zm1 3h-1v2h1v-2z" fill="#fc5d20"/>
|
||||
<polygon points="21 4 25 4 25 5 26 5 26 7 22 7 22 8 26 8 26 10 25 10 25 11 21 11 21 10 20 10 20 8 19 8 19 7 20 7 20 5 21 5" fill="#fdb02a"/>
|
||||
<rect x="29" y="2" width="49" height="1" fill="#fda829"/>
|
||||
<rect x="29" y="3" width="49" height="1" fill="#fd9c27"/>
|
||||
<rect x="29" y="4" width="49" height="1" fill="#fd9025"/>
|
||||
<rect x="29" y="5" width="49" height="1" fill="#fd8124"/>
|
||||
<rect x="29" y="6" width="49" height="1" fill="#fd7222"/>
|
||||
<rect x="29" y="7" width="49" height="1" fill="#fd6420"/>
|
||||
<rect x="29" y="8" width="49" height="1" fill="#fc561f"/>
|
||||
<rect x="29" y="9" width="49" height="1" fill="#fc481e"/>
|
||||
<rect x="29" y="10" width="49" height="1" fill="#fc371d"/>
|
||||
<rect x="29" y="11" width="49" height="1" fill="#fc291c"/>
|
||||
<rect x="29" y="12" width="49" height="1" fill="#fc1c1c"/>
|
||||
<path d="m34 5h1v5h-1z" fill="#fff"/>
|
||||
<path d="m37 5h1v1h1v1h1v1h1v-3h1v5h-1v-1h-1v-1h-1v-1h-1v3h-1z" fill="#fff"/>
|
||||
<path d="m44 5v5h3v-1h-2v-3h2v-1h-3zm3 1v3h1v-3h-1z" fill="#fff"/>
|
||||
<path d="m50 5h1v5h-1z" fill="#fff"/>
|
||||
<path d="m53 5h3v1h-2v1h2v1h-2v1h2v1h-3z" fill="#fff"/>
|
||||
<path d="m58 5h1v4h1v-3h1v3h1v-4h1v4h-1v1h-1v-1h-1v1h-1v-1h-1z" fill="#fff"/>
|
||||
<path d="m65 5h3v1h-2v1h2v1h-2v1h2v1h-3z" fill="#fff"/>
|
||||
<path d="m70 5v5h3v-1h-2v-1h2v-1h-2v-1h2v-1h-3zm3 1v1h1v-1h-1zm0 2v1h1v-1h-1z" fill="#fff"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.7 KiB |
50
assets/microformats-button.svg
Normal file
50
assets/microformats-button.svg
Normal file
|
@ -0,0 +1,50 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="80" height="15" version="1.1" viewBox="0 0 80 15" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="80" height="15" fill="#666"/>
|
||||
<rect x="1" y="1" width="78" height="13" fill="#fff"/>
|
||||
<rect x="18" y="2" width="2" height="11" fill="#5d8f17"/>
|
||||
<rect x="20" y="2" width="2" height="11" fill="#609218"/>
|
||||
<rect x="22" y="2" width="2" height="11" fill="#639519"/>
|
||||
<rect x="24" y="2" width="2" height="11" fill="#66981a"/>
|
||||
<rect x="26" y="2" width="2" height="11" fill="#699b1b"/>
|
||||
<rect x="28" y="2" width="2" height="11" fill="#6c9e1b"/>
|
||||
<rect x="30" y="2" width="2" height="11" fill="#6fa11c"/>
|
||||
<rect x="32" y="2" width="2" height="11" fill="#72a51d"/>
|
||||
<rect x="34" y="2" width="2" height="11" fill="#76a81e"/>
|
||||
<rect x="36" y="2" width="2" height="11" fill="#78aa1f"/>
|
||||
<rect x="38" y="2" width="2" height="11" fill="#7cae20"/>
|
||||
<rect x="40" y="2" width="2" height="11" fill="#7eb120"/>
|
||||
<rect x="42" y="2" width="2" height="11" fill="#82b421"/>
|
||||
<rect x="44" y="2" width="2" height="11" fill="#85b722"/>
|
||||
<rect x="46" y="2" width="2" height="11" fill="#88ba23"/>
|
||||
<rect x="48" y="2" width="2" height="11" fill="#8bbd24"/>
|
||||
<rect x="50" y="2" width="2" height="11" fill="#8ec125"/>
|
||||
<rect x="52" y="2" width="2" height="11" fill="#91c325"/>
|
||||
<rect x="54" y="2" width="2" height="11" fill="#94c626"/>
|
||||
<rect x="56" y="2" width="2" height="11" fill="#97ca27"/>
|
||||
<rect x="58" y="2" width="2" height="11" fill="#9acd28"/>
|
||||
<rect x="60" y="2" width="2" height="11" fill="#9dd029"/>
|
||||
<rect x="62" y="2" width="2" height="11" fill="#a0d32a"/>
|
||||
<rect x="64" y="2" width="2" height="11" fill="#a4d62b"/>
|
||||
<rect x="66" y="2" width="2" height="11" fill="#a6d92b"/>
|
||||
<rect x="68" y="2" width="2" height="11" fill="#a8db2c"/>
|
||||
<rect x="70" y="2" width="2" height="11" fill="#acdf2d"/>
|
||||
<rect x="72" y="2" width="2" height="11" fill="#b0e32e"/>
|
||||
<rect x="74" y="2" width="2" height="11" fill="#b3e62f"/>
|
||||
<rect x="76" y="2" width="2" height="11" fill="#b6e92f"/>
|
||||
<polygon points="4 4 6 4 6 9 7 9 7 10 12 10 12 12 11 12 11 13 4 13 4 12 3 12 3 5 4 5" fill="#5c8d17"/>
|
||||
<polygon points="7 3 9 3 9 6 10 6 10 7 13 7 13 9 8 9 8 8 7 8" fill="#8dc024"/>
|
||||
<polygon points="10 2 13 2 13 3 14 3 14 6 11 6 11 5 10 5" fill="#a5d82b"/>
|
||||
<path d="m20 5h1v1h1v1h1v-1h1v-1h1v5h-1v-3h-1v1h-1v-1h-1v3h-1z" fill="#fff"/>
|
||||
<path d="m26 5h1v5h-1z" fill="#fff"/>
|
||||
<path d="m29 5h2v1h1v1h-1v-1h-2v3h2v-1h1v1h-1v1h-2v-1h-1v-3h1z" fill="#fff"/>
|
||||
<path d="m33 5v5h1v-2h1v1h1v-2h-2v-1h2v-1h-3zm3 1v1h1v-1h-1zm0 3v1h1v-1h-1z" fill="#fff"/>
|
||||
<path d="m39 5v1h2v-1h-2zm2 1v1 1 1h1v-1-1-1h-1zm0 3h-2v1h2v-1zm-2 0v-3h-1v3h1z" fill="#fff"/>
|
||||
<path d="m43 5h3v1h-2v1h2v1h-2v2h-1z" fill="#fff"/>
|
||||
<path d="m48 5v1h2v-1h-2zm2 1v1 1 1h1v-1-1-1h-1zm0 3h-2v1h2v-1zm-2 0v-3h-1v3h1z" fill="#fff"/>
|
||||
<path d="m52 5v5h1v-2h1v1h1v-2h-2v-1h2v-1h-3zm3 1v1h1v-1h-1zm0 3v1h1v-1h-1z" fill="#fff"/>
|
||||
<path d="m57 5h1v1h1v1h1v-1h1v-1h1v5h-1v-3h-1v1h-1v-1h-1v3h-1z" fill="#fff"/>
|
||||
<path d="m64 5v1h2v-1h-2zm2 1v1h-2v-1h-1v4h1v-2h2v2h1v-4h-1z" fill="#fff"/>
|
||||
<path d="m68 5h3v1h-1v4h-1v-4h-1" fill="#fff"/>
|
||||
<path d="m73 5h3v1h-3v1h2v1h1v1h-1v1h-3v-1h3v-1h-2v-1h-1v-1h1" fill="#fff"/>
|
||||
</svg>
|
After Width: | Height: | Size: 3.2 KiB |
17
assets/webmention-button.svg
Normal file
17
assets/webmention-button.svg
Normal file
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="80" height="15" version="1.1" viewBox="0 0 80 15" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="80" height="15" fill="#666"/>
|
||||
<rect x="1" y="1" width="78" height="13" fill="#fff" style="paint-order:markers fill stroke"/>
|
||||
<path d="m13 1v1h-1v1h-1v1h1 1v1h-1v2h-1v2h-1v-3h-1v-2h-1v2h-1v3h-1v-2h-1v-3h-1v-2h-1-1v2h1v3h1v3h1v3h1 1v-3h1v-2h1v2h1v3h1 1v-3h1v-3h1v-3h1 1v-1h-1v-1h-1v-1h-1z" fill="#610371"/>
|
||||
<rect x="19" y="2" width="59" height="11" fill="#850e9a"/>
|
||||
<path d="m33 5v5h3v-1h-2v-1h2v-1h-2v-1h2v-1h-3zm3 1v1h1v-1h-1zm0 2v1h1v-1h-1z" fill="#fff"/>
|
||||
<path d="m28 5h3v1h-2v1h2v1h-2v1h2v1h-3z" fill="#fff"/>
|
||||
<path d="m21 5h1v4h1v-3h1v3h1v-4h1v4h-1v1h-1v-1h-1v1h-1v-1h-1z" fill="#fff"/>
|
||||
<path d="m39 5h1v1h1v1h1v-1h1v-1h1v5h-1v-3h-1v1h-1v-1h-1v3h-1z" fill="#fff"/>
|
||||
<path d="m51 5h1v1h1v1h1v1h1v-3h1v5h-1v-1h-1v-1h-1v-1h-1v3h-1z" fill="#fff"/>
|
||||
<path d="m58 5h3v1h-1v4h-1v-4h-1" fill="#fff"/>
|
||||
<path d="m63 5h1v5h-1z" fill="#fff"/>
|
||||
<path d="m67 5v1h2v-1zm2 1v3h1v-3zm0 3h-2v1h2zm-2 0v-3h-1v3z" fill="#fff"/>
|
||||
<path d="m71 5h1v1h1v1h1v1h1v-3h1v5h-1v-1h-1v-1h-1v-1h-1v3h-1z" fill="#fff"/>
|
||||
<path d="m46 5h3v1h-2v1h2v1h-2v1h2v1h-3z" fill="#fff"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.2 KiB |
126
meta.py
126
meta.py
|
@ -13,8 +13,6 @@ import requests
|
|||
import keys
|
||||
import settings
|
||||
|
||||
from pprint import pprint
|
||||
|
||||
EXIFDATE = re.compile(
|
||||
r'^(?P<year>[0-9]{4}):(?P<month>[0-9]{2}):(?P<day>[0-9]{2})\s+'
|
||||
r'(?P<time>[0-9]{2}:[0-9]{2}:[0-9]{2})$'
|
||||
|
@ -69,130 +67,6 @@ class CachedMeta(dict):
|
|||
for k, v in data.items():
|
||||
self[k] = v
|
||||
|
||||
class GoogleClassifyText(CachedMeta):
|
||||
def __init__(self, fpath, txt, lang='en'):
|
||||
self.fpath = fpath
|
||||
self.txt = txt
|
||||
self.lang = lang
|
||||
self._read()
|
||||
|
||||
def _call_tool(self):
|
||||
params = {
|
||||
"document": {
|
||||
"type": "PLAIN_TEXT",
|
||||
"content": self.txt,
|
||||
"language": self.lang,
|
||||
}
|
||||
}
|
||||
|
||||
url = "https://language.googleapis.com/v1beta2/documents:classifyText?key=%s" % (
|
||||
keys.gcloud.get('key')
|
||||
)
|
||||
logging.info(
|
||||
"calling Google classifyText for %s",
|
||||
self.fpath
|
||||
)
|
||||
try:
|
||||
r = requests.post(url, json=params)
|
||||
resp = r.json()
|
||||
for cat in resp.get('categories', []):
|
||||
self[cat.get('name')] = cat.get('confidence')
|
||||
except Exception as e:
|
||||
logging.error(
|
||||
'failed to call Google Vision API on: %s, reason: %s',
|
||||
self.fpath,
|
||||
e
|
||||
)
|
||||
|
||||
class GoogleVision(CachedMeta):
|
||||
def __init__(self, fpath, imgurl):
|
||||
self.fpath = fpath
|
||||
self.imgurl = imgurl
|
||||
self._read()
|
||||
|
||||
@property
|
||||
def response(self):
|
||||
if 'responses' not in self:
|
||||
return {}
|
||||
if not len(self['responses']):
|
||||
return {}
|
||||
if 'labelAnnotations' not in self['responses'][0]:
|
||||
return {}
|
||||
return self['responses'][0]
|
||||
|
||||
@property
|
||||
def tags(self):
|
||||
tags = []
|
||||
|
||||
if 'labelAnnotations' in self.response:
|
||||
for label in self.response['labelAnnotations']:
|
||||
tags.append(label['description'])
|
||||
|
||||
if 'webDetection' in self.response:
|
||||
if 'webEntities' in self.response['webDetection']:
|
||||
for label in self.response['webDetection']['webEntities']:
|
||||
tags.append(label['description'])
|
||||
return tags
|
||||
|
||||
@property
|
||||
def landmark(self):
|
||||
landmark = None
|
||||
if 'landmarkAnnotations' in self.response:
|
||||
if len(self.response['landmarkAnnotations']):
|
||||
match = self.response['landmarkAnnotations'].pop()
|
||||
landmark = {
|
||||
'name': match['description'],
|
||||
'latitude': match['locations'][0]['latLng']['latitude'],
|
||||
'longitude': match['locations'][0]['latLng']['longitude']
|
||||
}
|
||||
return landmark
|
||||
|
||||
@property
|
||||
def onlinecopies(self):
|
||||
copies = []
|
||||
if 'webDetection' in self.response:
|
||||
if 'pagesWithMatchingImages' in self.response['webDetection']:
|
||||
for match in self.response['webDetection']['pagesWithMatchingImages']:
|
||||
copies.append(match['url'])
|
||||
return copies
|
||||
|
||||
def _call_tool(self):
|
||||
params = {
|
||||
"requests": [{
|
||||
"image": {"source": {"imageUri": self.imgurl}},
|
||||
"features": [
|
||||
{
|
||||
"type": "LANDMARK_DETECTION",
|
||||
},
|
||||
{
|
||||
"type": "WEB_DETECTION",
|
||||
},
|
||||
{
|
||||
"type": "LABEL_DETECTION",
|
||||
}
|
||||
]
|
||||
}]
|
||||
}
|
||||
|
||||
url = "https://vision.googleapis.com/v1/images:annotate?key=%s" % (
|
||||
keys.gcloud.get('key')
|
||||
)
|
||||
logging.info(
|
||||
"calling Google Vision for %s",
|
||||
self.fpath
|
||||
)
|
||||
|
||||
try:
|
||||
r = requests.post(url, json=params)
|
||||
resp = r.json()
|
||||
for k, v in resp.items():
|
||||
self[k] = v
|
||||
except Exception as e:
|
||||
logging.error(
|
||||
'failed to call Google Vision API on: %s, reason: %s',
|
||||
self.fpath,
|
||||
e
|
||||
)
|
||||
|
||||
class Exif(CachedMeta):
|
||||
def __init__(self, fpath):
|
||||
|
|
238
nasg.py
238
nasg.py
|
@ -15,11 +15,13 @@ import asyncio
|
|||
import sqlite3
|
||||
import json
|
||||
import queue
|
||||
import base64
|
||||
from shutil import copy2 as cp
|
||||
from math import ceil
|
||||
from urllib.parse import urlparse
|
||||
from collections import OrderedDict, namedtuple
|
||||
import logging
|
||||
|
||||
import arrow
|
||||
import langdetect
|
||||
import wand.image
|
||||
|
@ -27,17 +29,15 @@ import jinja2
|
|||
import yaml
|
||||
import frontmatter
|
||||
from feedgen.feed import FeedGenerator
|
||||
from bleach import clean
|
||||
from emoji import UNICODE_EMOJI
|
||||
from slugify import slugify
|
||||
import requests
|
||||
|
||||
from pandoc import PandocMarkdown
|
||||
from meta import Exif
|
||||
import settings
|
||||
from settings import struct
|
||||
import keys
|
||||
|
||||
from pprint import pprint
|
||||
|
||||
logger = logging.getLogger('NASG')
|
||||
|
||||
MarkdownImage = namedtuple(
|
||||
|
@ -45,8 +45,6 @@ MarkdownImage = namedtuple(
|
|||
['match', 'alt', 'fname', 'title', 'css']
|
||||
)
|
||||
|
||||
REPLY_TYPES = ['webmention', 'in-reply-to', 'reply']
|
||||
|
||||
J2 = jinja2.Environment(
|
||||
loader=jinja2.FileSystemLoader(searchpath=settings.paths.get('tmpl')),
|
||||
lstrip_blocks=True,
|
||||
|
@ -60,7 +58,7 @@ RE_MDIMG = re.compile(
|
|||
)
|
||||
|
||||
RE_CODE = re.compile(
|
||||
r'^(?:[~`]{3}).+$',
|
||||
r'^(?:[~`]{3,4}).+$',
|
||||
re.MULTILINE
|
||||
)
|
||||
|
||||
|
@ -68,6 +66,11 @@ RE_PRECODE = re.compile(
|
|||
r'<pre class="([^"]+)"><code>'
|
||||
)
|
||||
|
||||
def mtime(path):
|
||||
if os.path.exists(path):
|
||||
return int(os.path.getmtime(path))
|
||||
return 0
|
||||
|
||||
def utfyamldump(data):
|
||||
return yaml.dump(
|
||||
data,
|
||||
|
@ -83,12 +86,43 @@ def url2slug(url, limit=200):
|
|||
lower=True
|
||||
)[:limit]
|
||||
|
||||
J2.filters['url2slug'] = url2slug
|
||||
|
||||
def rfc3339todt(rfc3339):
|
||||
t = arrow.get(rfc3339).format('YYYY-MM-DD HH:mm ZZZ')
|
||||
return "%s" % (t)
|
||||
|
||||
J2.filters['printdate'] = rfc3339todt
|
||||
J2.filters['url2slug'] = url2slug
|
||||
|
||||
|
||||
RE_MYURL = re.compile(
|
||||
r'(^(%s[^"]+)$|"(%s[^"]+)")' % (
|
||||
settings.site.url,
|
||||
settings.site.url
|
||||
)
|
||||
)
|
||||
|
||||
def relurl(text, baseurl=None):
|
||||
if not baseurl:
|
||||
baseurl = settings.site.url
|
||||
for match, standalone, href in RE_MYURL.findall(text):
|
||||
needsquotes = False
|
||||
if len(href):
|
||||
needsquotes = True
|
||||
url = href
|
||||
else:
|
||||
url = standalone
|
||||
|
||||
r = os.path.relpath(url, baseurl)
|
||||
if url.endswith('/') and not r.endswith('/'):
|
||||
r = "%s/index.html" % r
|
||||
if needsquotes:
|
||||
r = '"%s"' % r
|
||||
logger.debug("RELURL: %s => %s (base: %s)", match, r, baseurl)
|
||||
text = text.replace(match, r)
|
||||
return text
|
||||
|
||||
J2.filters['relurl'] = relurl
|
||||
|
||||
def writepath(fpath, content, mtime=0):
|
||||
d = os.path.dirname(fpath)
|
||||
|
@ -126,6 +160,7 @@ class cached_property(object):
|
|||
|
||||
|
||||
class AQ:
|
||||
""" Async queue which starts execution right on population """
|
||||
def __init__(self):
|
||||
self.loop = asyncio.get_event_loop()
|
||||
self.queue = asyncio.Queue(loop=self.loop)
|
||||
|
@ -145,6 +180,7 @@ class AQ:
|
|||
|
||||
|
||||
class Webmention(object):
|
||||
""" outgoing webmention class """
|
||||
def __init__(self, source, target, dpath, mtime=0):
|
||||
self.source = source
|
||||
self.target = target
|
||||
|
@ -166,7 +202,7 @@ class Webmention(object):
|
|||
def exists(self):
|
||||
if not os.path.isfile(self.fpath):
|
||||
return False
|
||||
elif os.path.getmtime(self.fpath) > self.mtime:
|
||||
elif mtime(self.fpath) > self.mtime:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
@ -196,9 +232,10 @@ class Webmention(object):
|
|||
|
||||
|
||||
class MarkdownDoc(object):
|
||||
""" Base class for anything that is stored as .md """
|
||||
@property
|
||||
def mtime(self):
|
||||
return os.path.getmtime(self.fpath)
|
||||
return mtime(self.fpath)
|
||||
|
||||
@property
|
||||
def dt(self):
|
||||
|
@ -234,7 +271,7 @@ class MarkdownDoc(object):
|
|||
def content(self):
|
||||
return self._parsed[1]
|
||||
|
||||
def __pandoc(self, c):
|
||||
def pandoc(self, c):
|
||||
if c and len(c):
|
||||
c = PandocMarkdown(c)
|
||||
c = RE_PRECODE.sub(
|
||||
|
@ -247,7 +284,7 @@ class MarkdownDoc(object):
|
|||
if hasattr(self, 'images') and len(self.images):
|
||||
for match, img in self.images.items():
|
||||
c = c.replace(match, str(img))
|
||||
return self.__pandoc(c)
|
||||
return self.pandoc(c)
|
||||
|
||||
|
||||
class Comment(MarkdownDoc):
|
||||
|
@ -260,7 +297,7 @@ class Comment(MarkdownDoc):
|
|||
if maybe and 'null' != maybe:
|
||||
dt = arrow.get(maybe)
|
||||
else:
|
||||
dt = arrow.get(os.path.getmtime(self.fpath))
|
||||
dt = arrow.get(mtime(self.fpath))
|
||||
return dt
|
||||
|
||||
@property
|
||||
|
@ -295,11 +332,12 @@ class Comment(MarkdownDoc):
|
|||
|
||||
@property
|
||||
def type(self):
|
||||
if len(self.content):
|
||||
maybe = clean(self.content, strip=True)
|
||||
if maybe in UNICODE_EMOJI:
|
||||
return maybe
|
||||
return self.meta.get('type', 'webmention')
|
||||
#if len(self.content):
|
||||
#maybe = clean(self.content, strip=True)
|
||||
#if maybe in UNICODE_EMOJI:
|
||||
#return maybe
|
||||
|
||||
|
||||
@cached_property
|
||||
def jsonld(self):
|
||||
|
@ -322,7 +360,7 @@ class Gone(object):
|
|||
|
||||
def __init__(self, fpath):
|
||||
self.fpath = fpath
|
||||
self.mtime = os.path.getmtime(fpath)
|
||||
self.mtime = mtime(fpath)
|
||||
|
||||
@property
|
||||
def source(self):
|
||||
|
@ -472,7 +510,7 @@ class Singular(MarkdownDoc):
|
|||
def html_summary(self):
|
||||
c = self.summary
|
||||
if c and len(c):
|
||||
c = PandocMarkdown(self.summary)
|
||||
c = self.pandoc(self.summary)
|
||||
return c
|
||||
|
||||
@property
|
||||
|
@ -531,13 +569,14 @@ class Singular(MarkdownDoc):
|
|||
@property
|
||||
def to_ping(self):
|
||||
urls = []
|
||||
w = Webmention(
|
||||
self.url,
|
||||
'https://fed.brid.gy/',
|
||||
os.path.dirname(self.fpath),
|
||||
self.dt
|
||||
)
|
||||
urls.append(w)
|
||||
if not self.is_page and self.is_front:
|
||||
w = Webmention(
|
||||
self.url,
|
||||
'https://fed.brid.gy/',
|
||||
os.path.dirname(self.fpath),
|
||||
self.dt
|
||||
)
|
||||
urls.append(w)
|
||||
if self.is_reply:
|
||||
w = Webmention(
|
||||
self.url,
|
||||
|
@ -589,6 +628,47 @@ class Singular(MarkdownDoc):
|
|||
else:
|
||||
return False
|
||||
|
||||
#@cached_property
|
||||
#def oembed_xml(self):
|
||||
#oembed = etree.Element("oembed", version="1.0")
|
||||
#xmldoc = etree.ElementTree(oembed)
|
||||
#for k, v in self.oembed_json.items():
|
||||
#x = etree.SubElement(oembed, k).text = "%s" % (v)
|
||||
#s = etree.tostring(
|
||||
#xmldoc,
|
||||
#encoding='utf-8',
|
||||
#xml_declaration=True,
|
||||
#pretty_print=True
|
||||
#)
|
||||
#return s
|
||||
|
||||
#@cached_property
|
||||
#def oembed_json(self):
|
||||
#r = {
|
||||
#"version": "1.0",
|
||||
#"provider_name": settings.site.name,
|
||||
#"provider_url": settings.site.url,
|
||||
#"author_name": settings.author.name,
|
||||
#"author_url": settings.author.url,
|
||||
#"title": self.title,
|
||||
#"type": "link",
|
||||
#"html": self.html_content,
|
||||
#}
|
||||
|
||||
#img = None
|
||||
#if self.is_photo:
|
||||
#img = self.photo
|
||||
#elif not self.is_photo and len(self.images):
|
||||
#img = list(self.images.values())[0]
|
||||
#if img:
|
||||
#r.update({
|
||||
#"type": "rich",
|
||||
#"thumbnail_url": img.jsonld.thumbnail.url,
|
||||
#"thumbnail_width": img.jsonld.thumbnail.width,
|
||||
#"thumbnail_height": img.jsonld.thumbnail.height
|
||||
#})
|
||||
#return r
|
||||
|
||||
@cached_property
|
||||
def review(self):
|
||||
if 'review' not in self.meta:
|
||||
|
@ -632,7 +712,6 @@ class Singular(MarkdownDoc):
|
|||
}
|
||||
return r
|
||||
|
||||
|
||||
@cached_property
|
||||
def jsonld(self):
|
||||
r = {
|
||||
|
@ -665,11 +744,6 @@ class Singular(MarkdownDoc):
|
|||
"@type": "Photograph",
|
||||
"image": self.photo.jsonld,
|
||||
})
|
||||
elif not self.is_photo and len(self.images):
|
||||
img = list(self.images.values())[0]
|
||||
r.update({
|
||||
"image": img.jsonld,
|
||||
})
|
||||
elif self.has_code:
|
||||
r.update({
|
||||
"@type": "TechArticle",
|
||||
|
@ -678,7 +752,11 @@ class Singular(MarkdownDoc):
|
|||
r.update({
|
||||
"@type": "WebPage",
|
||||
})
|
||||
|
||||
if not self.is_photo and len(self.images):
|
||||
img = list(self.images.values())[0]
|
||||
r.update({
|
||||
"image": img.jsonld,
|
||||
})
|
||||
|
||||
if self.is_reply:
|
||||
r.update({
|
||||
|
@ -708,7 +786,7 @@ class Singular(MarkdownDoc):
|
|||
for mtime in sorted(self.comments.keys()):
|
||||
r["comment"].append(self.comments[mtime].jsonld)
|
||||
|
||||
return r
|
||||
return struct(r)
|
||||
|
||||
@property
|
||||
def template(self):
|
||||
|
@ -734,7 +812,7 @@ class Singular(MarkdownDoc):
|
|||
elif not os.path.exists(self.renderfile):
|
||||
logger.debug('rendering required: no html yet')
|
||||
return False
|
||||
elif self.dt > os.path.getmtime(self.renderfile):
|
||||
elif self.dt > mtime(self.renderfile):
|
||||
logger.debug('rendering required: self.dt > html mtime')
|
||||
return False
|
||||
else:
|
||||
|
@ -768,31 +846,40 @@ class Singular(MarkdownDoc):
|
|||
self.name,
|
||||
os.path.basename(f)
|
||||
)
|
||||
if os.path.exists(t) and os.path.getmtime(
|
||||
f) <= os.path.getmtime(t):
|
||||
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(self):
|
||||
if self.exists:
|
||||
return
|
||||
logger.info("rendering %s", self.name)
|
||||
r = J2.get_template(self.template).render({
|
||||
@cached_property
|
||||
def html(self):
|
||||
r = J2.get_template(self.template).render({
|
||||
'baseurl': self.url,
|
||||
'post': self.jsonld,
|
||||
'site': settings.site,
|
||||
'menu': settings.menu,
|
||||
'meta': settings.meta,
|
||||
})
|
||||
return r
|
||||
|
||||
async def render(self):
|
||||
if self.exists:
|
||||
return
|
||||
logger.info("rendering %s", self.name)
|
||||
writepath(
|
||||
self.renderfile,
|
||||
r
|
||||
self.html
|
||||
)
|
||||
j = settings.site.copy()
|
||||
j.update({
|
||||
"mainEntity": self.jsonld
|
||||
})
|
||||
writepath(
|
||||
self.renderfile.replace('.html', '.json'),
|
||||
json.dumps(self.jsonld, indent=4, ensure_ascii=False)
|
||||
os.path.join(self.renderdir,'index.json'),
|
||||
json.dumps(j, indent=4, ensure_ascii=False)
|
||||
)
|
||||
del(j)
|
||||
|
||||
|
||||
class Home(Singular):
|
||||
|
@ -844,7 +931,7 @@ class WebImage(object):
|
|||
self.mdimg = mdimg
|
||||
self.fpath = fpath
|
||||
self.parent = parent
|
||||
self.mtime = os.path.getmtime(self.fpath)
|
||||
self.mtime = mtime(self.fpath)
|
||||
self.fname, self.fext = os.path.splitext(os.path.basename(fpath))
|
||||
self.resized_images = [
|
||||
(k, self.Resized(self, k))
|
||||
|
@ -863,20 +950,20 @@ class WebImage(object):
|
|||
return True
|
||||
return False
|
||||
|
||||
@cached_property
|
||||
@property
|
||||
def jsonld(self):
|
||||
r = {
|
||||
"@context": "http://schema.org",
|
||||
"@type": "ImageObject",
|
||||
"url": self.href,
|
||||
"image": self.href,
|
||||
"thumbnail": {
|
||||
"thumbnail": struct({
|
||||
"@context": "http://schema.org",
|
||||
"@type": "ImageObject",
|
||||
"url": self.src,
|
||||
"width": self.displayed.width,
|
||||
"height": self.displayed.height,
|
||||
},
|
||||
}),
|
||||
"name": os.path.basename(self.fpath),
|
||||
"encodingFormat": self.mime_type,
|
||||
"contentSize": self.mime_size,
|
||||
|
@ -902,21 +989,7 @@ class WebImage(object):
|
|||
})
|
||||
if self.is_mainimg:
|
||||
r.update({"representativeOfPage": True})
|
||||
return r
|
||||
|
||||
#@cached_property
|
||||
#def tmplvars(self):
|
||||
#return {
|
||||
#'src': self.src,
|
||||
#'href': self.href,
|
||||
#'width': self.displayed.width,
|
||||
#'height': self.displayed.height,
|
||||
#'title': self.title,
|
||||
#'caption': self.caption,
|
||||
#'exif': self.exif,
|
||||
#'is_photo': self.is_photo,
|
||||
#'is_mainimg': self.is_mainimg
|
||||
#}
|
||||
return struct(r)
|
||||
|
||||
def __str__(self):
|
||||
if len(self.mdimg.css):
|
||||
|
@ -966,7 +1039,12 @@ class WebImage(object):
|
|||
|
||||
@property
|
||||
def mime_size(self):
|
||||
return os.path.getsize(self.linked.fpath)
|
||||
try:
|
||||
size = os.path.getsize(self.linked.fpath)
|
||||
except Exception as e:
|
||||
logger.error('Failed to get mime size of %s', self.linked.fpath)
|
||||
size = self.meta.get('FileSize', 0)
|
||||
return size
|
||||
|
||||
@property
|
||||
def displayed(self):
|
||||
|
@ -1101,6 +1179,12 @@ class WebImage(object):
|
|||
self.size = size
|
||||
self.crop = crop
|
||||
|
||||
@property
|
||||
def data(self):
|
||||
with open(self.fpath, 'rb') as f:
|
||||
encoded = base64.b64encode(f.read())
|
||||
return "data:%s;base64,%s" % (self.parent.mime_type, encoded.decode('utf-8'))
|
||||
|
||||
@property
|
||||
def suffix(self):
|
||||
return settings.photo.get('sizes').get(self.size, '')
|
||||
|
@ -1144,7 +1228,7 @@ class WebImage(object):
|
|||
@property
|
||||
def exists(self):
|
||||
if os.path.isfile(self.fpath):
|
||||
if os.path.getmtime(self.fpath) >= self.parent.mtime:
|
||||
if mtime(self.fpath) >= self.parent.mtime:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
@ -1216,13 +1300,13 @@ class PHPFile(object):
|
|||
return False
|
||||
if not os.path.exists(self.renderfile):
|
||||
return False
|
||||
if self.mtime > os.path.getmtime(self.renderfile):
|
||||
if self.mtime > mtime(self.renderfile):
|
||||
return False
|
||||
return True
|
||||
|
||||
@property
|
||||
def mtime(self):
|
||||
return os.path.getmtime(
|
||||
return mtime(
|
||||
os.path.join(
|
||||
settings.paths.get('tmpl'),
|
||||
self.templatefile
|
||||
|
@ -1238,8 +1322,8 @@ class PHPFile(object):
|
|||
raise ValueError('Not implemented')
|
||||
|
||||
async def render(self):
|
||||
if self.exists:
|
||||
return
|
||||
#if self.exists:
|
||||
#return
|
||||
await self._render()
|
||||
|
||||
|
||||
|
@ -1532,7 +1616,7 @@ class Category(dict):
|
|||
return False
|
||||
if not os.path.exists(fpath):
|
||||
return False
|
||||
if os.path.getmtime(fpath) >= ts:
|
||||
if mtime(fpath) >= ts:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
@ -1554,10 +1638,10 @@ class Category(dict):
|
|||
'title': self.title,
|
||||
}
|
||||
|
||||
def tmplvars(self, posts=[], year=False):
|
||||
def tmplvars(self, posts=[], year=None):
|
||||
baseurl = self.url
|
||||
if year:
|
||||
baseurl = '%s/%s/' % (baseurl, year)
|
||||
baseurl = '%s%s/' % (baseurl, year)
|
||||
return {
|
||||
'baseurl': baseurl,
|
||||
'site': settings.site,
|
||||
|
@ -1672,8 +1756,10 @@ class Category(dict):
|
|||
for year in self.years.keys():
|
||||
if year == self.newest_year:
|
||||
fpath = self.indexfpath()
|
||||
tyear = None
|
||||
else:
|
||||
fpath = self.indexfpath("%d" % (year))
|
||||
tyear = year
|
||||
y = arrow.get("%d" % year, self.trange).to('utc')
|
||||
tsmin = y.floor('year').timestamp
|
||||
tsmax = y.ceil('year').timestamp
|
||||
|
@ -1697,7 +1783,7 @@ class Category(dict):
|
|||
# some posts disappear
|
||||
# TODO figure this out...
|
||||
self.get_posts(start, end+1),
|
||||
year
|
||||
tyear
|
||||
)
|
||||
)
|
||||
writepath(fpath, r)
|
||||
|
@ -1752,7 +1838,7 @@ class Sitemap(dict):
|
|||
def mtime(self):
|
||||
r = 0
|
||||
if os.path.exists(self.renderfile):
|
||||
r = os.path.getmtime(self.renderfile)
|
||||
r = mtime(self.renderfile)
|
||||
return r
|
||||
|
||||
def append(self, post):
|
||||
|
@ -1969,7 +2055,7 @@ def make():
|
|||
if e.endswith('.md'):
|
||||
continue
|
||||
t = os.path.join(settings.paths.get('build'),os.path.basename(e))
|
||||
if os.path.exists(t) and os.path.getmtime(e) <= os.path.getmtime(t):
|
||||
if os.path.exists(t) and mtime(e) <= mtime(t):
|
||||
continue
|
||||
cp(e, t)
|
||||
|
||||
|
|
24
settings.py
24
settings.py
|
@ -9,6 +9,13 @@ import re
|
|||
import argparse
|
||||
import logging
|
||||
|
||||
|
||||
class struct(dict):
|
||||
__getattr__ = dict.get
|
||||
__setattr__ = dict.__setitem__
|
||||
__delattr__ = dict.__delitem__
|
||||
|
||||
|
||||
base = os.path.abspath(os.path.expanduser('~/Projects/petermolnar.net'))
|
||||
syncserver = 'liveserver:/web/petermolnar.net'
|
||||
|
||||
|
@ -17,12 +24,12 @@ notinfeed = ['note']
|
|||
flat = ['article', 'journal']
|
||||
displaydate = 'YYYY-MM-DD HH:mm'
|
||||
|
||||
class struct(dict):
|
||||
__getattr__ = dict.get
|
||||
__setattr__ = dict.__setitem__
|
||||
__delattr__ = dict.__delitem__
|
||||
licence = struct({
|
||||
'article': 'CC-BY-4.0',
|
||||
'journal': 'CC-BY-NC-4.0',
|
||||
'_default': 'CC-BY-NC-ND-4.0'
|
||||
})
|
||||
|
||||
# full author, only for h-card generation
|
||||
author = struct({
|
||||
"@context": "http://schema.org",
|
||||
"@type": "Person",
|
||||
|
@ -39,6 +46,7 @@ site = struct({
|
|||
"url": "https://petermolnar.net",
|
||||
"name": "petermolnar.net",
|
||||
"image": "https://petermolnar.net/favicon.ico",
|
||||
"license": "https://spdx.org/licenses/%s.html" % (licence['_default']),
|
||||
"author": {
|
||||
"@context": "http://schema.org",
|
||||
"@type": "Person",
|
||||
|
@ -128,12 +136,6 @@ menu = {
|
|||
}
|
||||
}
|
||||
|
||||
licence = struct({
|
||||
'article': 'CC-BY-4.0',
|
||||
'journal': 'CC-BY-NC-4.0',
|
||||
'_default': 'CC-BY-NC-ND-4.0'
|
||||
})
|
||||
|
||||
meta = struct({
|
||||
'webmention': 'https://webmention.io/petermolnar.net/webmention',
|
||||
'pingback': 'https://webmention.io/petermolnar.net/xmlrpc',
|
||||
|
|
|
@ -23,6 +23,8 @@ $gone = array(
|
|||
|
||||
$gone_re = array(
|
||||
'^cache\/.*$',
|
||||
'^tag\/.*$',
|
||||
'^comment\/.*$',
|
||||
'^files\/.*$',
|
||||
'^wp-content\/.*$',
|
||||
'^broadcast\/wp-ffpc\.message$',
|
||||
|
@ -50,12 +52,12 @@ function gone($uri) {
|
|||
<body>
|
||||
<h1><center>This content was deleted.</center></h1>
|
||||
<hr>
|
||||
<p><center>{{ site.domain }}</center></p>
|
||||
<p><center>'.$uri.'</center></p>
|
||||
</body>
|
||||
</html>');
|
||||
}
|
||||
|
||||
function notfound() {
|
||||
function notfound($uri) {
|
||||
header('HTTP/1.0 404 Not Found');
|
||||
die('<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
@ -70,13 +72,15 @@ function notfound() {
|
|||
<h2><center>Please search for it instead.</center></h2>
|
||||
<p>
|
||||
<center>
|
||||
<form action="/search.php" class="search-form" method="get" role="search">
|
||||
<label for="search">Search</label>
|
||||
<input id="q" name="q" placeholder="search..." title="Search for:" type="search" value=""/>
|
||||
<input type="submit" value="OK"/>
|
||||
</form>
|
||||
<form action="/search.php" class="search-form" method="get" role="search">
|
||||
<label for="search">Search</label>
|
||||
<input id="q" name="q" placeholder="search..." title="Search for:" type="search" value=""/>
|
||||
<input type="submit" value="OK"/>
|
||||
</form>
|
||||
</center>
|
||||
</p>
|
||||
<hr>
|
||||
<p><center>'.$uri.'</center></p>
|
||||
</body>
|
||||
</html>');
|
||||
}
|
||||
|
@ -120,5 +124,5 @@ elseif (strstr($uri, '_')) {
|
|||
maybe_redirect(str_replace('_', '-', $uri));
|
||||
}
|
||||
else {
|
||||
notfound();
|
||||
notfound($uri);
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
<nav>
|
||||
<ul>
|
||||
{% for y, url in category.years.items() %}
|
||||
{% if y == category.year %}
|
||||
{% if (y == category.year) or (not category.year and loop.first) %}
|
||||
<li>
|
||||
<span>
|
||||
{{ y }}
|
||||
|
@ -21,7 +21,7 @@
|
|||
</li>
|
||||
{% else %}
|
||||
<li>
|
||||
<a href="{{ url }}">
|
||||
<a href="{{ url|relurl(baseurl) }}">
|
||||
<strong>{{ y }}</strong>
|
||||
</a>
|
||||
</li>
|
||||
|
@ -53,7 +53,7 @@
|
|||
{% endif %}
|
||||
{% set _ = year.append(post.copyrightYear)%}
|
||||
{% include 'meta-article.j2.html' %}
|
||||
{% if loop.last %}
|
||||
{% if not category.paginated and loop.last %}
|
||||
</section>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
{% for category, post in posts %}
|
||||
<section>
|
||||
<h2>in:
|
||||
<a href="{{ category.url }}/">
|
||||
<a href="{{ category.url|relurl(baseurl) }}/">
|
||||
<svg width="16" height="16"><use xlink:href="#icon-{{ category.name }}" /></svg>
|
||||
{{ category.name }}
|
||||
</a>
|
||||
|
|
|
@ -7,6 +7,9 @@
|
|||
{% block meta %}
|
||||
<meta name="description" content="{{ post.description|striptags|e }}" />
|
||||
<link rel="canonical" href="{{ post.url }}" />
|
||||
<link rel="alternate" type="application/json" href="{{ post.url }}index.json" />
|
||||
<link rel="alternate" type="application/ld+json" href="{{ post.url }}index.json" />
|
||||
<link rel="alternate" type="application/mf2+json" href="https://pin13.net/mf2/?url={{ post.url|urlencode }}" />
|
||||
<meta property="og:title" content="{{ post.headline }}" />
|
||||
<meta property="og:type" content="article" />
|
||||
<meta property="og:url" content="{{ post.url }}" />
|
||||
|
@ -38,6 +41,16 @@
|
|||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block cc %}
|
||||
<li>
|
||||
<a href="{{ post.license }}">
|
||||
<svg width="80" height="15">
|
||||
<use xlink:href="#button-cc"/>
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<main>
|
||||
<article class="h-entry hentry" lang="{{ post.inLanguage }}" id="article">
|
||||
|
@ -48,7 +61,7 @@
|
|||
<svg width="16" height="16">
|
||||
<use xlink:href="#icon-reply" />
|
||||
</svg>
|
||||
<a href="{{ post.url }}">
|
||||
<a href="{{ post.url|relurl(baseurl) }}">
|
||||
RE:
|
||||
</a>
|
||||
<a href="{{ post.mentions.url }}" class="u-in-reply-to">
|
||||
|
@ -56,7 +69,7 @@
|
|||
</a>
|
||||
</span>
|
||||
{% else %}
|
||||
<a href="{{ post.url }}">
|
||||
<a href="{{ post.url|relurl(baseurl) }}">
|
||||
{{ post.headline }}
|
||||
</a>
|
||||
{% endif %}
|
||||
|
@ -65,7 +78,7 @@
|
|||
|
||||
{% if post.review %}
|
||||
<div class="h-review hreview">
|
||||
<strong>Review summary of: <a href="{{ post.review.url }}" class="p-name u-url p-item h-product item fn">{{ post.review.name }}</a></strong>
|
||||
<strong>Review summary of: <a href="{{ post.review.url }}" class="p-name u-url p-item h-product item fn url">{{ post.review.name }}</a></strong>
|
||||
<p>
|
||||
By
|
||||
<span class="p-author h-card reviewer vcard">
|
||||
|
@ -86,12 +99,12 @@
|
|||
|
||||
{% if post.description|length %}
|
||||
<div class="e-summary entry-summary">
|
||||
{{ post.description }}
|
||||
{{ post.description|relurl(baseurl) }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="e-content entry-content">
|
||||
{{ post.text }}
|
||||
{{ post.text|relurl(baseurl) }}
|
||||
</div>
|
||||
|
||||
<footer>
|
||||
|
@ -164,7 +177,7 @@
|
|||
|
||||
<dt>Author</dt>
|
||||
<dd class="p-author h-card vcard">
|
||||
<img class="u-photo photo" src="{{ post.author.image }}" alt="" />
|
||||
<img class="u-photo photo" src="{{ post.author.image|relurl(baseurl) }}" alt="" />
|
||||
<a class="p-name u-url fn url" href="{{ post.author.url }}">{{ post.author.name }}</a>
|
||||
<a class="u-email email" href="mailto:{{ post.author.email }}">{{ post.author.email }}</a>
|
||||
</dd>
|
||||
|
@ -227,13 +240,24 @@
|
|||
<ol>
|
||||
{% for comment in post.comment %}
|
||||
<li class="h-entry p-comment hentry">
|
||||
<a href="{{ comment.url }}">
|
||||
{{ comment.disambiguatingDescription }}
|
||||
</a>
|
||||
<i>
|
||||
{% if 'like-of' == comment.disambiguatingDescription %}
|
||||
{% set icon = 'star' %}
|
||||
{% elif 'bookmark-of' == comment.disambiguatingDescription %}
|
||||
{% set icon = 'bookmark' %}
|
||||
{% elif 'reply' == comment.disambiguatingDescription %}
|
||||
{% set icon = 'reply' %}
|
||||
{% else %}
|
||||
{% set icon = 'link' %}
|
||||
{% endif %}
|
||||
<svg width="16" height="16">
|
||||
<use xlink:href="#icon-{{ icon }}"></use>
|
||||
</svg>
|
||||
</i>
|
||||
from
|
||||
<span class="p-author h-card vcard">
|
||||
{% if comment.author.url %}
|
||||
<a class="u-url p-name fn" href="{{ comment.author.url }}">
|
||||
<a class="u-url p-name fn url org" href="{{ comment.author.url }}">
|
||||
{{ comment.author.name }}
|
||||
</a>
|
||||
{% else %}
|
||||
|
@ -247,9 +271,6 @@
|
|||
{{ comment.datePublished|printdate }}
|
||||
</time>
|
||||
<br />
|
||||
<svg width="16" height="16">
|
||||
<use xlink:href="#icon-link"></use>
|
||||
</svg>
|
||||
<a class="u-url" href="{{ comment.url }}">
|
||||
{{ comment.url }}
|
||||
</a>
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
<!DOCTYPE html>
|
||||
<html{% block lang %}{% endblock %} prefix="og: http://ogp.me/ns# article: http://ogp.me/ns/article#">
|
||||
<head>
|
||||
<!--[if lt IE 9]>
|
||||
<script src="{{ site.url}}/html5shiv-printshiv.js"></script>
|
||||
<![endif]-->
|
||||
<title>{% block title %}{% endblock %}</title>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1" />
|
||||
<meta name="author" content="{{ site.author.name }} ({{ site.author.email }})" />
|
||||
<link rel="icon" href="{{ site.image }}" />
|
||||
<!-- <base href="{{ baseurl }}" /> -->
|
||||
{% for key, value in meta.items() %}
|
||||
<link rel="{{ key }}" href="{{ value }}" />
|
||||
{% endfor %}
|
||||
|
@ -35,7 +39,7 @@
|
|||
<ul>
|
||||
{% for key, data in menu.items() %}
|
||||
<li>
|
||||
<a title="{{ data.text }}" href="{{ data.url }}" {{ activemenu(key) }} >
|
||||
<a title="{{ data.text }}" href="{{ data.url|relurl(baseurl) }}" {{ activemenu(key) }} >
|
||||
<svg width="16" height="16">
|
||||
<use xlink:href="#icon-{{ key }}" />
|
||||
</svg>
|
||||
|
@ -62,7 +66,7 @@
|
|||
</form>
|
||||
{% for action in site.potentialAction %}
|
||||
{% if 'SearchAction' == action['@type'] %}
|
||||
<form role="search" method="get" action="{{ action.url }}">
|
||||
<form role="search" method="get" action="{{ action.url|relurl(baseurl) }}">
|
||||
<label for="qsub">
|
||||
<input type="submit" value="search" id="qsub" name="qsub" />
|
||||
<svg width="16" height="16">
|
||||
|
@ -88,7 +92,7 @@
|
|||
<p>
|
||||
<a href="https://creativecommons.org/">CC</a>,
|
||||
1999-2019,
|
||||
<img class="u-photo photo" src="{{ site.author.image }}" alt="Photo of {{ site.author.name }}" />
|
||||
<img class="u-photo photo" src="{{ site.author.image|relurl(baseurl) }}" alt="Photo of {{ site.author.name }}" />
|
||||
<a class="p-name u-url fn url" href="{{ site.author.url }}" rel="me"> {{ site.author.name }}</a>
|
||||
<a class="u-email email" rel="me" href="mailto:{{ site.author.email }}">
|
||||
<svg width="16" height="16">
|
||||
|
@ -138,6 +142,42 @@
|
|||
<a href="https://xn--sr8hvo.ws/🇻🇮📢/next">→</a>
|
||||
</nav>
|
||||
</section>
|
||||
<section>
|
||||
<nav>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="https://indieweb.org/">
|
||||
<svg width="80" height="15">
|
||||
<use xlink:href="#button-indieweb"/>
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://microformats.org/">
|
||||
<svg width="80" height="15">
|
||||
<use xlink:href="#button-microformats"/>
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://www.w3.org/TR/webmention/">
|
||||
<svg width="80" height="15">
|
||||
<use xlink:href="#button-webmention"/>
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
{% block cc %}
|
||||
<li>
|
||||
<a href="{{ site.license }}">
|
||||
<svg width="80" height="15">
|
||||
<use xlink:href="#button-cc"/>
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
{% endblock %}
|
||||
</ul>
|
||||
</nav>
|
||||
</section>
|
||||
</footer>
|
||||
|
||||
<script>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<svg width="16" height="16">
|
||||
<use xlink:href="#icon-reply" />
|
||||
</svg>
|
||||
<a href="{{ post.url }}">
|
||||
<a href="{{ post.url|relurl(baseurl) }}">
|
||||
RE:
|
||||
</a>
|
||||
<a href="{{ post.mentions.url }}" class="u-in-reply-to">
|
||||
|
@ -14,7 +14,7 @@
|
|||
</a>
|
||||
</span>
|
||||
{% else %}
|
||||
<a href="{{ post.url }}">
|
||||
<a href="{{ post.url|relurl(baseurl) }}">
|
||||
{{ post.headline }}
|
||||
</a>
|
||||
{% endif %}
|
||||
|
@ -25,16 +25,16 @@
|
|||
|
||||
{% if post.description|length %}
|
||||
<div class="e-summary entry-summary">
|
||||
{{ post.description }}
|
||||
{{ post.description|relurl(baseurl) }}
|
||||
<span class="more">
|
||||
<a href="{{ post.url }}">
|
||||
<a href="{{ post.url|relurl(baseurl) }}">
|
||||
{% if post.inLanguage == 'hu' %}Tovább »{% else %}Continue »{% endif %}
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="e-content entry-content">
|
||||
{{ post.text }}
|
||||
{{ post.text|relurl(baseurl) }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
|
@ -44,8 +44,8 @@
|
|||
<time datetime="{{ post.dateModified }}" class="dt-updated updated"></time>
|
||||
by
|
||||
<span class="p-author h-card vcard">
|
||||
<img class="u-photo photo" src="{{ post.author.image }}" alt="" />
|
||||
<a class="p-name u-url fn url" href="{{ post.author.url }}">{{ post.author.name }}</a>
|
||||
<img class="u-photo photo" src="{{ post.author.image|relurl(baseurl) }}" alt="" />
|
||||
<a class="p-name u-url fn url org" href="{{ post.author.url }}">{{ post.author.name }}</a>
|
||||
<a class="u-email email" href="mailto:{{ post.author.email }}">{{ post.author.email }}</a>
|
||||
</span>
|
||||
</footer>
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
.token.comment,
|
||||
.token.prolog,
|
||||
.token.doctype,
|
||||
|
@ -20,7 +19,7 @@
|
|||
.token.constant,
|
||||
.token.symbol,
|
||||
.token.deleted {
|
||||
color: #905;
|
||||
color: #f05;
|
||||
}
|
||||
|
||||
.token.selector,
|
||||
|
@ -29,7 +28,7 @@
|
|||
.token.char,
|
||||
.token.builtin,
|
||||
.token.inserted {
|
||||
color: #690;
|
||||
color: #7a0;
|
||||
}
|
||||
|
||||
.token.operator,
|
||||
|
@ -43,7 +42,7 @@
|
|||
.token.atrule,
|
||||
.token.attr-value,
|
||||
.token.keyword {
|
||||
color: #07a;
|
||||
color: #09c;
|
||||
}
|
||||
|
||||
.token.function,
|
||||
|
@ -67,4 +66,4 @@
|
|||
|
||||
.token.entity {
|
||||
cursor: help;
|
||||
}
|
||||
}
|
|
@ -1,5 +1,3 @@
|
|||
|
||||
|
||||
* {
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
|
@ -358,4 +356,4 @@ body > img {
|
|||
right: 0;
|
||||
width: 10em;
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -71,4 +71,121 @@
|
|||
<symbol id="icon-resume" viewBox="0 0 16 16">
|
||||
<path d="M13.5 0h-12c-0.825 0-1.5 0.675-1.5 1.5v13c0 0.825 0.675 1.5 1.5 1.5h12c0.825 0 1.5-0.675 1.5-1.5v-13c0-0.825-0.675-1.5-1.5-1.5zM13 14h-11v-12h11v12zM4 9h7v1h-7zM4 11h7v1h-7zM5 4.5c0-0.828 0.672-1.5 1.5-1.5s1.5 0.672 1.5 1.5c0 0.828-0.672 1.5-1.5 1.5s-1.5-0.672-1.5-1.5zM7.5 6h-2c-0.825 0-1.5 0.45-1.5 1v1h5v-1c0-0.55-0.675-1-1.5-1z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-bookmark" viewBox="0 0 16 16">
|
||||
<path d="M4 2v14l5-5 5 5v-14zM12 0h-10v14l1-1v-12h9z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-star" viewBox="0 0 16 16">
|
||||
<path d="M16 6.204l-5.528-0.803-2.472-5.009-2.472 5.009-5.528 0.803 4 3.899-0.944 5.505 4.944-2.599 4.944 2.599-0.944-5.505 4-3.899z"></path>
|
||||
</symbol>
|
||||
<symbol id="icon-reply" viewBox="0 0 16 16">
|
||||
<path d="M7 12.119v3.881l-6-6 6-6v3.966c6.98 0.164 6.681-4.747 4.904-7.966 4.386 4.741 3.455 12.337-4.904 12.119z"></path>
|
||||
</symbol>
|
||||
<symbol id="button-indieweb" viewBox="0 0 80 15">
|
||||
<rect width="80" height="15" fill="#666"/>
|
||||
<rect x="1" y="1" width="78" height="13" fill="#fff"/>
|
||||
<path d="m3 4v2h7v-2h-7zm0 3v4h7v-4h-7z" fill="#fc0d1b"/>
|
||||
<path d="m11 4v2h1v-2h-1zm1 2v3h1v-3h-1zm1 0h1v3h1v2h2v-2h1v-3h1v-2h-6v2zm1 3h-1v2h1v-2z" fill="#fc5d20"/>
|
||||
<polygon points="21 4 25 4 25 5 26 5 26 7 22 7 22 8 26 8 26 10 25 10 25 11 21 11 21 10 20 10 20 8 19 8 19 7 20 7 20 5 21 5" fill="#fdb02a"/>
|
||||
<rect x="29" y="2" width="49" height="1" fill="#fda829"/>
|
||||
<rect x="29" y="3" width="49" height="1" fill="#fd9c27"/>
|
||||
<rect x="29" y="4" width="49" height="1" fill="#fd9025"/>
|
||||
<rect x="29" y="5" width="49" height="1" fill="#fd8124"/>
|
||||
<rect x="29" y="6" width="49" height="1" fill="#fd7222"/>
|
||||
<rect x="29" y="7" width="49" height="1" fill="#fd6420"/>
|
||||
<rect x="29" y="8" width="49" height="1" fill="#fc561f"/>
|
||||
<rect x="29" y="9" width="49" height="1" fill="#fc481e"/>
|
||||
<rect x="29" y="10" width="49" height="1" fill="#fc371d"/>
|
||||
<rect x="29" y="11" width="49" height="1" fill="#fc291c"/>
|
||||
<rect x="29" y="12" width="49" height="1" fill="#fc1c1c"/>
|
||||
<path d="m34 5h1v5h-1z" fill="#fff"/>
|
||||
<path d="m37 5h1v1h1v1h1v1h1v-3h1v5h-1v-1h-1v-1h-1v-1h-1v3h-1z" fill="#fff"/>
|
||||
<path d="m44 5v5h3v-1h-2v-3h2v-1h-3zm3 1v3h1v-3h-1z" fill="#fff"/>
|
||||
<path d="m50 5h1v5h-1z" fill="#fff"/>
|
||||
<path d="m53 5h3v1h-2v1h2v1h-2v1h2v1h-3z" fill="#fff"/>
|
||||
<path d="m58 5h1v4h1v-3h1v3h1v-4h1v4h-1v1h-1v-1h-1v1h-1v-1h-1z" fill="#fff"/>
|
||||
<path d="m65 5h3v1h-2v1h2v1h-2v1h2v1h-3z" fill="#fff"/>
|
||||
<path d="m70 5v5h3v-1h-2v-1h2v-1h-2v-1h2v-1h-3zm3 1v1h1v-1h-1zm0 2v1h1v-1h-1z" fill="#fff"/>
|
||||
</symbol>
|
||||
<symbol id="button-webmention" viewBox="0 0 80 15">
|
||||
<rect width="80" height="15" fill="#666"/>
|
||||
<rect x="1" y="1" width="78" height="13" fill="#fff" style="paint-order:markers fill stroke"/>
|
||||
<path d="m13 1v1h-1v1h-1v1h1 1v1h-1v2h-1v2h-1v-3h-1v-2h-1v2h-1v3h-1v-2h-1v-3h-1v-2h-1-1v2h1v3h1v3h1v3h1 1v-3h1v-2h1v2h1v3h1 1v-3h1v-3h1v-3h1 1v-1h-1v-1h-1v-1h-1z" fill="#610371"/>
|
||||
<rect x="19" y="2" width="59" height="11" fill="#850e9a"/>
|
||||
<path d="m33 5v5h3v-1h-2v-1h2v-1h-2v-1h2v-1h-3zm3 1v1h1v-1h-1zm0 2v1h1v-1h-1z" fill="#fff"/>
|
||||
<path d="m28 5h3v1h-2v1h2v1h-2v1h2v1h-3z" fill="#fff"/>
|
||||
<path d="m21 5h1v4h1v-3h1v3h1v-4h1v4h-1v1h-1v-1h-1v1h-1v-1h-1z" fill="#fff"/>
|
||||
<path d="m39 5h1v1h1v1h1v-1h1v-1h1v5h-1v-3h-1v1h-1v-1h-1v3h-1z" fill="#fff"/>
|
||||
<path d="m51 5h1v1h1v1h1v1h1v-3h1v5h-1v-1h-1v-1h-1v-1h-1v3h-1z" fill="#fff"/>
|
||||
<path d="m58 5h3v1h-1v4h-1v-4h-1" fill="#fff"/>
|
||||
<path d="m63 5h1v5h-1z" fill="#fff"/>
|
||||
<path d="m67 5v1h2v-1zm2 1v3h1v-3zm0 3h-2v1h2zm-2 0v-3h-1v3z" fill="#fff"/>
|
||||
<path d="m71 5h1v1h1v1h1v1h1v-3h1v5h-1v-1h-1v-1h-1v-1h-1v3h-1z" fill="#fff"/>
|
||||
<path d="m46 5h3v1h-2v1h2v1h-2v1h2v1h-3z" fill="#fff"/>
|
||||
</symbol>
|
||||
<symbol id="button-microformats" viewBox="0 0 80 15">
|
||||
<rect width="80" height="15" fill="#666"/>
|
||||
<rect x="1" y="1" width="78" height="13" fill="#fff"/>
|
||||
<rect x="18" y="2" width="2" height="11" fill="#5d8f17"/>
|
||||
<rect x="20" y="2" width="2" height="11" fill="#609218"/>
|
||||
<rect x="22" y="2" width="2" height="11" fill="#639519"/>
|
||||
<rect x="24" y="2" width="2" height="11" fill="#66981a"/>
|
||||
<rect x="26" y="2" width="2" height="11" fill="#699b1b"/>
|
||||
<rect x="28" y="2" width="2" height="11" fill="#6c9e1b"/>
|
||||
<rect x="30" y="2" width="2" height="11" fill="#6fa11c"/>
|
||||
<rect x="32" y="2" width="2" height="11" fill="#72a51d"/>
|
||||
<rect x="34" y="2" width="2" height="11" fill="#76a81e"/>
|
||||
<rect x="36" y="2" width="2" height="11" fill="#78aa1f"/>
|
||||
<rect x="38" y="2" width="2" height="11" fill="#7cae20"/>
|
||||
<rect x="40" y="2" width="2" height="11" fill="#7eb120"/>
|
||||
<rect x="42" y="2" width="2" height="11" fill="#82b421"/>
|
||||
<rect x="44" y="2" width="2" height="11" fill="#85b722"/>
|
||||
<rect x="46" y="2" width="2" height="11" fill="#88ba23"/>
|
||||
<rect x="48" y="2" width="2" height="11" fill="#8bbd24"/>
|
||||
<rect x="50" y="2" width="2" height="11" fill="#8ec125"/>
|
||||
<rect x="52" y="2" width="2" height="11" fill="#91c325"/>
|
||||
<rect x="54" y="2" width="2" height="11" fill="#94c626"/>
|
||||
<rect x="56" y="2" width="2" height="11" fill="#97ca27"/>
|
||||
<rect x="58" y="2" width="2" height="11" fill="#9acd28"/>
|
||||
<rect x="60" y="2" width="2" height="11" fill="#9dd029"/>
|
||||
<rect x="62" y="2" width="2" height="11" fill="#a0d32a"/>
|
||||
<rect x="64" y="2" width="2" height="11" fill="#a4d62b"/>
|
||||
<rect x="66" y="2" width="2" height="11" fill="#a6d92b"/>
|
||||
<rect x="68" y="2" width="2" height="11" fill="#a8db2c"/>
|
||||
<rect x="70" y="2" width="2" height="11" fill="#acdf2d"/>
|
||||
<rect x="72" y="2" width="2" height="11" fill="#b0e32e"/>
|
||||
<rect x="74" y="2" width="2" height="11" fill="#b3e62f"/>
|
||||
<rect x="76" y="2" width="2" height="11" fill="#b6e92f"/>
|
||||
<polygon points="4 4 6 4 6 9 7 9 7 10 12 10 12 12 11 12 11 13 4 13 4 12 3 12 3 5 4 5" fill="#5c8d17"/>
|
||||
<polygon points="7 3 9 3 9 6 10 6 10 7 13 7 13 9 8 9 8 8 7 8" fill="#8dc024"/>
|
||||
<polygon points="10 2 13 2 13 3 14 3 14 6 11 6 11 5 10 5" fill="#a5d82b"/>
|
||||
<path d="m20 5h1v1h1v1h1v-1h1v-1h1v5h-1v-3h-1v1h-1v-1h-1v3h-1z" fill="#fff"/>
|
||||
<path d="m26 5h1v5h-1z" fill="#fff"/>
|
||||
<path d="m29 5h2v1h1v1h-1v-1h-2v3h2v-1h1v1h-1v1h-2v-1h-1v-3h1z" fill="#fff"/>
|
||||
<path d="m33 5v5h1v-2h1v1h1v-2h-2v-1h2v-1h-3zm3 1v1h1v-1h-1zm0 3v1h1v-1h-1z" fill="#fff"/>
|
||||
<path d="m39 5v1h2v-1h-2zm2 1v1 1 1h1v-1-1-1h-1zm0 3h-2v1h2v-1zm-2 0v-3h-1v3h1z" fill="#fff"/>
|
||||
<path d="m43 5h3v1h-2v1h2v1h-2v2h-1z" fill="#fff"/>
|
||||
<path d="m48 5v1h2v-1h-2zm2 1v1 1 1h1v-1-1-1h-1zm0 3h-2v1h2v-1zm-2 0v-3h-1v3h1z" fill="#fff"/>
|
||||
<path d="m52 5v5h1v-2h1v1h1v-2h-2v-1h2v-1h-3zm3 1v1h1v-1h-1zm0 3v1h1v-1h-1z" fill="#fff"/>
|
||||
<path d="m57 5h1v1h1v1h1v-1h1v-1h1v5h-1v-3h-1v1h-1v-1h-1v3h-1z" fill="#fff"/>
|
||||
<path d="m64 5v1h2v-1h-2zm2 1v1h-2v-1h-1v4h1v-2h2v2h1v-4h-1z" fill="#fff"/>
|
||||
<path d="m68 5h3v1h-1v4h-1v-4h-1" fill="#fff"/>
|
||||
<path d="m73 5h3v1h-3v1h2v1h1v1h-1v1h-3v-1h3v-1h-2v-1h-1v-1h1" fill="#fff"/>
|
||||
</symbol>
|
||||
<symbol id="button-cc" viewBox="0 0 80 15">
|
||||
<rect y="0" width="80" height="15" fill="#000"/>
|
||||
<rect x="1" y="1" width="78" height="13" fill="#fff"/>
|
||||
<rect x="2" y="2" width="76" height="11" fill="#000"/>
|
||||
<path d="m42 5h1v1h1v1h1v-1h1v-1h1v5h-1v-3h-1v1h-1v-1h-1v3h-1z" fill="#fff"/>
|
||||
<path d="m31 5h2v1h1v1h-1v-1h-2v3h2v-1h1v1h-1v1h-2v-1h-1v-3h1z" fill="#fff"/>
|
||||
<path d="m37 5v1h2v-1zm2 1v3h1v-3zm0 3h-2v1h2zm-2 0v-3h-1v3z" fill="#fff"/>
|
||||
<path d="m57 5v1h2v-1zm2 1v3h1v-3zm0 3h-2v1h2zm-2 0v-3h-1v3z" fill="#fff"/>
|
||||
<path d="m49 5h1v1h1v1h1v-1h1v-1h1v5h-1v-3h-1v1h-1v-1h-1v3h-1z" fill="#fff"/>
|
||||
<path d="m70 5h3v1h-3v1h2v1h1v1h-1v1h-3v-1h3v-1h-2v-1h-1v-1h1" fill="#fff"/>
|
||||
<path d="m62 5h1v1h1v1h1v1h1v-3h1v5h-1v-1h-1v-1h-1v-1h-1v3h-1z" fill="#fff"/>
|
||||
<path d="m2 2v11h19.891a8.5136 8.5 0 0 0 2.1088-5.5898 8.5136 8.5 0 0 0-1.9563-5.4102h-13.119z" fill="#aaa"/>
|
||||
<path d="m6.0195 2a8.5 8.5 0 0 0-2.0195 5.5 8.5 8.5 0 0 0 2.0312 5.5h12.949a8.5 8.5 0 0 0 2.0195-5.5 8.5 8.5 0 0 0-2.0312-5.5z" fill="#000"/>
|
||||
<circle cx="12.5" cy="7.5" r="6.5" fill="#fff"/>
|
||||
<path d="m9 5h2v1h1v1h-1v-1h-2v3h2v-1h1v1h-1v1h-2v-1h-1v-3h1z" fill="#000"/>
|
||||
<path d="m14 5h2v1h1v1h-1v-1h-2v3h2v-1h1v1h-1v1h-2v-1h-1v-3h1z" fill="#000"/>
|
||||
</symbol>
|
||||
</svg>
|
||||
|
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 21 KiB |
Loading…
Reference in a new issue