Add webdav upload script and docs

This commit is contained in:
MassiveBox 2025-03-26 23:13:08 +01:00
parent d6c414f887
commit bf3e635a1c
Signed by: massivebox
GPG key ID: 9B74D3A59181947D
7 changed files with 426 additions and 36 deletions

6
.gitignore vendored
View file

@ -35,5 +35,7 @@ pnpm-debug.log*
!.yarn/versions !.yarn/versions
.pnp.* .pnp.*
# blog # blog, meta
src/content/blog src/content/blog/*
Matomo.astro
src/pages/pages/*

View file

@ -27,6 +27,7 @@ You can use Joplin to write and manageyour blog posts, instead of just placing t
2. Start the Web Clipper Service: Tools > Options > Web Clipper > Start Web Clipper Service 2. Start the Web Clipper Service: Tools > Options > Web Clipper > Start Web Clipper Service
3. Run `npm run joplin` 3. Run `npm run joplin`
4. Allow the request for an API token on the Joplin app 4. Allow the request for an API token on the Joplin app
- You can also place the Joplin token in an `.env` file in the format `JOPLIN_KEY=your_token`.
The script will look for a notebook named `Blog`. It will then download all notes from that notebook, alongside their The script will look for a notebook named `Blog`. It will then download all notes from that notebook, alongside their
attachments, and place them in the `src/content/blog` folder. attachments, and place them in the `src/content/blog` folder.
@ -46,6 +47,22 @@ In order, to have an ogImage (also known as article cover):
``` ```
Note the `.` (dot) instead of `:` (colon)! Note the `.` (dot) instead of `:` (colon)!
## Uploading to WebDav
I have found that a quick and easy way to deploy the website is via WebDav and compatible software on the server side, like
[this](https://github.com/mholt/caddy-webdav) plugin for Caddy.
To simplify uploading to WebDav, I have created a script, which can be run with `npm run upload`.
You have to set the following environment variables:
- `WEBDAV_ENDPOINT`: The URL of the WebDav server, e.g. `https://example.com/webdav/`
- `WEBDAV_USERNAME`: The username for the WebDav server
- `WEBDAV_PASSWORD`: The password for the WebDav server
- `WEBDAV_PATH`: The path to the folder on the server, e.g. `/public_html/` (default: `/`)
The script will upload the `./dist` folder, so make sure you run `npm run build` before the upload script.
Note that running the script will clear the remote folder before uploading the files.
## License ## License
The original [Astro Paper](https://github.com/satnaing/astro-paper) is licensed under the MIT License, Copyright © 2025 The original [Astro Paper](https://github.com/satnaing/astro-paper) is licensed under the MIT License, Copyright © 2025

299
package-lock.json generated
View file

@ -25,7 +25,8 @@
"sass": "^1.77.2", "sass": "^1.77.2",
"satori": "^0.10.11", "satori": "^0.10.11",
"tailwindcss": "^3.4.1", "tailwindcss": "^3.4.1",
"typescript": "^5.4.5" "typescript": "^5.4.5",
"webdav": "^5.8.0"
}, },
"devDependencies": { "devDependencies": {
"@astrojs/react": "^3.0.9", "@astrojs/react": "^3.0.9",
@ -40,6 +41,7 @@
"astro-eslint-parser": "^0.16.2", "astro-eslint-parser": "^0.16.2",
"commitizen": "^4.3.0", "commitizen": "^4.3.0",
"cz-conventional-changelog": "^3.3.0", "cz-conventional-changelog": "^3.3.0",
"dotenv": "^16.4.7",
"eslint": "^8.56.0", "eslint": "^8.56.0",
"eslint-plugin-astro": "^0.31.3", "eslint-plugin-astro": "^0.31.3",
"husky": "^8.0.3", "husky": "^8.0.3",
@ -739,6 +741,15 @@
"node": ">=6.9.0" "node": ">=6.9.0"
} }
}, },
"node_modules/@buttercup/fetch": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/@buttercup/fetch/-/fetch-0.2.1.tgz",
"integrity": "sha512-sCgECOx8wiqY8NN1xN22BqqKzXYIG2AicNLlakOAI4f0WgyLVUbAigMf8CZhBtJxdudTcB1gD5lciqi44jwJvg==",
"license": "MIT",
"optionalDependencies": {
"node-fetch": "^3.3.0"
}
},
"node_modules/@commitlint/config-validator": { "node_modules/@commitlint/config-validator": {
"version": "17.6.7", "version": "17.6.7",
"resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-17.6.7.tgz", "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-17.6.7.tgz",
@ -4236,6 +4247,12 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/byte-length": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/byte-length/-/byte-length-1.0.2.tgz",
"integrity": "sha512-ovBpjmsgd/teRmgcPh23d4gJvxDoXtAzEL9xTfMU8Yc2kqCDb7L9jAG0XHl1nzuGl+h3ebCIF1i62UFyA9V/2Q==",
"license": "MIT"
},
"node_modules/cachedir": { "node_modules/cachedir": {
"version": "2.3.0", "version": "2.3.0",
"resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.3.0.tgz", "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.3.0.tgz",
@ -4365,6 +4382,15 @@
"integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
"dev": true "dev": true
}, },
"node_modules/charenc": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz",
"integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==",
"license": "BSD-3-Clause",
"engines": {
"node": "*"
}
},
"node_modules/cheerio": { "node_modules/cheerio": {
"version": "1.0.0-rc.12", "version": "1.0.0-rc.12",
"resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz",
@ -4987,6 +5013,15 @@
"node": ">= 8" "node": ">= 8"
} }
}, },
"node_modules/crypt": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz",
"integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==",
"license": "BSD-3-Clause",
"engines": {
"node": "*"
}
},
"node_modules/css-background-parser": { "node_modules/css-background-parser": {
"version": "0.1.0", "version": "0.1.0",
"resolved": "https://registry.npmjs.org/css-background-parser/-/css-background-parser-0.1.0.tgz", "resolved": "https://registry.npmjs.org/css-background-parser/-/css-background-parser-0.1.0.tgz",
@ -5120,6 +5155,15 @@
"@commitlint/load": ">6.1.1" "@commitlint/load": ">6.1.1"
} }
}, },
"node_modules/data-uri-to-buffer": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz",
"integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==",
"license": "MIT",
"engines": {
"node": ">= 12"
}
},
"node_modules/debug": { "node_modules/debug": {
"version": "4.3.4", "version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@ -5470,6 +5514,19 @@
"tslib": "^2.0.3" "tslib": "^2.0.3"
} }
}, },
"node_modules/dotenv": {
"version": "16.4.7",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.7.tgz",
"integrity": "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==",
"dev": true,
"license": "BSD-2-Clause",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://dotenvx.com"
}
},
"node_modules/dset": { "node_modules/dset": {
"version": "3.1.3", "version": "3.1.3",
"resolved": "https://registry.npmjs.org/dset/-/dset-3.1.3.tgz", "resolved": "https://registry.npmjs.org/dset/-/dset-3.1.3.tgz",
@ -6154,21 +6211,18 @@
"dev": true "dev": true
}, },
"node_modules/fast-xml-parser": { "node_modules/fast-xml-parser": {
"version": "4.2.7", "version": "4.5.3",
"resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.2.7.tgz", "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.5.3.tgz",
"integrity": "sha512-J8r6BriSLO1uj2miOk1NW0YVm8AGOOu3Si2HQp/cSmo6EA4m3fcwu2WKjJ4RK9wMLBtg69y1kS8baDiQBR41Ig==", "integrity": "sha512-RKihhV+SHsIUGXObeVy9AXiBbFwkVk7Syp8XgwN5U3JV416+Gwp/GO9i0JYKmikykgz/UHRrrV4ROuZEo/T0ig==",
"funding": [ "funding": [
{
"type": "paypal",
"url": "https://paypal.me/naturalintelligence"
},
{ {
"type": "github", "type": "github",
"url": "https://github.com/sponsors/NaturalIntelligence" "url": "https://github.com/sponsors/NaturalIntelligence"
} }
], ],
"license": "MIT",
"dependencies": { "dependencies": {
"strnum": "^1.0.5" "strnum": "^1.1.1"
}, },
"bin": { "bin": {
"fxparser": "src/cli/cli.js" "fxparser": "src/cli/cli.js"
@ -6190,6 +6244,29 @@
"pend": "~1.2.0" "pend": "~1.2.0"
} }
}, },
"node_modules/fetch-blob": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz",
"integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/jimmywarting"
},
{
"type": "paypal",
"url": "https://paypal.me/jimmywarting"
}
],
"license": "MIT",
"dependencies": {
"node-domexception": "^1.0.0",
"web-streams-polyfill": "^3.0.3"
},
"engines": {
"node": "^12.20 || >= 14.13"
}
},
"node_modules/fflate": { "node_modules/fflate": {
"version": "0.7.4", "version": "0.7.4",
"resolved": "https://registry.npmjs.org/fflate/-/fflate-0.7.4.tgz", "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.7.4.tgz",
@ -6333,6 +6410,18 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/formdata-polyfill": {
"version": "4.0.10",
"resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz",
"integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==",
"license": "MIT",
"dependencies": {
"fetch-blob": "^3.1.2"
},
"engines": {
"node": ">=12.20.0"
}
},
"node_modules/fraction.js": { "node_modules/fraction.js": {
"version": "4.3.6", "version": "4.3.6",
"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.6.tgz", "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.6.tgz",
@ -6852,6 +6941,12 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/hot-patcher": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/hot-patcher/-/hot-patcher-2.0.1.tgz",
"integrity": "sha512-ECg1JFG0YzehicQaogenlcs2qg6WsXQsxtnbr1i696u5tLUjtJdQAh0u2g0Q5YV45f263Ta1GnUJsc8WIfJf4Q==",
"license": "MIT"
},
"node_modules/html-escaper": { "node_modules/html-escaper": {
"version": "3.0.3", "version": "3.0.3",
"resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-3.0.3.tgz", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-3.0.3.tgz",
@ -7654,6 +7749,12 @@
"resolved": "https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz", "resolved": "https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz",
"integrity": "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==" "integrity": "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ=="
}, },
"node_modules/layerr": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/layerr/-/layerr-3.0.0.tgz",
"integrity": "sha512-tv754Ki2dXpPVApOrjTyRo4/QegVb9eVFq4mjqp4+NM5NaX7syQvN5BBNfV/ZpAHCEHV24XdUVrBAoka4jt3pA==",
"license": "MIT"
},
"node_modules/levn": { "node_modules/levn": {
"version": "0.4.1", "version": "0.4.1",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
@ -8433,6 +8534,23 @@
"node": ">= 18" "node": ">= 18"
} }
}, },
"node_modules/md5": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz",
"integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==",
"license": "BSD-3-Clause",
"dependencies": {
"charenc": "0.0.2",
"crypt": "0.0.2",
"is-buffer": "~1.1.6"
}
},
"node_modules/md5/node_modules/is-buffer": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
"integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
"license": "MIT"
},
"node_modules/mdast-util-definitions": { "node_modules/mdast-util-definitions": {
"version": "6.0.0", "version": "6.0.0",
"resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-6.0.0.tgz", "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-6.0.0.tgz",
@ -9505,6 +9623,12 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/nested-property": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/nested-property/-/nested-property-4.0.0.tgz",
"integrity": "sha512-yFehXNWRs4cM0+dz7QxCd06hTbWbSkV0ISsqBfkntU6TOY4Qm3Q88fRRLOddkGh2Qq6dZvnKVAahfhjcUvLnyA==",
"license": "MIT"
},
"node_modules/nlcst-to-string": { "node_modules/nlcst-to-string": {
"version": "3.1.1", "version": "3.1.1",
"resolved": "https://registry.npmjs.org/nlcst-to-string/-/nlcst-to-string-3.1.1.tgz", "resolved": "https://registry.npmjs.org/nlcst-to-string/-/nlcst-to-string-3.1.1.tgz",
@ -9545,6 +9669,43 @@
"integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==", "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==",
"optional": true "optional": true
}, },
"node_modules/node-domexception": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
"integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/jimmywarting"
},
{
"type": "github",
"url": "https://paypal.me/jimmywarting"
}
],
"license": "MIT",
"engines": {
"node": ">=10.5.0"
}
},
"node_modules/node-fetch": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz",
"integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==",
"license": "MIT",
"dependencies": {
"data-uri-to-buffer": "^4.0.0",
"fetch-blob": "^3.1.4",
"formdata-polyfill": "^4.0.10"
},
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/node-fetch"
}
},
"node_modules/node-releases": { "node_modules/node-releases": {
"version": "2.0.14", "version": "2.0.14",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz",
@ -10050,6 +10211,12 @@
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
}, },
"node_modules/path-posix": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/path-posix/-/path-posix-1.0.0.tgz",
"integrity": "sha512-1gJ0WpNIiYcQydgg3Ed8KzvIqTsDpNwq+cjBCssvBtuTWjEqY1AW+i+OepiEMqDCzyro9B2sLAe4RBPajMYFiA==",
"license": "ISC"
},
"node_modules/path-to-regexp": { "node_modules/path-to-regexp": {
"version": "6.2.1", "version": "6.2.1",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.1.tgz", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.1.tgz",
@ -10690,6 +10857,12 @@
"node": ">=6" "node": ">=6"
} }
}, },
"node_modules/querystringify": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
"integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==",
"license": "MIT"
},
"node_modules/queue-microtask": { "node_modules/queue-microtask": {
"version": "1.2.3", "version": "1.2.3",
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
@ -11033,6 +11206,12 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/requires-port": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
"integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
"license": "MIT"
},
"node_modules/resolve": { "node_modules/resolve": {
"version": "1.22.4", "version": "1.22.4",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.4.tgz", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.4.tgz",
@ -12265,9 +12444,16 @@
} }
}, },
"node_modules/strnum": { "node_modules/strnum": {
"version": "1.0.5", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.1.2.tgz",
"integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==" "integrity": "sha512-vrN+B7DBIoTTZjnPNewwhx6cBA/H+IS7rfW68n7XxC1y7uoiGQBxaKzqucGUgavX15dJgiGztLJ8vxuEzwqBdA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/NaturalIntelligence"
}
],
"license": "MIT"
}, },
"node_modules/strtok3": { "node_modules/strtok3": {
"version": "7.0.0", "version": "7.0.0",
@ -13175,6 +13361,25 @@
"punycode": "^2.1.0" "punycode": "^2.1.0"
} }
}, },
"node_modules/url-join": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/url-join/-/url-join-5.0.0.tgz",
"integrity": "sha512-n2huDr9h9yzd6exQVnH/jU5mr+Pfx08LRXXZhkLLetAMESRj+anQsTAh940iMrIetKAmry9coFuZQ2jY8/p3WA==",
"license": "MIT",
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
}
},
"node_modules/url-parse": {
"version": "1.5.10",
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz",
"integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==",
"license": "MIT",
"dependencies": {
"querystringify": "^2.1.1",
"requires-port": "^1.0.0"
}
},
"node_modules/util-deprecate": { "node_modules/util-deprecate": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
@ -13897,6 +14102,76 @@
"url": "https://github.com/sponsors/wooorm" "url": "https://github.com/sponsors/wooorm"
} }
}, },
"node_modules/web-streams-polyfill": {
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz",
"integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==",
"license": "MIT",
"engines": {
"node": ">= 8"
}
},
"node_modules/webdav": {
"version": "5.8.0",
"resolved": "https://registry.npmjs.org/webdav/-/webdav-5.8.0.tgz",
"integrity": "sha512-iuFG7NamJ41Oshg4930iQgfIpRrUiatPWIekeznYgEf2EOraTRcDPTjy7gIOMtkdpKTaqPk1E68NO5PAGtJahA==",
"license": "MIT",
"dependencies": {
"@buttercup/fetch": "^0.2.1",
"base-64": "^1.0.0",
"byte-length": "^1.0.2",
"entities": "^6.0.0",
"fast-xml-parser": "^4.5.1",
"hot-patcher": "^2.0.1",
"layerr": "^3.0.0",
"md5": "^2.3.0",
"minimatch": "^9.0.5",
"nested-property": "^4.0.0",
"node-fetch": "^3.3.2",
"path-posix": "^1.0.0",
"url-join": "^5.0.0",
"url-parse": "^1.5.10"
},
"engines": {
"node": ">=14"
}
},
"node_modules/webdav/node_modules/brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0"
}
},
"node_modules/webdav/node_modules/entities": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-6.0.0.tgz",
"integrity": "sha512-aKstq2TDOndCn4diEyp9Uq/Flu2i1GlLkc6XIDQSDMuaFE3OPW5OphLCyQ5SpSJZTb4reN+kTcYru5yIfXoRPw==",
"license": "BSD-2-Clause",
"engines": {
"node": ">=0.12"
},
"funding": {
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
"node_modules/webdav/node_modules/minimatch": {
"version": "9.0.5",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
"license": "ISC",
"dependencies": {
"brace-expansion": "^2.0.1"
},
"engines": {
"node": ">=16 || 14 >=14.17"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/whatwg-encoding": { "node_modules/whatwg-encoding": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz",

View file

@ -13,7 +13,8 @@
"cz": "cz", "cz": "cz",
"prepare": "husky install", "prepare": "husky install",
"lint": "eslint .", "lint": "eslint .",
"joplin": "node src/utils/joplin.js" "joplin": "node src/utils/joplin.mjs",
"upload": "node src/utils/upload.mjs"
}, },
"dependencies": { "dependencies": {
"@astrojs/check": "^0.7.0", "@astrojs/check": "^0.7.0",
@ -33,7 +34,8 @@
"sass": "^1.77.2", "sass": "^1.77.2",
"satori": "^0.10.11", "satori": "^0.10.11",
"tailwindcss": "^3.4.1", "tailwindcss": "^3.4.1",
"typescript": "^5.4.5" "typescript": "^5.4.5",
"webdav": "^5.8.0"
}, },
"devDependencies": { "devDependencies": {
"@astrojs/react": "^3.0.9", "@astrojs/react": "^3.0.9",
@ -48,6 +50,7 @@
"astro-eslint-parser": "^0.16.2", "astro-eslint-parser": "^0.16.2",
"commitizen": "^4.3.0", "commitizen": "^4.3.0",
"cz-conventional-changelog": "^3.3.0", "cz-conventional-changelog": "^3.3.0",
"dotenv": "^16.4.7",
"eslint": "^8.56.0", "eslint": "^8.56.0",
"eslint-plugin-astro": "^0.31.3", "eslint-plugin-astro": "^0.31.3",
"husky": "^8.0.3", "husky": "^8.0.3",

View file

@ -1,12 +1 @@
<script is:inline> <script defer src="https://stats.massive.box/p.js" data-website-id="30344937-ffdf-4a6a-ba52-dc60a23aa4f2"></script>
var _paq = _paq || [];
_paq.push(["trackPageView"]), _paq.push(["enableLinkTracking"]),
function() {
_paq.push(["setTrackerUrl", "//stats.massive.box/sjprfvo.php"]);
_paq.push(["setSiteId", "1"]);
_paq.push(['disableAlwaysUseSendBeacon', 'true']);
var a = document, r = a.createElement("script"), s = a.getElementsByTagName("script")[0];
r.async = !0, r.defer = !0, r.src = "//stats.massive.box/fauqtkg.php", s.parentNode.insertBefore(r, s)
}();
</script>
<noscript><img src="//stats.massive.box/sjprfvo.php?dzp=1&opl=1" /></noscript>

View file

@ -1,6 +1,12 @@
const http = require('node:http'); import dotenv from 'dotenv';
const fs = require('fs'); dotenv.config();
const path = require('path');
import http from 'node:http';
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
async function fetch(url, method = "GET") { async function fetch(url, method = "GET") {
return new Promise((resolve) => { return new Promise((resolve) => {
@ -172,16 +178,18 @@ async function clearBlogFolder() {
} }
async function main() { async function main() {
console.log("Finding JoplinClipperServer port..."); console.log("Finding JoplinClipperServer port...");
let host = "http://localhost:" + await findPort(); let host = "http://localhost:" + await findPort();
let apiToken = await authenticate(host);
//let apiToken = ""; let apiToken = process.env.JOPLIN_KEY;
if (!apiToken) {
apiToken = await authenticate(host);
}
let notes = await getNotebookNotes(apiToken, host); let notes = await getNotebookNotes(apiToken, host);
await clearBlogFolder(); await clearBlogFolder();
for(let noteId of notes) { for(let noteId of notes) {
let noteBody = await getNoteBody(apiToken, host, noteId); let noteBody = await getNoteBody(apiToken, host, noteId);
let slug = await getNoteSlug(noteBody); let slug = await getNoteSlug(noteBody);

96
src/utils/upload.mjs Normal file
View file

@ -0,0 +1,96 @@
import dotenv from 'dotenv';
dotenv.config();
import { createClient } from 'webdav';
import fs from 'fs';
import path from 'path';
const client = createClient(
process.env.WEBDAV_ENDPOINT,
{
username: process.env.WEBDAV_USERNAME,
password: process.env.WEBDAV_PASSWORD,
maxBodyLength: Infinity,
maxContentLength: Infinity,
headers: {
Accept: "*/*",
Connection: "keep-alive"
}
}
);
async function createDirectoryIfNotExist(remotePath) {
try {
const exists = await client.exists(remotePath);
if (!exists) {
await client.createDirectory(remotePath);
}
} catch (error) {
if (error.status !== 409 && error.status !== 405) {
throw error;
}
}
}
async function uploadDirectory(localPath, remoteBasePath) {
try {
const items = fs.readdirSync(localPath, { withFileTypes: true });
for (const item of items) {
const localItemPath = path.join(localPath, item.name);
const remoteItemPath = path.posix.join(remoteBasePath, item.name);
if (item.isDirectory()) {
// Create directory on WebDAV server
await createDirectoryIfNotExist(remoteItemPath);
console.log(`Verified directory: ${remoteItemPath}`);
await uploadDirectory(localItemPath, remoteItemPath);
} else {
// Upload file
console.log(`Uploading file: ${remoteItemPath}`);
const content = fs.readFileSync(localItemPath);
await client.putFileContents(remoteItemPath, content);
}
}
} catch (error) {
console.error(`Error processing ${localPath}:`, error.message);
throw error;
}
}
async function clearFolder(remotePath) {
try {
const items = await client.getDirectoryContents(remotePath);
for (const item of items) {
if (item.basename !== '..') {
const itemPath = path.posix.join(remotePath, item.basename);
await client.deleteFile(itemPath);
}
}
} catch (error) {
console.error('Error clearing root folder:', error.message);
throw error;
}
}
// Usage example
async function main() {
const localDir = './dist';
let remoteDir = process.env.WEBDAV_REMOTE_DIR;
if(remoteDir === undefined) {
remoteDir = '/';
}
try {
// Clear root folder
await clearFolder(remoteDir);
// Upload new content
await uploadDirectory(localDir, remoteDir);
console.log('Directory upload complete');
} catch (error) {
console.error('Upload failed:', error.message);
}
}
main();