~0wx.es~ :: Хостинг файлов и другие полезные инструменты


Загрузка TinyURL HugeURL Pastebin О сервисе Пожаловаться Вход
Русский ▼
English English Deutsch Deutsch Plattdüütsch Plattdüütsch Lëtzebuergesch Lëtzebuergesch Nederlands Nederlands Dansk Dansk Svenska Svenska Bokmål Bokmål Nynorsk Nynorsk Íslenska Íslenska Føroyskt Føroyskt Español Español Català Català Galego Galego Português Português Français Français Italiano Italiano Latina Latina Română Română Rumantsch Rumantsch Gaeilge Gaeilge Suomi Suomi Magyar Magyar Euskara Euskara Esperanto Esperanto 日本語 日本語 简体中文 简体中文 繁體中文(台灣) 繁體中文(台灣) 繁體中文(香港) 繁體中文(香港) 粵語 粵語 한국어 한국어 Tiếng Việt Tiếng Việt ไทย ไทย Bahasa Indonesia Bahasa Indonesia Bahasa Melayu Bahasa Melayu हिन्दी हिन्दी Ελληνικά Ελληνικά Polski Polski Čeština Čeština Українська Українська Türkçe Türkçe العربية العربية עברית עברית Kiswahili Kiswahili ʻŌlelo Hawaiʻi ʻŌlelo Hawaiʻi tlhIngan Hol tlhIngan Hol Quenya Quenya

Для всех функций на 0wx.es есть API. Его можно использовать в скриптах или из консоли.

Всё, что делают формы на этом сайте, для скриптов. Каждый ответ — JSON, включая ошибки, так что вам никогда не придётся гадать, результат это или объяснение.

Выполнение запроса

POST на конечную точку с параметрами формы или с телом JSON. Оба варианта равнозначны; выбирайте тот, что удобнее вашим инструментам. Параметр action выбирает действие. Для всего, что набрал человек — текста, URL, перевода — используйте --data-urlencode, потому что -d отправляет значение как есть и оно обрежется на первом &. Обычного -d достаточно для фиксированных значений вроде самого action. У wget вообще нет --data-urlencode, так что с wget либо процентно кодируйте такие значения сами, либо отправляйте тело JSON, которому кодирование не нужно.

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

curl -X POST https://0wx.es/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.es/api.cgi
Значения, содержащие &

В теле формы & разделяет параметры, а curl -d не кодирует то, что вы ему даёте. Поэтому URL со строкой запроса обрезается на своём первом &, а остаток приходит отдельными параметрами. Используйте --data-urlencode или отправляйте JSON. Лишние параметры отклоняются, а не игнорируются, так что это громко падает, а не сохраняет половину ссылки.

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

# right
curl -X POST https://0wx.es/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.es/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.es/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.es/api.cgi
Аутентификация

Необязательно. Без ключа запрос анонимен и ведёт себя в точности как анонимный посетитель — результат в любом случае публичен, разница лишь в том, попадёт ли он в ваш список файлов. Создайте ключ на странице аккаунта и отправляйте его как bearer-токен; передача параметром apikey тоже работает, но ключ в строке запроса оседает в журналах сервера и истории браузера.

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

wget -qO- --header='Authorization: Bearer YOUR_KEY' \
     --post-data 'action=whoami' https://0wx.es/api.cgi
Действия
actionПараметрыОписание
whoami—Подтверждает, что ключ работает, и сообщает текущие лимиты. Ничего не стоит; вызывайте его первым.
ip—Сообщает ваш адрес, его PTR, страну, регион и город, куда он геолоцируется, координаты и присланный вами user agent. Ключ не нужен, ответ одинаков с ним и без него. Намеренно уже веб-страницы: без WHOIS, без зоны DNS и без запросов к чёрным спискам, так что вызов стоит серверу лишь одного чтения из локальной базы.
uploadfile (повторяемый), resize, lifetime, gallery или g *Загружает один или несколько файлов. Должно быть multipart/form-data. Указание галереи помещает их прямо в неё и возвращает её id.
tinyurlurl, lifetimeСокращает URL.
hugeurlurl, lifetimeУдлиняет URL, абсурдно, намеренно.
pastecontent, lifetimeСохраняет блок текста и возвращает ссылку на него.
translatecontent, to, fromПереводит текст. to и from — коды из действия langs — учтите, что это не всегда коды стран: датский — da, а не dk. from можно опустить или указать как auto, тогда бэкенд определит язык сам; явное указание даёт лучший результат на коротком тексте.
langsПеречисляет языки, которые принимает translate, как supported_langs: один объект на язык, код и название, в том порядке, в каком их предлагает сайт. Ключ API не нужен.
dyndnskey, ip, formatОбновляет динамическое DNS-имя. Единственное действие, которому не нужен ключ API: его вызывает маршрутизатор, у которого одно поле для URL и нет способа отправить заголовок. key — ключ обновления конкретного имени, показанный в вашем аккаунте, а не ваш ключ API. Опустите ip, и будет использован адрес, с которого вы вызываете. Ответ — фактическое слово dyndns2 — good, nochg, badauth, abuse или dnserr — простым текстом, потому что именно его разбирают маршрутизаторы; добавьте format=json для обычного JSON.
listfiles *page, gПеречисляет ваши файлы со всем, что показывает панель «Инфо», плюс миниатюру и прямую ссылку. g ограничивает одной галереей, none — файлами вне галерей.
listpastes *pageПеречисляет ваши тексты, для каждого — превью в 200 символов вместо всего тела.
listurls *pageПеречисляет ваши короткие и огромные URL с адресом, на который указывает каждый.
otl *shareСоздаёт одноразовую ссылку на один из ваших файлов. Каждый вызов чеканит новую, так что отдать один файл двум людям — значит получить две ссылки.
listotl *pageПеречисляет ваши активные одноразовые ссылки, файл, на который указывает каждая, и не истёк ли с тех пор этот файл.
listgalleries *—Перечисляет ваши галереи с их id, названиями, числом файлов и состоянием публикации.
gallery *g, publishСообщает состояние публикации галереи и меняет его, если передан publish.
move *share (повторяемый), gallery или gПеремещает файлы в галерею по имени (создаётся, если новое) или по id. Если опущено и то и другое, возвращает их в основной список.
delete *share (повторяемый), g, otl, withfilesУдаляет файлы, тексты, короткие URL, галереи, одноразовые ссылки или любую их смесь. Share сначала сопоставляется с вашими файлами, затем с текстами и ссылками, так что вызывающему не нужно сортировать их по типу. Одноразовые ссылки идут отдельно, в otl: удаление ссылки не должно путаться с удалением файла, на который она указывает.

* Этим действиям нужен ключ API. Они читают или меняют данные одного аккаунта, поэтому анонимной формы у них нет.

Несколько за раз

share и g принимают повторяющееся поле, массив JSON или список через запятую — что удобнее вашим инструментам. Дубликаты игнорируются.

curl -X POST https://0wx.es/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.es/api.cgi -H 'Authorization: Bearer YOUR_KEY' \
     -d action=delete -d 'share=Ab3xK9pQ,Zz7yT2mN'

curl -X POST https://0wx.es/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.es/api.cgi
Галереи

Где бы ни указывалась галерея — в upload или в move — это делается одними и теми же двумя способами: g для существующего id или gallery для имени, которое создаётся, если оно новое. Если переданы оба, побеждает g. Ответ несёт id галереи. Учтите, что удаление галереи удаляет только галерею, оставляя её файлы в основном списке — в отличие от веб-формы, которая после вопроса удаляет и их. Передайте withfiles=true, чтобы удалить и файлы: скрипт, наводящий порядок в своих группах, не должен случайно терять загрузки.

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

curl -X POST https://0wx.es/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.es/api.cgi
Загрузка файлов

Загрузки не могут использовать тело JSON, потому что файл должен передаваться как multipart. Повторите часть file, чтобы отправить несколько за раз. О каждом файле сообщается отдельно: ответ несёт список files принятых и список rejected отклонённых, так что частичный успех — всё равно успех.

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

Варианта для wget здесь нет. wget не умеет собирать тело multipart/form-data — у него нет аналога -F из curl — а загрузки должны быть multipart. Используйте curl либо соберите тело и boundary сами и отправьте через --post-file.

Срок хранения

Необязательно для любого действия, которое что-то сохраняет. Принимает просто секунды или число с m, h или d после него — те же формы, что и веб-формы. Опустите или передайте 0, чтобы хранить элемент бессрочно.

Ответы

Каждый ответ — объект JSON с полем ok. При успехе он несёт результат; при ошибке — стабильный код error и читаемое message. Ветвитесь по коду, сообщение пишите в журнал.

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

{"ok":false,"error":"url_too_long",
 "message":"URL exceeds the maximum length."}
Аудиотеги

Если файл их несёт, listfiles добавляет в его запись file_tags: исполнителя, название и альбом, прочитанные из ID3, комментариев Vorbis или атомов MP4 при загрузке файла. Когда сообщать нечего — а это большинство файлов — ключ отсутствует, а не равен null, так что проверяйте его наличие перед чтением. Отдельные поля тоже могут отсутствовать — у файла может быть название и не быть альбома. Ничего больше из метаданных файла не раскрывается: покупка в iTunes хранит имя и Apple ID покупателя, и они намеренно никогда не читаются.

{"ok":true,"type":"files","total":2,"page":1,"pages":1,"files":[
  {"share":"Ab3xK9pQ","name":"autobahn.mp3","mime":"audio/mpeg",
   "bytes":8123456,"url":"https://0wx.es/i/Ab3xK9pQ",
   "file_tags":{"artist":"Kraftwerk","title":"Autobahn","album":"Autobahn"}},
  {"share":"Zz7yT2mN","name":"photo.jpg","mime":"image/jpeg",
   "bytes":204800,"url":"https://0wx.es/i/Zz7yT2mN"}
]}
Коды ошибок
errorHTTPОписание
unknown_action400Такого действия нет.
bad_json400Тело не было корректным JSON, или поле содержало вложенную структуру.
unexpected_parameter400Пришёл параметр, который это действие не принимает — обычно незакодированный & в значении. Сообщение называет параметры.
bad_key401Ключ не распознан. Неверный ключ отклоняется, а не молча считается анонимным.
bad_url400URL сформирован неверно или использует схему, отличную от http(s), ftp или gopher.
bad_lifetime400Срок хранения не был числом или числом с m, h или d после него.
no_content400Нечего сохранять: ничего не отправлено.
url_too_long413URL длиннее лимита.
paste_too_long413Текст больше лимита для текстов. Лимиты измеряются в байтах UTF-8, поэтому нелатинский текст считается больше, чем подсказывает число символов.
too_many_files413Файлов больше, чем принимает один вызов.
no_usable_files415Все файлы отклонены. Причины — в списке rejected.
backend_unavailable502Бэкенд перевода не ответил.
internal500Что-то неожиданно сломалось. Это записано в журнал.
Лимиты

Читайте текущие значения вызовом whoami, а не зашивайте их в код — их задаёт оператор сервера, и они могут меняться. Размеры — в байтах UTF-8.

Клиент для shell

0wx.sh оборачивает всё перечисленное выше. Это чистый POSIX shell, ему нужен только curl, и он достаточно короток, чтобы прочитать его перед запуском — что и следует делать со скриптом, который будет хранить ваш ключ API. Положите ключ в OWX_KEY вместо передачи --key, и он не попадёт в историю вашей оболочки.

wget https://0wx.es/clients/0wx.sh
chmod +x 0wx.sh
export OWX_KEY=YOUR_KEY
./0wx.sh help
./0wx.sh paste --content 'hello & world'
Клиент на Python

0wx.py делает то же, что и shell-клиент, но разбирает ответ и печатает, что означают поля, вместо того чтобы выдавать сырой JSON — добавьте --json, когда нужна сырая форма. Только стандартная библиотека: никакого requests, устанавливать нечего. Если пишете свой клиент, его функции send() и report() — то, что стоит прочитать: вместе они показывают, как собрать запрос, как вытащить сообщение из неудавшегося и что содержат ответы.

wget https://0wx.es/clients/0wx.py
chmod +x 0wx.py
export OWX_KEY=YOUR_KEY
./0wx.py listfiles
./0wx.py listfiles --json | jq '.files[].url'
Клиент на Perl

0wx.pl делает то же, что и клиент на Python, и печатает то же самое. Только базовые модули — HTTP::Tiny и JSON::PP поставляются с Perl начиная с 5.14, так что устанавливать нечего. Стоит читать рядом с клиентом на Python, если пишете свой: два языка по-разному падают на сломанном запросе, и оба скрипта говорят где.

wget https://0wx.es/clients/0wx.pl
chmod +x 0wx.pl
export OWX_KEY=YOUR_KEY
./0wx.pl listfiles
Клиент на PowerShell

0wx.ps1 — аналог клиента на Python для Windows: те же команды, тот же вывод, и он разбирает ответ, а не выдаёт сырой JSON — для сырого добавьте --json. Он написан для Windows PowerShell, который уже есть на машине, так что устанавливать нечего, и без изменений работает на PowerShell 7. В окне, из которого вы его запускаете, может понадобиться Set-ExecutionPolicy -Scope Process Bypass; это Windows спрашивает, действительно ли вы хотите запустить скачанный скрипт — справедливый вопрос, а файл достаточно короток, чтобы сначала прочитать его.

$env:OWX_KEY = 'YOUR_KEY'
.\0wx.ps1 listfiles
.\0wx.ps1 paste --content 'hello & world'
.\0wx.ps1 upload --file .\holiday.jpg --gallery 'Holiday 2026'
Окно в вашем браузере

0wx.html — тот же набор вкладок, что у настольного клиента, в виде трёх файлов — страницы, таблицы стилей и скрипта — без установки, без фреймворка и без загрузки чего-либо откуда-то, кроме этого сайта. Три вместо одного потому, что Content-Security-Policy сайта запрещает встроенные скрипты и стили, и это стоит сохранить. На него можно перетаскивать файлы. Открывать его нужно отсюда, а не сохранять и открывать с диска: API не отправляет заголовки cross-origin, так что у локальной копии браузер отклонил бы каждый запрос ещё до отправки. Ключ держится в памяти, если вы не поставите галочку «запомнить».

https://0wx.es/clients/0wx.html
Окно в Windows

0wx-gui.ps1 — тот же набор вкладок, что у настольного клиента, нарисованный средствами WinForms — то есть устанавливать не нужно вообще ничего, ведь это уже часть Windows. Положите его в одну папку с 0wx.ps1: окно заимствует обработку запросов из того файла, а не носит вторую копию, так что нужны оба. Windows спросит, прежде чем запустить скрипт, который писала не она, и это справедливый вопрос; оба файла достаточно коротки, чтобы прочитать их перед ответом.

powershell -ExecutionPolicy Bypass -File .\0wx-gui.ps1
Окно в Linux с GTK

0wx-gtk.pl — небольшое окно GTK с вкладками для загрузки, вставки, сокращения и просмотра ваших файлов — списком или галереей миниатюр, с фильтром по галерее. Это единственный клиент здесь, которому нужно что-то установить — привязки GTK3 для Perl — что стоит помнить рядом с окном для Windows выше, которому не нужно вообще ничего. Всё остальное, что он использует, поставляется с Perl. Ключ держится только в памяти: закрытие окна его забывает, а установка OWX_KEY заполняет его при запуске. Что бы он ни показывал, сырой ответ сервера в одном клике под “Server reply”.

apt install libgtk3-perl        # or: dnf install perl-Gtk3
wget https://0wx.es/clients/0wx-gtk.pl
chmod +x 0wx-gtk.pl
OWX_KEY=YOUR_KEY ./0wx-gtk.pl
Приложение для Android

0wx-android.apk делает то же, что и другие клиенты, с телефона: загрузка, вставка, сокращение, перевод и просмотр ваших файлов списком или галереей. Поделиться в него файлом из любого другого приложения — значит загрузить его, поделиться текстом — сохранить его как текст. Его нет ни в одном магазине приложений, поэтому устройство спросит, разрешить ли установку — вопрос, к которому вообще стоит относиться серьёзно, и причина, по которой полный исходный код тоже здесь: откройте его в Android Studio и соберите сами, а не доверяйте файлу. Для сборки нужен JDK 21; BUILDING.md внутри объясняет почему.

https://0wx.es/clients/0wx-android.apk        # install it
https://0wx.es/clients/0wx-android.zip        # build it yourself
Примечания

Действия удалённой загрузки намеренно нет. Оно заставило бы сервер получать URL по выбору вызывающего, а это поверхность для подделки запросов, и скрипт способен эксплуатировать её куда жёстче формы. Загрузите файл сами.


(p) 2018 0wx.es -/- Powered by Linux and GNU. Live free or die! (root@0wx.es)