Add site selection and config override
This commit is contained in:
parent
160388194a
commit
8d1488f354
13
README.md
13
README.md
@ -14,7 +14,17 @@ Make sure you have `curl` and `jq` installed. If you want to enter text in
|
|||||||
markdown format, install `python-markdown2` (`pip install markdown2` or your
|
markdown format, install `python-markdown2` (`pip install markdown2` or your
|
||||||
distro's `python3-markdown2` package).
|
distro's `python3-markdown2` package).
|
||||||
|
|
||||||
Create a config file `~/.config/wordpress-rest-curl/config.sh` from the `config.sh.template` file.
|
Copy `config.sh.template` to `~/.config/wordpress-rest-curl/config.sh` and
|
||||||
|
fill in whatever's shared across sites (`TRANSFORM`, `EDITOR`, `STATUS`, ...).
|
||||||
|
`config.sh` is always loaded first if it exists — it doesn't need `USER`,
|
||||||
|
`PASSWORD`, or `SERVER` filled in.
|
||||||
|
|
||||||
|
If you post to more than one WordPress instance, copy `site.sh.template` to
|
||||||
|
`~/.config/wordpress-rest-curl/NAME.sh` once per site, e.g.
|
||||||
|
`blog-example-com.sh` and `news-example-com.sh`, containing just the per-instance bits
|
||||||
|
(`USER`, `PASSWORD`, `SERVER`, and any `CATEGORIES`/`TAGS` that differ). Pick
|
||||||
|
one at run time with `--site NAME` (see Options below) — its values are
|
||||||
|
layered on top of `config.sh`, overriding only what it sets.
|
||||||
|
|
||||||
Copy the posting script to e.g. `/usr/local/bin/wordpress-post` so that you can run it from anywhere.
|
Copy the posting script to e.g. `/usr/local/bin/wordpress-post` so that you can run it from anywhere.
|
||||||
|
|
||||||
@ -25,6 +35,7 @@ Copy the posting script to e.g. `/usr/local/bin/wordpress-post` so that you can
|
|||||||
* Done!
|
* Done!
|
||||||
|
|
||||||
### Options
|
### Options
|
||||||
|
* `--site NAME` — use `~/.config/wordpress-rest-curl/NAME.sh` instead of the default `config.sh`. Useful when posting to multiple WordPress instances with different credentials.
|
||||||
* `--file PATH` — use PATH as the post content instead of opening `$EDITOR`.
|
* `--file PATH` — use PATH as the post content instead of opening `$EDITOR`.
|
||||||
* `--publish` — shortcut for `STATUS=publish`, posts live immediately.
|
* `--publish` — shortcut for `STATUS=publish`, posts live immediately.
|
||||||
* `--edit POST_ID` — update an existing post instead of creating a new one.
|
* `--edit POST_ID` — update an existing post instead of creating a new one.
|
||||||
|
|||||||
@ -1,4 +1,8 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
# Shared defaults, loaded before any --site NAME file. If you only ever post
|
||||||
|
# to one WordPress instance, fill in USER/PASSWORD/SERVER here too and skip
|
||||||
|
# --site entirely. If you post to more than one, leave those three blank
|
||||||
|
# here and put them in per-site files instead (see README).
|
||||||
EDITOR=vim
|
EDITOR=vim
|
||||||
TRANSFORM=('title' 'markdown') # empty or a subset of: 'title' 'markdown'
|
TRANSFORM=('title' 'markdown') # empty or a subset of: 'title' 'markdown'
|
||||||
USER="" # WP user to create the post
|
USER="" # WP user to create the post
|
||||||
|
|||||||
29
post.sh
29
post.sh
@ -11,21 +11,28 @@ STATUS="draft" # one of publish,future,draft,pending,private
|
|||||||
CATEGORIES="" # comma separated integer IDs of categories
|
CATEGORIES="" # comma separated integer IDs of categories
|
||||||
TAGS="" # comma separated integer IDs of tags
|
TAGS="" # comma separated integer IDs of tags
|
||||||
TMPFILE=/tmp/wordpress-post.txt # location of a temporary file with the post text
|
TMPFILE=/tmp/wordpress-post.txt # location of a temporary file with the post text
|
||||||
|
CONFIG_DIR="${WORDPRESS_REST_CURL_CONFIG_DIR:-$HOME/.config/wordpress-rest-curl}"
|
||||||
|
|
||||||
source ~/.config/wordpress-rest-curl/config.sh
|
# CLI options:
|
||||||
|
# --site NAME after config.sh, also source $CONFIG_DIR/NAME.sh, whose
|
||||||
# CLI options (override config):
|
# values override config.sh's (lets you keep just the
|
||||||
|
# per-instance bits — USER/PASSWORD/SERVER — in each site
|
||||||
|
# file, and shared defaults in config.sh)
|
||||||
# --edit POST_ID update an existing post instead of creating a new one
|
# --edit POST_ID update an existing post instead of creating a new one
|
||||||
# --publish shortcut for STATUS=publish
|
# --publish shortcut for STATUS=publish
|
||||||
# --file PATH use PATH as the post source instead of opening $EDITOR
|
# --file PATH use PATH as the post source instead of opening $EDITOR
|
||||||
|
SITE=""
|
||||||
POST_ID=""
|
POST_ID=""
|
||||||
SOURCE_FILE=""
|
SOURCE_FILE=""
|
||||||
|
PUBLISH=0
|
||||||
while [[ $# -gt 0 ]]; do
|
while [[ $# -gt 0 ]]; do
|
||||||
case "$1" in
|
case "$1" in
|
||||||
|
--site)
|
||||||
|
SITE="$2"; shift 2 ;;
|
||||||
--edit)
|
--edit)
|
||||||
POST_ID="$2"; shift 2 ;;
|
POST_ID="$2"; shift 2 ;;
|
||||||
--publish)
|
--publish)
|
||||||
STATUS="publish"; shift ;;
|
PUBLISH=1; shift ;;
|
||||||
--file)
|
--file)
|
||||||
SOURCE_FILE="$2"; shift 2 ;;
|
SOURCE_FILE="$2"; shift 2 ;;
|
||||||
*)
|
*)
|
||||||
@ -34,6 +41,20 @@ while [[ $# -gt 0 ]]; do
|
|||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
|
DEFAULT_CONFIG_FILE="$CONFIG_DIR/config.sh"
|
||||||
|
[[ -e "$DEFAULT_CONFIG_FILE" ]] && source "$DEFAULT_CONFIG_FILE"
|
||||||
|
|
||||||
|
if [[ -n "$SITE" ]]; then
|
||||||
|
SITE_CONFIG_FILE="$CONFIG_DIR/$SITE.sh"
|
||||||
|
[[ -e "$SITE_CONFIG_FILE" ]] || { echo "Config file not found: $SITE_CONFIG_FILE" >&2; exit 1; }
|
||||||
|
source "$SITE_CONFIG_FILE"
|
||||||
|
elif [[ ! -e "$DEFAULT_CONFIG_FILE" ]]; then
|
||||||
|
echo "No site specified and no default config found. Pass --site NAME or create $DEFAULT_CONFIG_FILE" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
[[ "$PUBLISH" -eq 1 ]] && STATUS="publish"
|
||||||
|
|
||||||
# let the user provide the post content
|
# let the user provide the post content
|
||||||
if [[ -n "$SOURCE_FILE" ]]; then
|
if [[ -n "$SOURCE_FILE" ]]; then
|
||||||
cp "$SOURCE_FILE" "$TMPFILE" || exit 1
|
cp "$SOURCE_FILE" "$TMPFILE" || exit 1
|
||||||
|
|||||||
9
site.sh.template
Normal file
9
site.sh.template
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Per-site overrides, loaded after config.sh when running with --site NAME.
|
||||||
|
# Copy to ~/.config/wordpress-rest-curl/NAME.sh and fill in. Only set what
|
||||||
|
# differs from config.sh -- anything left out here falls back to config.sh.
|
||||||
|
USER="" # WP user to create the post
|
||||||
|
PASSWORD="" # application password generated for your WP user
|
||||||
|
SERVER="" # server hostname, optionally with subdirectories
|
||||||
|
CATEGORIES="" # comma separated integer IDs of categories
|
||||||
|
TAGS="" # comma separated integer IDs of tags
|
||||||
@ -34,6 +34,13 @@ SERVER="http://127.0.0.1:$PORT"
|
|||||||
CATEGORIES="3,7"
|
CATEGORIES="3,7"
|
||||||
TAGS="10"
|
TAGS="10"
|
||||||
EOF
|
EOF
|
||||||
|
# Deliberately sparse: only the fields that differ from config.sh, to prove
|
||||||
|
# --site layers on top of the default config rather than replacing it.
|
||||||
|
cat > "$HOME/.config/wordpress-rest-curl/othersite.sh" <<EOF
|
||||||
|
USER="other-tester"
|
||||||
|
PASSWORD="other-pass"
|
||||||
|
CATEGORIES="1"
|
||||||
|
EOF
|
||||||
|
|
||||||
POST_FILE="$WORKDIR/post.md"
|
POST_FILE="$WORKDIR/post.md"
|
||||||
cat > "$POST_FILE" <<'EOF2'
|
cat > "$POST_FILE" <<'EOF2'
|
||||||
@ -77,6 +84,27 @@ REQ=$(cat "$MOCK_WP_REQUEST_FILE")
|
|||||||
assert_eq "edit: path includes post ID" "/wp-json/wp/v2/posts/99" "$(jq -r '.path' <<<"$REQ")"
|
assert_eq "edit: path includes post ID" "/wp-json/wp/v2/posts/99" "$(jq -r '.path' <<<"$REQ")"
|
||||||
assert_eq "edit: status defaults to draft" "draft" "$(jq -r '.payload.status' <<<"$REQ")"
|
assert_eq "edit: status defaults to draft" "draft" "$(jq -r '.payload.status' <<<"$REQ")"
|
||||||
|
|
||||||
|
# --- --site layers on top of config.sh: overrides what it sets, inherits the rest ---
|
||||||
|
rm -f "$MOCK_WP_REQUEST_FILE" "$MOCK_WP_CONTROL_FILE"
|
||||||
|
run_post_sh --site othersite --file "$POST_FILE" >/dev/null
|
||||||
|
assert_eq "site: exit code" "0" "$?"
|
||||||
|
REQ=$(cat "$MOCK_WP_REQUEST_FILE")
|
||||||
|
assert_eq "site: categories overridden by site config" "[1]" "$(jq -c '.payload.categories' <<<"$REQ")"
|
||||||
|
assert_eq "site: tags inherited from default config" "[10]" "$(jq -c '.payload.tags' <<<"$REQ")"
|
||||||
|
assert_eq "site: title transform inherited from default config" "My Test Title" "$(jq -r '.payload.title' <<<"$REQ")"
|
||||||
|
|
||||||
|
rm -f "$MOCK_WP_REQUEST_FILE" "$MOCK_WP_CONTROL_FILE"
|
||||||
|
OUT=$(run_post_sh --site does-not-exist --file "$POST_FILE" 2>&1)
|
||||||
|
assert_eq "site: unknown site exits non-zero" "1" "$?"
|
||||||
|
assert_eq "site: unknown site error message" "true" "$(grep -q "Config file not found" <<<"$OUT" && echo true || echo false)"
|
||||||
|
|
||||||
|
# --- no --site and no default config.sh: clean error, not a crash ---
|
||||||
|
mv "$HOME/.config/wordpress-rest-curl/config.sh" "$WORKDIR/config.sh.bak"
|
||||||
|
OUT=$(run_post_sh --file "$POST_FILE" 2>&1)
|
||||||
|
assert_eq "no config: exits non-zero" "1" "$?"
|
||||||
|
assert_eq "no config: error message" "true" "$(grep -q "No site specified and no default config found" <<<"$OUT" && echo true || echo false)"
|
||||||
|
mv "$WORKDIR/config.sh.bak" "$HOME/.config/wordpress-rest-curl/config.sh"
|
||||||
|
|
||||||
# --- non-2xx response is surfaced and script exits non-zero ---
|
# --- non-2xx response is surfaced and script exits non-zero ---
|
||||||
rm -f "$MOCK_WP_REQUEST_FILE"
|
rm -f "$MOCK_WP_REQUEST_FILE"
|
||||||
echo '{"status": 401, "body": {"code": "rest_forbidden", "message": "Sorry, you are not allowed to do that."}}' > "$MOCK_WP_CONTROL_FILE"
|
echo '{"status": 401, "body": {"code": "rest_forbidden", "message": "Sorry, you are not allowed to do that."}}' > "$MOCK_WP_CONTROL_FILE"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user