Содержание

To the Un-Known!

Как я переезжал с Known на Hugo

Посетители этого блога могли заметить, что я недавно перенёс его с Known на Hugo. Сделать это, не теряя возможностей IndieWeb было, надо сказать, непросто, так что я решил процесс задокументировать. Надеюсь, мой опыт окажется кому-то полезен, а если и нет, — зачем вообще вести блог, если в нём не хвастаться?

Зачем вообще переезжать?

Я сидел на Known почти пять лет. На самом деле, именно с Known для меня начался IndieWeb; не будь его, я бы, наверно, даже не попытался включиться в IndieWeb в 2015-м. В те далёкие времена, да при наличии hosted-варианта, работа с Known не требовала больше знаний и умений, чем у меня на тот момент было.

К 2020-му году Known так и не оправдал ожиданий «ЖЖ со встроенной беспроблемной интеграцией в IndieWeb». Не хочу сказать ничего плохого о Маркусе Пови и других разработчиках, продолжающих работать над Known все эти годы, огромное им спасибо за эту систему (разработанную в свободное время и бесплатно, кстати), но без hosted-варианта начать с ней работать непросто, а хостить самому полномасштабную CMS ради простого блога — это слегка перебор.

Я бы и дальше пользовался Known. Спину моего верблюда сломал мелкий баг, точнее, не сам баг, а то, что я не мог его исправить сам. Понимаете, я не умею в PHP (хотя много раз пытался его осилить). Мне было понятно, что исправить должно быть несложно, но сам я этого сделать не мог, пришлось ждать, пока у Маркуса найдётся свободное время на этот баг взглянуть. А я, тем временем, даже не мог разобраться, как откатиться на работающую версию! Разумеется, проблема была во мне, а не в PHP и Composer, в которые я никак не могу въехать, но факт остаётся фактом: я и PHP несовместны.

В последнее время я много слышал хорошего о Hugo; окончательно убедил меня его попробовать, наверно, пост Криса Фердинанди, который перенёс свой сайт на Hugo с WordPress. Я на этот пост наткнулся около месяца назад, примерно в то же время, как прочёл хорошую статью про IPFS и стал в ней ковыряться. В итоге было принято решение сделать маленький простенький сайт на IPFS и Hugo, просто чтобы посмотреть, на что это похоже.

В Hugo я немедленно влюбился. В нём оказалось можно разобраться! Потрясающее ощущение всемогущества под пальцами. С Hugo я оказался способен делать разные штуки! Я мог, наконец-то, сделать себе сайт, и он был реально мой. Вопрос переезда на новую платформу оставался только в наличии свободного времени (написал я две недели назад).

Пару дней спустя в России началась борьба с COVID-19 по полной программе. Времени стало сколько угодно.

Подготовка

Known у меня крутился на самом дешёвом shared-хостинге на DreamHost, вместе с RSS-агрегатором и парой других штук. По плану я в конце-концов заменял Known на свой новый сайт, сгенерированный Hugo, но перед этим нужно было вытащить данные из Known. Вообще-то Known умеет экспортировать данные, проблем быть не должно, правда же?

Нет. Слишком долго я жил на Known. Постепенные апгрейды что-то подломали в базе данных; дальше конца 2016 года экспортированная лента RSS не шла. К тому же картинки в ней оказались компрессированные и без оригиналов. Часть ссылок на картинки побились… Многовато всего для правок вручную.

Но первым делом я слепил на поддомене маленький прототип на Hugo (мой план даёт пять поддоменов, задействован был только один, резервы были), забросил туда пару свежих постов вручную, копипастом, и стал выяснять, как всё это сделать IndieWeb-совместимым.

Отправной точкой стала IWC wiki. Я выбрал тему hyde-hyde — в ней встроены несколько простейших штук для IndieWeb, — и начал доработку напильником. Исключительно полезна оказалась статья Амита Гаванде, по которой я разобрался с большинством базовых вещей и уяснил, какие именно данные мне придётся вытаскивать из Known.

В конце концов пришлось написать собственный скрейпер, который просто пробегает по сайту на Known и сохраняет всё, что возможно, в Markdown в Hugo-совместимое дерево директорий, со всеми нужными заголовками и т. д. Он даже сохраняет webmention’ы каждой страницы в JSON. По сути, весь драгоценный контент за годы пользования Known, кроме шести страниц, даже ссылки на которые оказались изуродованы до неузнаваемости каким-то обновлением в 2016 году. Эти 6 страниц я, так уж и быть, сохранил вручную.

Этот же скрейпер заодно создал мне нужные заголовки aliases, чтобы посты были доступны по прежним URL. На URLы картинок я заморачиваться не стал.

Потом — последний пост в Known с объяснением, что старая лента RSS больше обновляться не будет, и со ссылкой на новую. RSS я сохранил в отдельный файл, и настроил редирект на него с адреса, по которому лента висела в Known, через .htaccess.

Всё готово. Можно менять местами симлинк на Known и симлинк на public Hugo.

А как же вебменшены?

Самый большой затык IndieWeb на статическом сайте. Как принимать их? Как посылать?

Входящие вебменшены я решил на своём сайте пока не хранить. Все эти заморочки с GDPR и тому подобным — да ну его. Меня вполне устраивает webmention.io, и API у него в порядке, так что можно делать регулярные бэкапы на случай, если я когда-нибудь передумаю. Что до отображения комментариев на страницах сайта, пока пусть это делает webmention.js — если потом мне разонравится, всё можно заменить и переделать.

Отправка вебменшенов — совсем другое дело, её просто так аутсорсить не выйдет. Нужно, чтобы какой-то софт узнал, что на сайте что-то поменялось. Поиски подходящего инструмента заняли изрядно времени, и похоже, большинство владельцев статических IndieWeb-сайтов либо занимаются отсылкой вебменшенов вручную (вообще не мой вариант), либо поднимают какой-то активный сервис типа lazymention или stapibas, а кто-то вообще задействует особую магию Netlify. На Netlify я переезжать не собирался, Node.JS на моём хостинге надо было ещё поднять, а с Known я уходил совсем не для того, чтобы снова оказаться в обнимку с PHP, так что требовалось другое решение.

В конце концов, насколько это вообще сложно? Допустим, я копирую public, сгенерированный Hugo, во временную директорию, и генерирую новую версию. Всё, что нужно — программа, которая пройдётся по обеим директориям, вычислит, какие страницы новые, какие изменились или удалены, найдёт на этих страницах ссылки и отправит вебменшены. А отправка вебменшенов сама по себе тоже не так сложна, есть симпатичная библиотека на Go, которая именно это и делает буквально в пару вызовов.

Разумеется, в итоге я эту программу сам и написал. Программа делает именно это: сравнивает две директории, находит новые, изменённые и удалённые страницы и рассылает вебменшены по нужным адресам. Заодно она сканирует сайт на предмет изменившихся XML-лент и отправляет WebSub-пинги pings на хаб, где им и место.

Остальное было несложно. С brid.gy я дружу много лет, их же коннектор для Fediverse я открыл для себя только недавно, но работу с ним тоже настроить просто. Предстоит ещё много всего настроить, подчистить и отполировать; я расчитываю в итоге пропихнуть в hyde-hyde свои доработки для IndieWeb, а если их не примут, возможно, сделаю форк, но это всё ещё впереди.

Автоматизируем публикации

Ещё пару слов о том, как у меня на сегодняшний день устроен процесс публикации. Ведение блога должно приносить радость, а для меня делать каждую мелочь вручную раз за разом — это не радость, а как раз наоборот. В идеале всё должно быть просто: написал новый пост или ещё что, нажал на кнопку — и всё произошло само. Собственно, сейчас у меня всё достаточно к этому близко.

Hugo хорошо работает в паре с Git, незачем изобретать велосипеды. Я пишу пост в Markdown-редакторе, сохраняю его в нужное место структуры директорий Hugo, git commit и git push — всё. Git-репозиторий живёт в Gitolite на Raspberry Pi у меня в шкафу, на нём настроен хук, запускающий (по ssh) скрипт на DreamHost. Скрипт что-то вроде такого:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
#!/bin/bash
set -e
cd /home/username/hugo/
git pull --recurse-submodules
mkdir staging
hugo -d staging/public
mkdir old
rsync -am --del public old
ln -s ../../repository/ staging/public/repo
# и другие всякие симлинки для разных штук,
# которые у меня на сайте крутятся
rsync -am --del staging/public ./
static-webmentions
# и потом удаляем лишние директории

Разумеется, этот же самый скрипт запускается и из cron, так что можно было настроить, чтобы этот пост опубликовался после полуночи, а не первого апреля. Но этот блог в принципе можно считать дурацкой затеей, поэтому пусть уж будет.