~0wx.eu~ :: Filhotell och andra användbara verktyg


Ladda upp Kort URL Enorma URL Pastebin Handla om Anmäl Logga in
Svenska
English English Español Español Català Català Galego Galego Português Português Français Français Italiano Italiano Română Română Deutsch Deutsch Nederlands Nederlands Dansk Dansk Bokmål Bokmål Íslenska Íslenska 日本語 日本語 简体中文 简体中文 繁體中文 繁體中文 한국어 한국어 Euskara Euskara Esperanto Esperanto Polski Polski Čeština Čeština Українська Українська Русский Русский Türkçe Türkçe Bahasa Indonesia Bahasa Indonesia Bahasa Melayu Bahasa Melayu

Det finns en fjärrkontroll för alla funktioner på 0wx.eu. Du kan använda den för skript eller kommandorad.

Everything the forms on this site do, for scripts. Every reply is JSON, including errors, so you never have to guess whether a body is a result or an explanation.

Making a request

POST to the endpoint with either form parameters or a JSON body. Both are equivalent; pick whichever your tooling makes easier. The action parameter selects what to do. Use --data-urlencode for anything a person typed — paste text, a URL, a translation — because -d sends the value raw and it will be cut at the first &. Plain -d is fine for fixed values like action itself. wget has no --data-urlencode at all, so with wget either percent-encode such values yourself or send a JSON body, which needs no encoding.

curl -X POST https://0wx.eu/api.cgi \
     -d action=paste --data-urlencode 'content=hello & world'

curl -X POST https://0wx.eu/api.cgi \
     -H 'Content-Type: application/json' \
     -d '{"action":"paste","content":"hello & world"}'

wget -qO- --header='Content-Type: application/json' \
     --post-data '{"action":"paste","content":"hello & world"}' https://0wx.eu/api.cgi
Values containing &

In a form body & separates parameters, and curl -d does not encode what you give it. A URL with a query string is therefore cut at its first &, and the rest arrives as separate parameters. Use --data-urlencode, or send JSON. Stray parameters are refused rather than ignored, so this fails loudly instead of storing half a link.

# wrong -- the value is cut at the &
curl -X POST https://0wx.eu/api.cgi \
     -d action=tinyurl -d 'url=https://example.com/?a=1&b=2'

# right
curl -X POST https://0wx.eu/api.cgi \
     -d action=tinyurl --data-urlencode 'url=https://example.com/?a=1&b=2'

# also right -- JSON needs no escaping
curl -X POST https://0wx.eu/api.cgi -H 'Content-Type: application/json' \
     -d '{"action":"tinyurl","url":"https://example.com/?a=1&b=2"}'

# wget has no --data-urlencode, so percent-encode it yourself...
wget -qO- --post-data 'action=tinyurl&url=https%3A%2F%2Fexample.com%2F%3Fa%3D1%26b%3D2' https://0wx.eu/api.cgi

# ...or send JSON, which needs no encoding at all
wget -qO- --header='Content-Type: application/json' \
     --post-data '{"action":"tinyurl","url":"https://example.com/?a=1&b=2"}' https://0wx.eu/api.cgi
Authentication

Optional. Without a key a request is anonymous and behaves exactly like an anonymous visitor — the result is public either way, the only difference is whether it lands in your file list. Generate a key on your account page and send it as a bearer token; passing it as an apikey parameter also works, but a key in a query string ends up in server logs and browser history.

curl -X POST https://0wx.eu/api.cgi \
     -H 'Authorization: Bearer YOUR_KEY' \
     -d action=whoami

wget -qO- --header='Authorization: Bearer YOUR_KEY' \
     --post-data 'action=whoami' https://0wx.eu/api.cgi
Actions
actionParametersDescription
whoamiConfirms a key works and reports the current limits. Costs nothing; call it first.
ipReports your address, its PTR, the country, state and city it geolocates to, the coordinates, and the user agent you sent. Needs no key and answers the same with or without one. Deliberately narrower than the web page: no WHOIS, no DNS zone and no blocklist lookups, so calling it costs the server nothing but a local database read.
uploadfile (repeatable), resize, lifetime, gallery or gUploads one or more files. Must be multipart/form-data. Naming a gallery puts them straight into it and returns its id.
tinyurlurl, lifetimeShortens a URL.
hugeurlurl, lifetimeLengthens a URL, absurdly, on purpose.
pastecontent, lifetimeStores a block of text and returns a link to it.
translatecontent, toTranslates text. to is an ISO 639 code — note these are not always country codes: Danish is da, not dk.
listfilespage, gLists your files with everything the Info panel shows, plus the thumbnail and direct link. g limits it to one gallery, or none for files in no gallery.
listpastespageLists your pastes, with a 200-character preview of each rather than the whole body.
listurlspageLists your short and huge URLs, with the address each one points at.
otlshareCreates a one-time link to one of your files. Each call mints a new one, so handing the same file to two people gives two links.
listotlpageLists your active one-time links, the file each points at, and whether that file has since expired.
listgalleriesLists your galleries with their ids, names, file counts and publishing state.
galleryg, publishReports a gallery's publishing state, and changes it when publish is given.
moveshare (repeatable), gallery or gMoves files into a gallery, by name (created if new) or by id. Both omitted moves them back to the main listing.
deleteshare (repeatable), g, otl, withfilesDeletes files, pastes, short URLs, galleries, one-time links, or any mix. A share is matched against your files first and then against your pastes and links, so the caller does not have to sort them by type. One-time links go in otl, separately: removing a link must not be confusable with deleting the file it points at.

☉ These actions need an API key. They read or change one account's own data, so there is no anonymous form of them.

Several at once

share and g accept a repeated field, a JSON array, or a comma-separated list — whichever your tooling makes easiest. Duplicates are ignored.

curl -X POST https://0wx.eu/api.cgi -H 'Authorization: Bearer YOUR_KEY' \
     -d action=move -d share=Ab3xK9pQ -d share=Zz7yT2mN --data-urlencode 'gallery=Holiday 2026'

curl -X POST https://0wx.eu/api.cgi -H 'Authorization: Bearer YOUR_KEY' \
     -d action=delete -d 'share=Ab3xK9pQ,Zz7yT2mN'

curl -X POST https://0wx.eu/api.cgi -H 'Content-Type: application/json' \
     -H 'Authorization: Bearer YOUR_KEY' \
     -d '{"action":"move","share":["Ab3xK9pQ","Zz7yT2mN"],"g":7}'

wget -qO- --header='Authorization: Bearer YOUR_KEY' \
     --post-data 'action=delete&share=Ab3xK9pQ,Zz7yT2mN' https://0wx.eu/api.cgi
Galleries

Wherever a gallery is named — on upload or on move — it is given the same two ways: g for an existing id, or gallery for a name, which is created if it is new. If both are sent, g wins. The reply carries the gallery id. Note that deleting a gallery removes only the gallery, leaving its files in the main listing — unlike the web form, which deletes them after asking. Pass withfiles=true to delete them as well: a script tidying up its groupings should not lose the uploads by accident.

curl -X POST https://0wx.eu/api.cgi -H 'Authorization: Bearer YOUR_KEY' \
     -F action=upload -F file=@photo.jpg --form-string 'gallery=Holiday 2026'

curl -X POST https://0wx.eu/api.cgi -H 'Authorization: Bearer YOUR_KEY' \
     -d action=gallery -d g=7 -d publish=true

wget -qO- --header='Authorization: Bearer YOUR_KEY' \
     --post-data 'action=gallery&g=7&publish=true' https://0wx.eu/api.cgi
Uploading files

Uploads cannot use the JSON body, because a file has to be sent as multipart. Repeat the file part to send several at once. Each file is reported separately: the reply carries a files list of those that were accepted and a rejected list of those that were not, so a partial success is still a success.

curl -X POST https://0wx.eu/api.cgi \
     -H 'Authorization: Bearer YOUR_KEY' \
     -F action=upload \
     -F file=@photo.jpg \
     -F file=@notes.txt \
     -F lifetime=7d

There is no wget form of this one. wget cannot build a multipart/form-data body — it has no equivalent of curl's -F — and uploads must be multipart. Use curl, or assemble the body and boundary yourself and send it with --post-file.

Lifetime

Optional on every action that stores something. Accepts bare seconds, or a number followed by m, h or d — the same forms the web forms take. Omit it or pass 0 to keep the item indefinitely.

Replies

Every reply is a JSON object with an ok field. On success it carries the result; on failure it carries a stable error code and a human-readable message. Branch on the code, log the message.

{"ok":true,"type":"paste","share":"Ab3xK9pQ",
 "url":"https://0wx.eu/p/Ab3xK9pQ","bytes":11}

{"ok":false,"error":"url_too_long",
 "message":"URL exceeds the maximum length."}
Error codes
errorHTTPDescription
unknown_action400No such action.
bad_json400The body was not valid JSON, or a field held a nested structure.
unexpected_parameter400A parameter arrived that this action does not take — usually an unencoded & in a value. The message names the parameters.
bad_key401The key was not recognised. A wrong key is refused rather than silently treated as anonymous.
bad_url400The URL is malformed, or uses a scheme other than http(s), ftp or gopher.
bad_lifetime400The lifetime was not a number or a number followed by m, h or d.
no_content400Nothing was sent to store.
url_too_long413The URL is longer than the limit.
paste_too_long413The text is larger than the paste limit. Limits are measured in bytes of UTF-8, so non-Latin text counts more than its character count suggests.
too_many_files413More files than one call accepts.
no_usable_files415Every file was rejected. Check the rejected list for why.
backend_unavailable502The translation backend did not answer.
internal500Something failed unexpectedly. It has been logged.
Limits

Call whoami to read the current values rather than hardcoding them — they are set by the server operator and can change. Sizes are bytes of UTF-8.

A shell client

0wx.sh wraps all of the above. It is plain POSIX shell and needs nothing but curl, and it is short enough to read before you run it — which is the right thing to do with a script that will hold your API key. Put the key in OWX_KEY rather than passing --key, and it stays out of your shell history.

wget https://0wx.eu/clients/0wx.sh
chmod +x 0wx.sh
export OWX_KEY=YOUR_KEY
./0wx.sh help
./0wx.sh paste --content 'hello & world'
A Python client

0wx.py does the same as the shell client, but parses the reply and prints what the fields mean rather than handing you raw JSON — add --json when you want the raw form back. Standard library only: no requests, nothing to install. If you are writing your own client, its send() and report() functions are the parts worth reading: between them they show how to build the request, how to get the message out of a failed one, and what the replies contain.

wget https://0wx.eu/clients/0wx.py
chmod +x 0wx.py
export OWX_KEY=YOUR_KEY
./0wx.py listfiles
./0wx.py listfiles --json | jq '.files[].url'
A Perl client

0wx.pl does the same as the Python one and prints the same output. Core modules only — HTTP::Tiny and JSON::PP have shipped with Perl since 5.14, so there is nothing to install. Worth reading next to the Python client if you are writing your own: the two languages fail differently on a broken request, and both scripts say where.

wget https://0wx.eu/clients/0wx.pl
chmod +x 0wx.pl
export OWX_KEY=YOUR_KEY
./0wx.pl listfiles
A window, if you prefer one

0wx-gtk.pl is a small GTK window with tabs for uploading, pasting, shortening, and browsing your files — as a list or as a gallery of thumbnails, filtered by gallery. It is the one client here with a dependency: the Perl GTK3 bindings, which a graphical program cannot avoid. Everything else it uses ships with Perl. The key is held in memory only: closing the window forgets it, and setting OWX_KEY fills it in at startup. Whatever it shows you, the server's raw reply is one click away under “Server reply”.

apt install libgtk3-perl        # or: dnf install perl-Gtk3
wget https://0wx.eu/clients/0wx-gtk.pl
chmod +x 0wx-gtk.pl
OWX_KEY=YOUR_KEY ./0wx-gtk.pl
An Android app

0wx-android.apk does what the other clients do, from a phone: uploading, pasting, shortening, translating, and browsing your files as a list or a gallery. Sharing a file to it from any other app uploads it, and sharing text stores it as a paste. It is not on any app store, so your device will ask you to allow installing it — which is a question worth taking seriously in general, and the reason the whole source is also here: open it in Android Studio and build it yourself rather than trusting the file. Building needs JDK 21; BUILDING.md inside says why.

https://0wx.eu/clients/0wx-android.apk        # install it
https://0wx.eu/clients/0wx-android.zip        # build it yourself
Notes

There is deliberately no remote-fetch action. It would make the server retrieve a URL of the caller's choosing, which is a request-forgery surface, and a script can drive that far harder than a form. Upload the file yourself instead.


(p) 2018 0wx.eu - / - Drivs av Linux och GNU. Lev fritt eller dö! (root@0wx.eu)