A migração de dados do Evolution (na atualização) perdeu todas as primeiras "contas" (correio, lista de endereços, calendário ...)

0

Devido a uma falha no sistema, tive que fazer uma nova instalação em um novo computador. Felizmente o meu disco rígido não foi afetado - mas infelizmente o "bom e velho 8.04" não queria arrancar a partir dele no novo sistema ...

Portanto, com o 12.04 instalado em um disco rígido novo, copiei todas as pastas de evolução do disco antigo para os locais correspondentes (~ / .evolution plus ~ / .gconf / apps / evolution - o antigo Evo no 8.04 não tinha ~ / .local / share / evolution) e iniciou o aplicativo. O assistente de migração apareceu e eu passei - mas no final, apenas uma das minhas "contas" em cada categoria foi migrada e disponibilizada: correio local, uma das 4 contas IMAP (embora os dados de todas as 4 contas tenham sido movidos para ~ / .local / share / evolution), um dos quatro livros de endereços e assim por diante.

Não é uma grande coisa para o material IMAP, como eu tinha que configurá-lo (os dados são armazenados no servidor, neste caso). Mas como posso recuperar meus catálogos de endereços? Como descrito acima, iniciar a "instalação antiga" para exportar esses dados não é uma opção, pois o sistema antigo não pode mais ser iniciado. Existe uma maneira de disparar o assistente de migração para um determinado conjunto de dados (no meu caso: dizer para apenas migrar e importar um único catálogo de endereços especificado)?

    
por Izzy 04.06.2012 / 14:57

2 respostas

0

Indo um pouco mais a fundo, eu percebi duas coisas: Enquanto o novo formato de banco de dados é SQLite3, o antigo era algum armazenamento binário que armazena VCARDs, onde claramente legível. Então eu criei um pequeno snippet PHP:

#!/usr/bin/php
<?php
# -=[ UserConf ]=-
$evodb = 'addressbook.db'; // (path and) name to the old address database
$name  = 'business';       // name of the address book (used as filename)
$separate_vcards = FALSE;  // if TRUE, each VCARD will go to a separate file

#-=[ Do not touch below lines ]=-
$re_vcard = '!(BEGIN:VCARD.*?END:VCARD)!ims';

$evo = file_get_contents($evodb);
preg_match_all($re_vcard,$evo,$vcards);
$cards = count($vcards[1]);
$new = '';
for ($i=0;$i<$cards;++$i) {
  if ($separate_vcards) {
    file_put_contents("${name}_${i}.vcf",$vcards[1][$i]);
  } else {
    $new .= $vcards[1][$i] . "\n\n";
  }
}
if (!$separate_vcards) file_put_contents("${name}.vcf",$new);
?>

Isso não é 100% perfeito, mas é melhor do que perder todos esses dados. O script é executado no banco de dados de estilo antigo e tenta buscar todos os VCARDs armazenados nele. Estes são exportados para arquivos separados (cada VCARD em um arquivo, se $ separate_vcards = TRUE), ou para uma coleção (caso contrário).

Como estes devem ser arquivos de texto simples, é possível verificá-los e corrigi-los facilmente (quebras de linha, lixo binário) - e finalmente usar o Evolutions Import-Feature (encontrado no menu "Arquivo") para importar os dados ("arquivo único") em um livro de endereços existente (crie um vazio antes, se você quiser um novo livro de endereços).

Para mim, isso restaurou cerca de 90% dos meus endereços. Para os 10% restantes, alguns onde foram misturados ou quebrados (lembre-se, até mesmo o formato antigo era binário - e o trecho apenas funciona no "modo ASCII").

Espero que isso ajude alguém (se for o caso, não esqueça de votar nessa solução).

    
por Izzy 11.06.2012 / 02:53
1

O PHP acima me iniciou. Mas eu tive problemas com lixo nos cartões.

Eu sou um cara do Python, então escrevi um novo programa em Python. Eu usei o Python 2.x para executar isso.

Isso usa um dicionário Python para rastrear os endereços de e-mail já vistos nos cartões de endereço e armazena apenas um determinado endereço uma vez. Isso resolveu outro problema que tive, de registros de cartões duplicados.

Eu acho que o lixo binário entre as cartas foi usado pelo Evolution para descobrir quais cartas eram válidas. Este programa usa apenas algumas regras básicas: se uma carta tiver caracteres binários de lixo nela, ou não estiver terminada corretamente, ou não tiver um endereço de e-mail nela, ela será uma placa ruim e entrará no estado "ruim". arquivo de saída.

Depois de concluir a conversão, você pode verificar o arquivo de saída "ruim" e ver se há algo lá que não esteja no arquivo de saída .vcf. No meu caso, não havia; este programa tem todas as boas cartas para mim.

#!/usr/bin/python

import re
import sys

def bad_chars():
    for n in range(0, 32):
        if n not in (9, 10, 13):
            yield chr(n)
    for n in range(128, 256):
        yield chr(n)

def has_bad(s):
    return any(ch in s for ch in bad_chars())

def get_email(card):
    lst = card.split('\n')
    for line in lst:
        if "EMAIL" in line:
            _, _, email = line.partition(':')
            return email.strip()
    else:
        return ''

if len(sys.argv) != 4:
    print("Usage: cvt.py <input_old_address_book> <output.vcf> <bad.txt>")
    sys.exit(1)


with open(sys.argv[1], "rb") as in_f:
    s = in_f.read()

s_start = "BEGIN:VCARD"
s_end = "END:VCARD"

cards = {}
lst_bad = []

while s:
    i_start = s.find(s_start)
    if i_start == -1:
        break

    i_next = s.find(s_start, i_start + len(s_start))
    if i_next == -1:
        i_next = len(s) - 1

    i_end = s.find(s_end, i_start + len(s_start))
    if i_end == -1:
        i_end = len(s) - 1
    else:
        i_end += len(s_end)

    if i_next < i_end:
        i_end = i_next

    card = s[i_start:i_end+1].strip()
    s = s[i_end:]

    card = card.replace('\r', '')
    card = card.replace('
#!/usr/bin/python

import re
import sys

def bad_chars():
    for n in range(0, 32):
        if n not in (9, 10, 13):
            yield chr(n)
    for n in range(128, 256):
        yield chr(n)

def has_bad(s):
    return any(ch in s for ch in bad_chars())

def get_email(card):
    lst = card.split('\n')
    for line in lst:
        if "EMAIL" in line:
            _, _, email = line.partition(':')
            return email.strip()
    else:
        return ''

if len(sys.argv) != 4:
    print("Usage: cvt.py <input_old_address_book> <output.vcf> <bad.txt>")
    sys.exit(1)


with open(sys.argv[1], "rb") as in_f:
    s = in_f.read()

s_start = "BEGIN:VCARD"
s_end = "END:VCARD"

cards = {}
lst_bad = []

while s:
    i_start = s.find(s_start)
    if i_start == -1:
        break

    i_next = s.find(s_start, i_start + len(s_start))
    if i_next == -1:
        i_next = len(s) - 1

    i_end = s.find(s_end, i_start + len(s_start))
    if i_end == -1:
        i_end = len(s) - 1
    else:
        i_end += len(s_end)

    if i_next < i_end:
        i_end = i_next

    card = s[i_start:i_end+1].strip()
    s = s[i_end:]

    card = card.replace('\r', '')
    card = card.replace('%pre%', '')
    if not card:
        continue

    key = get_email(card)
    if has_bad(card) or s_end not in card or not key:
        lst_bad.append(card)
        continue

    if key not in cards or len(card) > len(cards[key]):
        cards[key] = card

with open(sys.argv[2], "w") as out_f:
    for key in sorted(cards.keys()):
        out_f.write(cards[key] + "\n\n")

with open(sys.argv[3], "w") as bad_f:
    for s in lst_bad:
        bad_f.write(s + "\n\n")
', '') if not card: continue key = get_email(card) if has_bad(card) or s_end not in card or not key: lst_bad.append(card) continue if key not in cards or len(card) > len(cards[key]): cards[key] = card with open(sys.argv[2], "w") as out_f: for key in sorted(cards.keys()): out_f.write(cards[key] + "\n\n") with open(sys.argv[3], "w") as bad_f: for s in lst_bad: bad_f.write(s + "\n\n")
    
por steveha 07.07.2013 / 08:26