Zenway

Linux - это интересно!

Вы не вошли.

#1 31-10-2012 17:37:22

vovans
Администратор
Откуда: Ростов-на-Дону
Здесь с 19-10-2010
Сообщений: 461
Сайт
LinuxSeaMonkey 2.13

Импорт базы пользователей из Openfire в Ejabberd

Так как Openfire окончательно загнулся, судя по всему, и куча багов уже много лет не фиксится, решил попробовать перевести рабочий jabber на Ejabberd. Но пользователей было лень руками перетаскивать.

Есть плагин openfire-export в модулях у Ejabberd. Отлично. Только там исходники. И ни слова, как его собирать. И собранного модуля в инете не нашёл. По имени файла гугл выдаёт всего 2 страницы в поиске. В общем, удалось-таки разобраться с компилияцией и openfireExporter.jar я получил, установил, экспортировал. Но импортировать это добро в Ejabberd не удалось. Куча ошибок. Наверно, давно формат требуемого xml-файла давно изменился. Как бы там ни было, нужно что-то делать. Гуглением нашёл заметку на сайте Ejabberd, где фигурирует openfire-jabberd-convertor.jar smile

И да, выполнив сие:

$ java -jar openfire-jabberd-convertor.jar users.xml /tmp/jusers/ my.domen.org

и получил-таки директорию с выгрузкой, аналогичной таковой из jabberd14. Теперь заходим в админку - Узлы => Работающие узлы => Резервное копирование => Импорт пользовательских данных из буферной директории jabberd 1.4. Указываем нашу директорию и ждём окончания процесса smile

Жаль, не переносятся группы (shared roster), но всё равно так проще, чем всё руками переносить.

Да, есть ещё скрипт на пёрле для перенесения пользователей из users.xml (экспорт из Openfire) сразу в БД (mysql) Ejabberd:

Скрытый текст
#!/usr/bin/perl -w
#
# Convert a Openfire user export file to a ejabberd mysql user database
#
# See http://www.igniterealtime.org/projects/openfire/plugins/userimportexport/readme.html
# for spec of XML User export format
#
# Licensed in the same terms as perl
#
# Author: Pedro Melo <melo@simplicidade.org>
# Date: 2007/09/20
# Version: 1.0
#

use strict;
use DBI;
use XML::LibXML;
use XML::LibXML::XPathContext;
use Getopt::Long;

# FIXME: not all state are covered yet
my %states = (
  '3 -1 -1' => [ 'B', 'N', 'N' ],
  '2 0 -1' => [ 'F', 'O', 'N' ],
  '2 -1 -1' => [ 'F', 'N', 'N' ],
  '1 -1 -1' => [ 'T', 'N', 'N' ],
  '0 -1 -1' => [ 'N', 'N', 'N' ],
  '0 0 -1' => [ 'N', 'O', 'N' ],
  '0 -1 2' => [ 'N', 'I', 'N' ],
);

my $db;
my $host = 'localhost';
my $user;
my $pass;

my $ok = GetOptions(
  "database=s" => \$db,
  "host=s"     => \$host,
  "user=s"     => \$user,
  "password=s" => \$pass,
);
my $user_file = $ARGV[0];

if (!$ok || !$user_file) {
  print STDERR "Usage: x-convert-openfire-to-ejabberd OPTIONS FILE\n\n";
  print STDERR "Use the OPTIONS to select the destination MySQL database,\n";
  print STDERR "and use your Openfire user export file as the final parameter.\n\n";
  print STDERR "Valid options are:\n";
  print STDERR "    --host: hostname of the MySQL server (default: localhost)\n";
  print STDERR "    --database: database to use in the MySQL server\n";
  print STDERR "    --user: authenticate as\n";
  print STDERR "    --password: authenticate with\n";
  print STDERR "\n";
  exit(1);
}

# Connect to database
my $dbh = DBI->connect(
  "dbi:mysql:database=$db;host=$host",
  $user,
  $pass,
  {
    AutoCommit => 0,
    RaiseError => 1,
    PrintError => 1,
  }
);
if (!$dbh) {
  print STDERR "FATAL: could not connect to the database: $DBI::errstr\n";
  exit(1);
}
$dbh->do(q{SET NAMES 'utf8'});

# Parse the XML file
my $parser = XML::LibXML->new;
my $doc = $parser->parse_file($user_file);
my $xp = XML::LibXML::XPathContext->new($doc);

# Scan for users
foreach my $user ($xp->findnodes('/Openfire/User')) {
  # fetch login and password
  my $login = $xp->findvalue('Username', $user);
  my $passw = $xp->findvalue('Password', $user);
  $dbh->do(q{
    INSERT INTO users (username, password) VALUES (?, ?)
  }, undef, $login, $passw);
  
  # fetch some vcard fields: email, and name
  my $email = exml($xp->findvalue('Email', $user) || '');
  my $name  = exml($xp->findvalue('Name', $user)  || '');
  my $nick  = exml($login);
  my $vcard = q{<vCard xmlns='vcard-temp' version='2.0' prodid='-//HandGen//NONSGML vGen v1.0//EN'>};
  $vcard .= qq{<FN>$name</FN>} if $name;
  $vcard .= qq{<EMAIL><INTERNET/><USERID>$email</USERID></EMAIL>} if $email;
  $vcard .= qq{<NICKNAME>$nick</NICKNAME>};
  $vcard .= q{</vCard>};
  $dbh->do(q{
    INSERT INTO vcard (username, vcard) VALUES (?, ?)
  }, undef, $login, $vcard);
  
  # fetch and insert roster items, including groups
  foreach my $item ($xp->findnodes('Roster/Item', $user)) {
    my $r_jid  = $item->getAttribute('jid');
    my $r_name = $item->getAttribute('name') || '';
    my $r_ask  = $item->getAttribute('askstatus');
    my $r_recv = $item->getAttribute('recvstatus');
    my $r_sub  = $item->getAttribute('substatus');

    my $key = "$r_sub $r_ask $r_recv";
    if (!exists $states{$key}) {
      die "State combination '$key' not found in valid state table\n";
      exit(1);
    }

    my ($sub, $ask, $server) = @{$states{$key}};
    
    $dbh->do(q{
      INSERT INTO rosterusers (username, jid, nick, subscription, ask, server, type,   askmessage, subscribe   )
                       VALUES (?,        ?,   ?,    ?,            ?,   ?,      'item', '',         '' )
    }, undef, $login, $r_jid, $r_name, $sub, $ask, $server);
    
    # deal with groups also
    foreach my $group ($xp->findnodes('Group', $item)) {
      $group = $group->textContent;
      next unless $group;

      $dbh->do(q{
        INSERT INTO rostergroups ( username, jid, grp )
                          VALUES ( ?,        ?,   ?   )
      }, undef, $login, $r_jid, $group);
    }
  }
  
  $dbh->commit;
 # print "User: $login   Passw: $passw   Name: $name  Email: $email\n";
}

$dbh->disconnect;


sub exml {
  # fast path for the commmon case:
  return $_[0] unless $_[0] =~ /[&\"\'<>]/;
  
  my $x = shift;
  for ($x) {
    s/\&/&amp;/g;
    s/\"/&quot;/g;
    s/\'/&apos;/g;
    s/</&lt;/g;
    s/>/&gt;/g;
  }
  return $x;
}

С ним у меня тоже всё получилось.

Кроме того, есть свежая заметка на хабре, как хранить всё необходимое во внешней БД (mysql, н-р). Я себе так и сделал. Странно, что указывая все настройки внешней базы данных почти все данные всё равно хранятся во внутренней по умолчанию sad


zenway admin

Вне форума

Сейчас в этой теме пользователей: 0, гостей: 1
[Bot] CCBot

Подвал форума

Под управлением FluxBB
Модифицировал Visman

[ Сгенерировано за 0.007 сек, 7 запросов выполнено - Использовано памяти: 496.16 Кбайт (Пик: 580.83 Кбайт) ]