Пятого октября сего года мир потрясла страшная новость, что Яндекс отключил свои xmpp серверы. Причем, примерно за месяц до этого события я обращался в техническую поддержку с просьбой выгрузить ростер и историю в любом удобном для них формате. На что в ответ получил следующее письмо.
К сожалению, такой возможности нет, т.к. мы не хранили историю переписки с момента официального закрытия Я.Онлайн.
Спасибо за то, что пользуетесь нашими сервисами!
--
С уважением, Алёна Суворова
Служба поддержки Яндекса
https://yandex.ru/support
Переносить ростер руками ну уж совсем не хотелось, как и историю сообщений. Поэтому за ответами я пошёл к jabber-клиенту.
Так уж сложилось, что стандартом de facto для jabber клиентов за последнее время у меня является кнопка "Chat" в Mozilla Thunderbird.
Поэтому, для ленивых, могу предложить следующий вариант получения ростера.
Переходим в %APPDATA%\Thunderbird\Profiles и заходим в используемый профиль.
Далее можно выполнить "dir /b logs\jabber\имя_аккаунта
".
Очевидно, если с контактом не было переписки, jid мы не увидим. Это первое "НО".
Окей, список jid-ов получили. Но вручную создавать их в новом аккаунте совсем не хочется. Это второе "НО".
Поэтому пойдём чуть более правильным путём. Есть в том же каталоге профиля файл с именем "blist.sqlite".
Я написал простенький почти интерактивный скрипт, который получает все jid-ы и nick-и из этой базы.
Сразу забегая вперёд, у меня есть хорошая новость! В Thunderbird реализована поддержка групп (shared groups) в ростере.
Реализована, но не работает :) Список групп можно получить нехитрым образом из того же файла, но нигде нет соответствия пользователей этим группам. Хоть и есть предусмотренная табличка.
Рассмотрим скрипт для выгрузки подробнее.
#!/bin/sh -e
USAGE="$0 blist.sqlite [account]"
[ -z "$1" ] && echo "$USAGE" >&2 && exit 1
ACCS=`sqlite3 "$1" "select name from accounts where prpl like 'prpl-jabber';"`
[ -z "$2" ] && echo "Please use '$0 <account>' with one of accounts:" $ACCS >&2 && exit 2
sqlite3 "$1" "
select name||'@'||srv_alias from buddies where id in (
select buddy_id from account_buddy where account_id in (
select id from accounts where name like '$2'
));"
Первый аргумент -- путь к файлу blist.sqlite, второй -- аккаунт, для которого мы хотим получить. В результате его выполнения без аргументов, выводится USAGE; если введён только путь к файлу, выводится список возможных аккаунтов. В случае, когда введены оба аргумента, скрипт формирует вывод в формате "пользователь@домен@ник".
root@zhmylove.ru@Adun
admin@jabber.ru@Tassadar
korg@rambler.ru@Zeratul
admin@gmail.com@Artanis
user_without_nickname@contoso.com@
Собственно, если у вас возникает потребность сделать подобную выгрузку из других клиентов, формат простой и, как мы дальше увидим, легко импортируем. Впрочем, если пользователей мало, можно и вручную их создать. Но если их тысячи, то можно воспользоваться следующим простеньким скриптом на perl, имеющим одну зависимость -- Net::XMPP.
#!/usr/bin/perl
# made by: KorG
use strict;
use v5.18;
use warnings;
use utf8;
my $SERVER = 'unix.com';
my $USER = 'root';
my $PASSWORD = 'love';
use Net::XMPP qw( Client );
(my $sock = new Net::XMPP::Client())->Connect(hostname => $SERVER);
exit 2 unless $sock->Connected();
exit 3 if "ok" ne (
$sock->AuthSend(username => $USER, password => $PASSWORD, resource => "pl")
)[0];
while(<>) {
utf8::decode($_);
chomp;
my @rec = split "@";
next unless defined $rec[1];
my $jid = join "@", @rec[0,1];
my $name = defined $rec[2] ? $rec[2] : $jid;
$sock->Subscription(type => "subscribe", to => $jid);
$sock->Subscription(type => "subscribed", to => $jid);
$sock->RosterAdd(jid => $jid, name => $name);
}
Интересующие пользователя параметры расположены в верхней части скрипта -- это переменные SERVER, USER и PASSWORD. Собственно, из наваний понятно их назначение. Скрипт из stdin, либо из файла, переданного в качестве первого аругмента, читает список в рассмотренном ранее формате и добавляет пользователей в наш ростер, разрешая им подписку и сразу отправляя им запрос на подписку.
В первом приближении можно выполнить команду "./script1 /path/to/blist.sqlite old@server.ru | ./script2.pl ;echo $?
".
Если код возврата равен нулю, всё выполнено успешно. Если же код возврата отличен от нуля, у второго скрипта возникли проблемы с аутентификацией на jabber сервере.
Далее можно удалить старый аккаунт, тем самым "почистив" список пользователей, привязанных к нему. Группы, увы, придется настроить руками. Но если воспользоваться нормальным клиентом (типа psi+), это делается в пару кликов мышкой. На этом, думаю, миграция окончена.