Compare commits
15 commits
Author | SHA1 | Date | |
---|---|---|---|
Hugh Rundle | 1ac9d03231 | ||
Hugh Rundle | 74f2e0756f | ||
Hugh Rundle | a6cdf52f7d | ||
Hugh Rundle | fc2b43a659 | ||
Hugh Rundle | d40b38adc3 | ||
Hugh Rundle | 87e2a39a56 | ||
Hugh Rundle | e5d7031705 | ||
Hugh Rundle | cb932edacf | ||
Hugh Rundle | c2bb66b514 | ||
Hugh Rundle | 71b92d5900 | ||
Hugh Rundle | d92a35a027 | ||
Hugh Rundle | a035b43d9a | ||
Hugh Rundle | c066383e8a | ||
Hugh Rundle | 3f1bd0aded | ||
Hugh Rundle | f946e8a800 |
162
Cargo.lock
generated
162
Cargo.lock
generated
|
@ -11,6 +11,12 @@ dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "android-tzdata"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "android_system_properties"
|
name = "android_system_properties"
|
||||||
version = "0.1.5"
|
version = "0.1.5"
|
||||||
|
@ -75,17 +81,16 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "chrono"
|
name = "chrono"
|
||||||
version = "0.4.23"
|
version = "0.4.38"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f"
|
checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"android-tzdata",
|
||||||
"iana-time-zone",
|
"iana-time-zone",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"num-integer",
|
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"time",
|
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
"winapi",
|
"windows-targets",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -174,6 +179,12 @@ dependencies = [
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "equivalent"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "expanduser"
|
name = "expanduser"
|
||||||
version = "1.2.2"
|
version = "1.2.2"
|
||||||
|
@ -193,14 +204,14 @@ checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"libc",
|
"libc",
|
||||||
"wasi 0.9.0+wasi-snapshot-preview1",
|
"wasi",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "hashbrown"
|
||||||
version = "0.12.3"
|
version = "0.14.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iana-time-zone"
|
name = "iana-time-zone"
|
||||||
|
@ -228,11 +239,11 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "indexmap"
|
name = "indexmap"
|
||||||
version = "1.9.2"
|
version = "2.2.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399"
|
checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"equivalent",
|
||||||
"hashbrown",
|
"hashbrown",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -281,25 +292,6 @@ version = "2.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "nom8"
|
|
||||||
version = "0.2.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ae01545c9c7fc4486ab7debaf2aad7003ac19431791868fb2e8066df97fad2f8"
|
|
||||||
dependencies = [
|
|
||||||
"memchr",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "num-integer"
|
|
||||||
version = "0.1.45"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
|
|
||||||
dependencies = [
|
|
||||||
"autocfg",
|
|
||||||
"num-traits",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-traits"
|
name = "num-traits"
|
||||||
version = "0.2.15"
|
version = "0.2.15"
|
||||||
|
@ -417,16 +409,16 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_spanned"
|
name = "serde_spanned"
|
||||||
version = "0.6.1"
|
version = "0.6.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0efd8caf556a6cebd3b285caf480045fcc1ac04f6bd786b09a6f11af30c4fcf4"
|
checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "soyuz-cli"
|
name = "soyuz-cli"
|
||||||
version = "1.0.0"
|
version = "1.0.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"expanduser",
|
"expanduser",
|
||||||
|
@ -475,22 +467,11 @@ dependencies = [
|
||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "time"
|
|
||||||
version = "0.1.45"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
"wasi 0.10.0+wasi-snapshot-preview1",
|
|
||||||
"winapi",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml"
|
name = "toml"
|
||||||
version = "0.7.2"
|
version = "0.7.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f7afcae9e3f0fe2c370fd4657108972cbb2fa9db1b9f84849cefd80741b01cb6"
|
checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
"serde_spanned",
|
"serde_spanned",
|
||||||
|
@ -500,24 +481,24 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml_datetime"
|
name = "toml_datetime"
|
||||||
version = "0.6.1"
|
version = "0.6.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3ab8ed2edee10b50132aed5f331333428b011c99402b5a534154ed15746f9622"
|
checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml_edit"
|
name = "toml_edit"
|
||||||
version = "0.19.3"
|
version = "0.19.15"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5e6a7712b49e1775fb9a7b998de6635b299237f48b404dde71704f2e0e7f37e5"
|
checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"nom8",
|
|
||||||
"serde",
|
"serde",
|
||||||
"serde_spanned",
|
"serde_spanned",
|
||||||
"toml_datetime",
|
"toml_datetime",
|
||||||
|
"winnow",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -538,12 +519,6 @@ version = "0.9.0+wasi-snapshot-preview1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
|
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "wasi"
|
|
||||||
version = "0.10.0+wasi-snapshot-preview1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen"
|
name = "wasm-bindgen"
|
||||||
version = "0.2.84"
|
version = "0.2.84"
|
||||||
|
@ -628,3 +603,76 @@ name = "winapi-x86_64-pc-windows-gnu"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-targets"
|
||||||
|
version = "0.52.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb"
|
||||||
|
dependencies = [
|
||||||
|
"windows_aarch64_gnullvm",
|
||||||
|
"windows_aarch64_msvc",
|
||||||
|
"windows_i686_gnu",
|
||||||
|
"windows_i686_gnullvm",
|
||||||
|
"windows_i686_msvc",
|
||||||
|
"windows_x86_64_gnu",
|
||||||
|
"windows_x86_64_gnullvm",
|
||||||
|
"windows_x86_64_msvc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_gnullvm"
|
||||||
|
version = "0.52.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_msvc"
|
||||||
|
version = "0.52.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_gnu"
|
||||||
|
version = "0.52.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_gnullvm"
|
||||||
|
version = "0.52.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_msvc"
|
||||||
|
version = "0.52.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnu"
|
||||||
|
version = "0.52.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnullvm"
|
||||||
|
version = "0.52.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_msvc"
|
||||||
|
version = "0.52.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winnow"
|
||||||
|
version = "0.5.40"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
12
Cargo.toml
12
Cargo.toml
|
@ -1,13 +1,13 @@
|
||||||
[package]
|
[package]
|
||||||
name = "soyuz-cli"
|
name = "soyuz-cli"
|
||||||
version = "1.0.0"
|
version = "1.0.2"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
chrono = "0.4.23"
|
chrono = "~0.4.38"
|
||||||
expanduser = "1.2.2"
|
expanduser = "~1.2.2"
|
||||||
regex = "1.7.1"
|
regex = "~1.7.1"
|
||||||
serde = { version = "1.0.152", features = ["derive"] }
|
serde = { version = "~1.0.152", features = ["derive"] }
|
||||||
toml = { version = "0.7.2", features = ["parse"] }
|
toml = { version = "~0.7.3", features = ["parse"] }
|
||||||
|
|
34
README.md
34
README.md
|
@ -1,23 +1,47 @@
|
||||||
# soyuz-cli
|
# soyuz-cli
|
||||||
|
|
||||||
This is the sister application to `soyuz-web`.
|
This is the sister application to [`soyuz-web`](https://github.com/hughrun/soyuz-web).
|
||||||
|
|
||||||
`soyuz-cli` can be used alone or on combination with `soyuz-web` to publish and syncronise a gemlog between your local machine and your gemini server.
|
`soyuz-cli` can be used alone or on combination with `soyuz-web` to publish and syncronise a gemlog between your local machine and your gemini server.
|
||||||
|
|
||||||
It is essentially a wrapper around `rsync`. Additionally it will maintain an archive of posts for each year, and the latest 5 posts on your gemlog homepage.
|
It is mostly a wrapper around `rsync`. Additionally it will maintain an archive of posts for each year, and the latest 5 posts on your gemlog homepage.
|
||||||
|
|
||||||
## Assumptions
|
## Assumptions
|
||||||
|
|
||||||
1. You are using MacOS locally and a unix-like OS on the server (it probably works on n*x locally but I haven't tested it)
|
1. You are using MacOS locally and a unix-like OS on the server (it probably works on n*x locally but I haven't tested it)
|
||||||
2. If you have text _under_ the list of latest posts on your homepage, you have at least 5 posts listed already (I could have put in some logic to deal with this but I am lazy)
|
2. If you have text _under_ the list of latest posts on your homepage, you have at least 5 posts listed already (I could have put in some logic to deal with this but I am lazy)
|
||||||
3. You have `rsync` installed on your local machine
|
3. You have `rsync` and `ssh` installed on your local machine
|
||||||
4. You have read and write permission for your gemlog files on the server, with the same username as your local machine (otherwise file permissions get weird)
|
4. You have read and write permission for your gemlog files on the server, with the same username as your local machine (otherwise file permissions get weird)
|
||||||
5. You have permission to install files at `/usr/local/bin` on your local machine
|
5. You have permission to install files at `/usr/local/bin` on your local machine
|
||||||
|
6. You publish posts one at a time, so each post will be published prior to the next one being drafted
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
The easiest way to install `soyuz-cli` is using the install script:
|
The easiest way to install `soyuz-cli` is using the install script. Note that these scripts **will overwrite any previously installed version**.
|
||||||
|
|
||||||
|
If you are using a recent version of MacOS, run this command in `Terminal`:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
curl https://hugh.run/install-soyuz | bash
|
curl -kL https://hugh.run/install-soyuz | bash
|
||||||
```
|
```
|
||||||
|
|
||||||
|
To install for MacOS Mojave, run this command instead:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl -kL https://hugh.run/install-soyuz-mojave | bash
|
||||||
|
```
|
||||||
|
|
||||||
|
Alternatively, you can build from source if you have rust and cargo installed.
|
||||||
|
|
||||||
|
## Set up
|
||||||
|
|
||||||
|
Once installed, run `soyuz settings` to create a new settings file. The settings file has the following values:
|
||||||
|
|
||||||
|
* `local_dir` - the directory on your local machine where your Gemini files are saved
|
||||||
|
* `remote_dir` - the SSH remote directory path to your files on the server. This includes the server name or ip address, so should look something like `gemini-server:/srv/gemini/example.com` or `username@123.456.789:/srv/gemini/example.com`.
|
||||||
|
* `editor` - the command to open the text editor you want to use. Defaults to `nano`.
|
||||||
|
* `index_heading` - the heading text above the latest posts listing on your homepage. If unsure, leave this on the default.
|
||||||
|
|
||||||
|
## Commands
|
||||||
|
|
||||||
|
Run `soyuz help` for a list of commands and what they do.
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
# This script installs soyuz-cli
|
# This script installs soyuz-cli
|
||||||
# Download latest binary and save in /usr/local/bin
|
|
||||||
curl -L https://github.com/hughrun/soyuz-cli/releases/download/latest/MacOS > /usr/local/bin/soyuz
|
# Download latest binary
|
||||||
|
wget -q --show-progress https://github.com/hughrun/soyuz-cli/releases/latest/download/MacOS
|
||||||
|
# mv to /usr/local/bin and rename
|
||||||
|
mv MacOS /usr/local/bin/soyuz
|
||||||
# make it executable
|
# make it executable
|
||||||
chmod +x /usr/local/bin/yawp_test
|
chmod +x /usr/local/bin/soyuz
|
||||||
|
|
||||||
cat 1>&2 << 'EOM'
|
cat 1>&2 << 'EOM'
|
||||||
|
|
||||||
|
|
123
src/main.rs
123
src/main.rs
|
@ -9,7 +9,7 @@ use std::path::PathBuf;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::process::Command;
|
use std::process::{Command, Stdio};
|
||||||
use toml;
|
use toml;
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
|
@ -59,31 +59,32 @@ fn create_or_update_homepage(string: String) -> Result<(), std::io::Error> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn help() {
|
fn help() {
|
||||||
println!("Союз (Soyuz) - v{}", option_env!("CARGO_PKG_VERSION").unwrap());
|
println!("\x1B[1;37;41mСоюз (Soyuz) - v{}\x1B[0m", option_env!("CARGO_PKG_VERSION").unwrap());
|
||||||
println!("A command line program for publishing Gemini posts.\n");
|
println!("A command line program for publishing Gemini posts\n\x1B[0m");
|
||||||
println!(" soyuz ( help | settings | write | publish | sync [ --overwrite | --delete ] )\n");
|
println!(" \x1B[1;31mhelp | settings | write | publish | sync [ up | down [ --overwrite | --delete ]]\n\x1B[0m");
|
||||||
println!(" help");
|
println!(" \x1B[1;31mhelp\x1B[0m");
|
||||||
println!(" - shows this help screen\n");
|
println!(" - shows this help screen\n");
|
||||||
println!(" settings");
|
println!(" \x1B[1;31msettings\x1B[0m");
|
||||||
println!(" - create or edit the settings file\n");
|
println!(" - create or edit the settings file\n");
|
||||||
println!(" write");
|
println!(" \x1B[1;31mwrite\x1B[0m");
|
||||||
println!(" - create or edit today's gempost using the editor specified in the settings file\n");
|
println!(" - create or edit today's gempost using the editor specified in the settings file\n");
|
||||||
println!(" publish");
|
println!(" \x1B[1;31mpublish\x1B[0m");
|
||||||
println!(" - update the homepage and year archive lists of posts, and publish to server.");
|
println!(" - update the homepage and year archive lists of posts, and publish to server");
|
||||||
println!(" Syncs new or changed files from the server before updating indexes and syncing up.\n");
|
println!(" Syncs new or changed files from the server before updating indexes and syncing up\n");
|
||||||
println!(" sync");
|
println!(" If you wish to make manual homepage changes you should use 'sync down' first\n");
|
||||||
println!(" - synchronise files between local machine and server.");
|
println!(" \x1B[1;31msync\x1B[0m");
|
||||||
|
println!(" - synchronise files between local machine and server");
|
||||||
println!(" This is a wrapper around rsync, the default being 'rsync -rtOq'");
|
println!(" This is a wrapper around rsync, the default being 'rsync -rtOq'");
|
||||||
println!(" Without arguments sync defaults to 'sync up' which is the equivalent of 'publish'\n");
|
println!(" Without arguments sync defaults to 'sync up' which is the equivalent of 'publish'\n");
|
||||||
println!(" sync up");
|
println!(" \x1B[1;31msync up\x1B[0m");
|
||||||
println!(" - syncronise new or changed files from local machine to server.\n");
|
println!(" - synchronise new or changed files from local machine to server\n");
|
||||||
println!(" sync down");
|
println!(" \x1B[1;31msync down\x1B[0m");
|
||||||
println!(" - syncronise new or changed files from server to local machine.\n");
|
println!(" - synchronise new or changed files from server to local machine\n");
|
||||||
println!(" sync (down | up) --overwrite");
|
println!(" \x1B[1;31msync (down | up) --overwrite\x1B[0m");
|
||||||
println!(" - sync, and overwrite all files at the destination regardless of last edit date.");
|
println!(" - sync, and overwrite all files at the destination regardless of last edit date");
|
||||||
println!(" Without this flag, sync will ignore files at the destination edited more recently than the source.\n");
|
println!(" Without this flag, sync will ignore files at the destination edited more recently than the source\n");
|
||||||
println!(" sync (down | up) --delete");
|
println!(" \x1B[1;31msync (down | up) --delete\x1B[0m");
|
||||||
println!(" - sync, and delete any files at the destination that do not exist at the source.\n");
|
println!(" - sync, and delete any files at the destination that do not exist at the source\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn open_file(filepath: std::path::PathBuf) {
|
fn open_file(filepath: std::path::PathBuf) {
|
||||||
|
@ -100,6 +101,7 @@ fn open_file(filepath: std::path::PathBuf) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn publish() -> Result<(), Box<dyn std::error::Error>> {
|
fn publish() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
println!("Publishing, please wait...");
|
||||||
let config = read_config()?;
|
let config = read_config()?;
|
||||||
// sync down from server (only files that are newer on the server than local)
|
// sync down from server (only files that are newer on the server than local)
|
||||||
let mut sync = Command::new("rsync")
|
let mut sync = Command::new("rsync")
|
||||||
|
@ -138,6 +140,11 @@ fn publish() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let post = fs::read_to_string(format!("{}/{}", dirpath, &filename))?;
|
let post = fs::read_to_string(format!("{}/{}", dirpath, &filename))?;
|
||||||
let post_lines: Vec<&str> = post.lines().collect();
|
let post_lines: Vec<&str> = post.lines().collect();
|
||||||
let title = post_lines[0].strip_prefix("# ");
|
let title = post_lines[0].strip_prefix("# ");
|
||||||
|
if title.is_none() {
|
||||||
|
println!("ABORTING: Your latest post does not have a title.");
|
||||||
|
println!("Use a '# Heading' on the first line.");
|
||||||
|
return Ok(())
|
||||||
|
}
|
||||||
let entry_string = format!("=> {} {} ({})", filename, sliced, title.unwrap());
|
let entry_string = format!("=> {} {} ({})", filename, sliced, title.unwrap());
|
||||||
let home_entry_string = format!("=> /{}/{} {} ({})", &year, filename, sliced, title.unwrap());
|
let home_entry_string = format!("=> /{}/{} {} ({})", &year, filename, sliced, title.unwrap());
|
||||||
if let Ok(index) = fs::read_to_string(&indexfilepath) {
|
if let Ok(index) = fs::read_to_string(&indexfilepath) {
|
||||||
|
@ -227,7 +234,7 @@ fn settings() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
fn sync(args: &Vec<String>) -> Result<(), Box<dyn std::error::Error>> {
|
fn sync(args: &Vec<String>) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let config = read_config()?;
|
let config = read_config()?;
|
||||||
let rsync_args = match args.len() {
|
let rsync_args = match args.len() {
|
||||||
2 => ["-rtOq", "--update", &config.remote_dir, &config.local_dir],
|
2 => ["-rtOq", "--update", &config.local_dir, &config.remote_dir],
|
||||||
3 | 4 => {
|
3 | 4 => {
|
||||||
match args[2].as_str() {
|
match args[2].as_str() {
|
||||||
"down" => {
|
"down" => {
|
||||||
|
@ -277,19 +284,75 @@ fn sync(args: &Vec<String>) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write() -> Result<(), Box<dyn std::error::Error>> {
|
fn write(args: &Vec<String>) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
|
||||||
let config = read_config()?;
|
let config = read_config()?;
|
||||||
let dt = Local::now();
|
let dt = Local::now();
|
||||||
let year = &dt.format("%Y").to_string();
|
let year = &dt.format("%Y").to_string();
|
||||||
let local_dir: std::path::PathBuf = expanduser(config.local_dir)?;
|
let local_dir: std::path::PathBuf = expanduser(&config.local_dir)?;
|
||||||
fs::create_dir_all(format!("{}{}", &local_dir.display(), &year))?;
|
fs::create_dir_all(format!("{}{}", &local_dir.display(), &year))?;
|
||||||
let filepath = format!("{}{}/{}.gmi", local_dir.display(), year, dt.format("%Y-%m-%d"));
|
let filepath = format!("{}{}/{}.gmi", local_dir.display(), year, dt.format("%Y-%m-%d"));
|
||||||
Ok(open_file(filepath.into()))
|
|
||||||
|
match args.len() {
|
||||||
|
2 => {
|
||||||
|
let remote_dir: std::path::PathBuf = expanduser(&config.remote_dir)?;
|
||||||
|
let spath = format!("{}", remote_dir.display());
|
||||||
|
let remote_vec = spath.split(':').collect::<Vec<_>>();
|
||||||
|
let server_name = remote_vec[0];
|
||||||
|
let server_path = remote_vec[1];
|
||||||
|
let remote_filepath = format!("{}{}/{}.gmi", server_path, year, dt.format("%Y-%m-%d"));
|
||||||
|
let cmd = format!("[[ -f {} ]] && echo 'true' || echo 'false';", &remote_filepath);
|
||||||
|
|
||||||
|
println!("Checking server for latest post...");
|
||||||
|
let check = Command::new("ssh")
|
||||||
|
.args(["-q", &server_name, &cmd])
|
||||||
|
.stdout(Stdio::piped())
|
||||||
|
.spawn()
|
||||||
|
.expect("reading from server failed");
|
||||||
|
let output = check
|
||||||
|
.wait_with_output()
|
||||||
|
.expect("something fucked up");
|
||||||
|
let out = std::str::from_utf8(&output.stdout);
|
||||||
|
let out2 = out.clone()?.trim();
|
||||||
|
match out?.trim() {
|
||||||
|
"true" => {
|
||||||
|
// user has already published today
|
||||||
|
println!("\x1B[1;31mYou have already published today!\x1B[0m");
|
||||||
|
println!("To edit a post published with soyuz-web, run 'soyuz sync down' first.");
|
||||||
|
println!("To edit a published post already saved locally, use 'soyuz write --edit'");
|
||||||
|
Ok(())
|
||||||
|
},
|
||||||
|
"false" => {
|
||||||
|
// open a new file
|
||||||
|
Ok(open_file(filepath.into()))
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
println!("Something went wrong checking your gemini server");
|
||||||
|
println!("Error: {:?}", out2);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
3 => {
|
||||||
|
match args[2].as_str() {
|
||||||
|
"--edit" => Ok(open_file(filepath.into())),
|
||||||
|
_ => {
|
||||||
|
println!("Unknown command. Try 'soyuz help'.");
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
println!("Unknown command. Try 'soyuz help'.");
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn match_single_arg(args: &Vec<String>) -> Result<(), Box<dyn std::error::Error>> {
|
fn match_single_arg(args: &Vec<String>) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
match args[1].as_str() {
|
match args[1].as_str() {
|
||||||
"write" => write(),
|
"write" => write(args),
|
||||||
"settings" => settings(),
|
"settings" => settings(),
|
||||||
"publish" => publish(),
|
"publish" => publish(),
|
||||||
"sync" => sync(args),
|
"sync" => sync(args),
|
||||||
|
@ -302,7 +365,13 @@ fn main() -> Result<(), Box<dyn std::error::Error>>{
|
||||||
match &args.len() {
|
match &args.len() {
|
||||||
1 => Ok(help()),
|
1 => Ok(help()),
|
||||||
2 => match_single_arg(&args),
|
2 => match_single_arg(&args),
|
||||||
3 | 4 => sync(&args),
|
3 | 4 => {
|
||||||
|
match args[1].as_str() {
|
||||||
|
"sync" => sync(&args),
|
||||||
|
"write" => write(&args),
|
||||||
|
&_ => Ok(help())
|
||||||
|
}
|
||||||
|
},
|
||||||
_ => Ok(help())
|
_ => Ok(help())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue