null

Миграция Thunderbird jabber roster на другой сервер

Пятого октября сего года мир потрясла страшная новость, что Яндекс отключил свои 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+), это делается в пару кликов мышкой. На этом, думаю, миграция окончена.
korg

 

Коротко о себе

Работаю в компании Tune-IT, администрирую инфраструктуру компании и вычислительную сеть кафедры Вычислительной ТехникиСПбНИУ ИТМО.

Интересы: администрирование UNIX и UNIX-like систем и активного сетевого оборудования, написание shell- и perl-скриптов, изучение технологий глобальных сетей.
Люблю собирать GNU/Linux и FreeBSD, использовать тайлинговые оконные менеджеры и писать системный софт.