8 Commits

Author SHA1 Message Date
Markus F.J. Busche
fd5ff20743 Add disclaimer 2025-09-20 19:31:50 +02:00
Markus F.J. Busche
87449641f6 chore: remove scripts/upload_asset_direct.sh (deprecated) 2025-09-20 19:29:49 +02:00
Markus F.J. Busche
731cd207dd chore: stage remaining changes 2025-09-20 18:29:54 +02:00
Markus F.J. Busche
a5489de212 docs: korrigiere Screenshot-Dateiname auf .png 2025-09-20 18:24:47 +02:00
Markus F.J. Busche
c0d4448dc1 docs: symlink docs/ -> octoprint_tailscale_funnel/octoprint_tailscale_funnel/docs 2025-09-20 18:24:24 +02:00
Markus F.J. Busche
0d43e181c8 docs: Screenshot der Funnel-Einstellungen in README verlinkt 2025-09-20 18:18:37 +02:00
Markus F.J. Busche
f60068b01f release: update scripts/release_gitea.sh to jq-based flow; skip existing assets 2025-09-20 18:13:22 +02:00
Markus F.J. Busche
4d484c5023 Bump to v0.1.6.2 2025-09-20 18:07:27 +02:00
6 changed files with 42 additions and 72 deletions

1
docs Symbolic link
View File

@@ -0,0 +1 @@
octoprint_tailscale_funnel/octoprint_tailscale_funnel/docs

View File

@@ -2,6 +2,8 @@
This plugin makes your OctoPrint instance accessible from anywhere via Tailscale Funnel, without needing to configure port forwarding, dynamic DNS, or complex firewall settings.
Disclaimer: *This plugin was partially vibe-coded*.
## Features
* Enable/disable Tailscale Funnel access directly from OctoPrint's settings
@@ -9,6 +11,10 @@ This plugin makes your OctoPrint instance accessible from anywhere via Tailscale
* Display the public URL for accessing OctoPrint remotely
* Configure the port to expose via Funnel
## Screenshot
![Tailscale Funnel Settings](octoprint_tailscale_funnel/octoprint_tailscale_funnel/docs/screenshots/funnel-settings.png)
## Requirements
* OctoPrint 1.3.0 or higher

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

View File

@@ -14,7 +14,7 @@ plugin_package = "octoprint_tailscale_funnel"
plugin_name = "OctoPrint-Tailscale-Funnel"
# The plugin's version. Can be overwritten within OctoPrint's internal data via __plugin_version__ in the plugin module
plugin_version = "0.1.6.1"
plugin_version = "0.1.6.2"
# The plugin's description. Can be overwritten within OctoPrint's internal data via __plugin_description__ in the plugin
# module

View File

@@ -1,4 +1,4 @@
{
"version": "0.1.6.1"
"version": "0.1.6.2"
}

View File

@@ -44,54 +44,36 @@ if [ -z "$TOKEN" ]; then
echo "GITEA_API_TOKEN not set (in .env)." >&2; exit 1
fi
# Derive asset name early for later use
ASSET_NAME="$(basename "$ASSET_PATH")"
BODY="Tailscale Funnel Plugin ${TAG}\n\nAutomated release."
if [ -n "$BODY_FILE" ] && [ -f "$BODY_FILE" ]; then
BODY=$(cat "$BODY_FILE")
fi
# Build JSON payload via python (robust quoting)
create_payload=$(REL_TAG="$TAG" REL_NAME="$NAME" REL_BODY_TXT="$BODY" python3 - <<'PY'
import json, os
payload = {
"tag_name": os.environ["REL_TAG"],
"name": os.environ["REL_NAME"],
"body": os.environ["REL_BODY_TXT"],
"draft": False,
"prerelease": False
}
print(json.dumps(payload))
PY
)
# Try to fetch existing release by tag first
get_resp=$(curl -sS -H "Authorization: token ${TOKEN}" "${API_URL}/repos/${OWNER}/${REPO}/releases/tags/${TAG}" || true)
rel_id=$(echo "$get_resp" | jq -r '.id // empty')
create_resp=$(curl -sS -X POST \
if [ -z "$rel_id" ]; then
# Build minimal JSON payload (use existing tag)
create_payload=$(jq -n --arg tag "$TAG" --arg name "$NAME" --arg body "$BODY" '{tag_name:$tag, name:$name, body:$body, draft:false, prerelease:false}')
create_resp=$(curl -sS -X POST \
-H 'Content-Type: application/json' \
-H "Authorization: token ${TOKEN}" \
-d "$create_payload" \
"${API_URL}/repos/${OWNER}/${REPO}/releases" || true)
# Extract id; if missing, fetch by tag
rel_id=$(python3 - <<'PY'
import sys, json
data=sys.stdin.read().strip()
if not data:
print("")
else:
try:
obj=json.loads(data)
print(obj.get('id',''))
except Exception:
print("")
PY
<<<"$create_resp")
# Extract id from create response
rel_id=$(echo "$create_resp" | jq -r '.id // empty')
fi
# Fallback: search releases list for matching tag if still empty
if [ -z "$rel_id" ]; then
get_resp=$(curl -sS -H "Authorization: token ${TOKEN}" "${API_URL}/repos/${OWNER}/${REPO}/releases/tags/${TAG}")
rel_id=$(python3 - <<'PY'
import sys, json
obj=json.loads(sys.stdin.read())
print(obj.get('id',''))
PY
<<<"$get_resp")
list_resp=$(curl -sS -H "Authorization: token ${TOKEN}" "${API_URL}/repos/${OWNER}/${REPO}/releases?limit=100")
rel_id=$(echo "$list_resp" | jq -r --arg tag "$TAG" '[.[] | select(.tag_name==$tag)][0].id // empty')
fi
if [ -z "$rel_id" ]; then
@@ -100,37 +82,18 @@ if [ -z "$rel_id" ]; then
exit 1
fi
# Delete existing asset with same name (if any)
# Check if asset exists (skip upload if present)
assets_json=$(curl -sS -H "Authorization: token ${TOKEN}" "${API_URL}/repos/${OWNER}/${REPO}/releases/${rel_id}/assets")
asset_id=$(python3 - <<'PY'
import sys, json, os
name=os.environ['ASSET_NAME']
try:
arr=json.loads(sys.stdin.read())
for a in arr:
if a.get('name')==name:
print(a.get('id',''))
break
except Exception:
pass
PY
ASSET_NAME="$(basename "$ASSET_PATH")" <<<"$assets_json")
asset_exists=$(echo "$assets_json" | jq -r --arg name "$ASSET_NAME" 'any(.[]; .name==$name)')
if [ -n "$asset_id" ]; then
curl -sS -X DELETE -H "Authorization: token ${TOKEN}" "${API_URL}/repos/${OWNER}/${REPO}/releases/${rel_id}/assets/${asset_id}" >/dev/null || true
if [ "$asset_exists" = "true" ]; then
echo "Asset already exists, skipping upload: ${ASSET_NAME}"
else
echo "Uploading asset: ${ASSET_NAME}"
upload_resp=$(curl -sS -H "Authorization: token ${TOKEN}" -F attachment=@"${ASSET_PATH}" "${API_URL}/repos/${OWNER}/${REPO}/releases/${rel_id}/assets?name=${ASSET_NAME}")
html_url=$(echo "$upload_resp" | jq -r '.browser_download_url // empty')
echo "Asset uploaded: ${html_url}"
fi
# Upload asset
upload_resp=$(curl -sS -H "Authorization: token ${TOKEN}" -F attachment=@"${ASSET_PATH}" "${API_URL}/repos/${OWNER}/${REPO}/releases/${rel_id}/assets?name=$(basename "$ASSET_PATH")")
html_url=$(python3 - <<'PY'
import sys, json
try:
print(json.loads(sys.stdin.read()).get('browser_download_url',''))
except Exception:
print("")
PY
<<<"$upload_resp")
echo "Release ${TAG} created (id=${rel_id}). Asset uploaded: ${html_url}"
echo "Release ${TAG} ready (id=${rel_id})."