Corruzioni all'interno del calendario: duplicati. Come analizzare la loro causa e risolvere?

1

Sto utilizzando Calendar su un Mac con MacOS X Mountain Lion (10.8.5).

Questo Mac viene regolarmente sincronizzato manualmente con un iPhone con iOS 7.1.2.

Questo Calendar memorizza 15 anni di eventi organizzati in 9 "calendari". Poiché alcune di queste informazioni sono altamente sensibili, professionali o private, non le sincronizzo su nessuna forma di calendario di un negozio pubblico ( iCloud , Google Calendar ...). D'altra parte ho molti% backup di% di backup e backup completi.

Recentemente ho scoperto in modo inaspettato che dall'estate 2001 ho duplicato gli eventi dell'intera giornata in Time Machine sul mio Mac. Sono stato in grado di vederli rapidamente poiché la loro duplice natura è direttamente visibile. Questo non è un caso generale: la maggior parte dei miei eventi di un giorno intero non lo sono duplicato. Ma tutti i miei 9 "calendari" sono colpiti da questo corruzione . Immagino di avere circa un centinaio di eventi in questo caso. Vedo la stessa corruzione sul mio iPhone.

Ho esportato uno dei miei calendari e ho estratto una delle voci duplicate. Ecco l'output di un diff sugli estratti del 2% diCalendar:
••My_Mac••$ diff duplicate.[12].ics
2c2
< UID:74FC7CC1-016C-4A74-9E02-7ECDD82C8129
---
> UID:9B6BC4CD-5859-4DC2-8DEA-9158CB8F9B0D
10,11c10,11
< X-WR-ALARMUID:D0FE4A14-981C-4409-84C1-B11107F7EC31
< UID:D0FE4A14-981C-4409-84C1-B11107F7EC31
---
> X-WR-ALARMUID:48141767-C3C6-4131-9984-0DD080833D9F
> UID:48141767-C3C6-4131-9984-0DD080833D9F
••My_Mac••$

Notazione: la stringa .ics nome •• significa che "nome" è stato redatto.

Ecco cosa ho trovato in •• e che potrebbe essere correlato:

Sep 13 10:08:32 ••My_Mac•• SyncServer[93677]: [0x7fbe60c0bdd0] |SyncServer|Warning| Refreshing watchdog because of a calendar time change alert.
Sep 13 16:09:10 ••My_Mac•• SyncServer[94189]: [0x7fd25a40bdd0] |SyncServer|Warning| Refreshing watchdog because of a calendar time change alert.
Sep 14 03:21:15 ••My_Mac•• SyncServer[94351]: [0x7f9e1ac0bdd0] |SyncServer|Warning| Refreshing watchdog because of a calendar time change alert.
Sep 14 08:56:41 ••My_Mac•• SyncServer[94351]: [0x7f9e1ac0bdd0] |SyncServer|Warning| Refreshing watchdog because of a calendar time change alert.
Sep 15 14:11:39 ••My_Mac•• SyncServer[94351]: [0x7f9e1ac0bdd0] |SyncServer|Warning| Refreshing watchdog because of a calendar time change alert.
Sep 16 00:25:17 ••My_Mac•• SyncServer[95764]: [0x7faf92c0bdd0] |SyncServer|Warning| Refreshing watchdog because of a calendar time change alert.
Sep 16 13:36:27 ••My_Mac•• SyncServer[96213]: [0x7f9470c0bdd0] |SyncServer|Warning| Refreshing watchdog because of a calendar time change alert.
Sep 16 13:51:33 ••My_Mac•• CalendarAgent[90827]: Invalid char _ for PropertyName in line 7
Sep 16 13:51:33 ••My_Mac•• CalendarAgent[90827]: Unexpected EOF, returning last token as fallback

Come posso analizzare da dove vengono questi eventi duplicati?

Come posso trovare la data e l'ora in cui un evento potrebbe aver avviato una tale corruzione dei miei ordini del giorno? Senza una data di inizio del danno, i miei backup sono di scarso aiuto. Inoltre, implicheranno una ricostruzione totale degli eventi corretti che si sono verificati dopo il danno .

Come posso ottenere una visione corretta di questa corruzione di tutti i miei "calendari"?

E inoltre, come posso risolvere questo enorme e apparentemente casuale danneggiamento dei dati ?

    
posta daniel Azuelos 16.09.2015 - 16:46
fonte

1 risposta

0

Non ho ancora una spiegazione corretta di queste corruzioni, ma almeno ho scritto una soluzione per avere una visione chiara dell'entità del danno e per risolverlo.

Ecco uno script perl: duplicate.pl :

$ cat <<'eof' >duplicate.pl
#!/usr/bin/perl
use strict ;
use warnings ;

# program reading on its standard input a file under
# ics format exported by iCal or Calendar
# Both only export one calendar at a time

# file = name of created file for a given calendar

my %file = () ;

# filedesc = file descriptor of the created calendar file

my %filedesc = () ;

# hash of all unduplicated events local_event_id
my %events = () ;

# current event storage
my @event = () ;
my $dtstart = '' ;
my $dtend = '' ;

# number of events analysed
my $num_event = 0 ;
my $duplicate = 0 ;
my $calendar = '' ;

# state booleans
my $in_header = 1 ;
my $in_event = 0 ;
my $in_summary = 0 ;
my $line = '' ;
my $summary = '' ;

# local event identifier :      summary;dtstart;dtend
# because ';' is never used within a name
my $local_event_id = '' ;

while (<STDIN>) {
        $line = $_ ;

# header :      BEGIN:VCALENDAR
#               ...
#               BEGIN:VEVENT

        if ( $in_summary ) {

#               continuation line of summary

                if ( $line =~ /^ (.+)\r\n$/ ) {
                        $summary .= $1 ;
                } else {

#                       end of summary continuation lines analysis

                        $in_summary = 0 ;
                }
        }
        if ( $line =~ /^SUMMARY[^:]*:(.+)\r\n$/ ) {
                $summary = $1 ;
                $in_summary = 1 ;
        } elsif ( $line =~ /^BEGIN:VEVENT/) {
                if ( $in_header ) {
                        $in_header = 0 ;

#                       print every lines of event or header

                        foreach $line (@event) {
                                printf {$filedesc{$calendar}} "%s", $line ;
                        }
                }
                $in_event = 1 ;
                @event = () ;
        } elsif ( $line =~ /^X-WR-CALNAME:(.+)\r\n$/) {
                $calendar = $1 ;

#               create .ics file

                if ( ! defined $file{$calendar} ) {
                        $file{$calendar} = $calendar . ".ics" ;
                        if ( -e $file{$calendar} ) {
                                die "$file{$calendar} already exists\n" ;
                        }
                        open ($filedesc{$calendar}, ">", $file{$calendar}) ;

#                       print every lines of header

                        foreach $line (@event) {
                                printf {$filedesc{$calendar}} "%s", $line ;
                        }
                        @event = () ;
                        $in_event = 0 ;
                }
#               printf STDOUT "calendar = %s\n", $calendar ;
#               printf STDOUT "file = %s\n", $file{$calendar} ;
#               printf STDOUT "fh = %d\n", $filedesc{$calendar} ;

        } elsif ( $line =~ /^DTSTART[^:]*:(.*)\r\n$/ ) {
                $dtstart = $1 ;

#               printf STDOUT "DTSTART = %32s\n", $dtstart ;

        } elsif ( $line =~ /^DTEND[^:]*:(.*)\r\n$/ ) {
                $dtend = $1 ;

#               printf STDOUT "DTEND = %32s\n", $dtend ;

        } elsif ( $line =~ /^END:VEVENT/ ) {

# it's only on closing an event definition that we have
# a complete local event identifier

                $local_event_id = "$summary" . ";" . "$dtstart" . ";" . "$dtend" ;


                if ( defined ( $events{"$local_event_id"} )) {

#                       duplicate event

                        printf STDOUT "\n\tduplicate\t%s\n", $local_event_id ;

#                       free event storage

                        @event = () ;
                        $in_event = 0 ;
                        $duplicate++ ;
                } else {

#                       new event
                        $events{$local_event_id} = 1;

                        if ($in_event) {

#                               print every lines of stored event

                                foreach $line (@event) {
                                        printf {$filedesc{$calendar}} "%s", $line ;
                                }
                                @event = () ;
                                $in_event = 0 ;
                                $num_event++ ;
                                $in_header = 1 ;

#                               show progress
                                if (($num_event % 100) == 0) {
                                        printf STDOUT "\n%8d", $num_event ;
                                } else {
                                        print STDOUT "." ;
                                }
                        }
                }
        } elsif ( $in_event == 0 ) {
                $in_header = 1 ;
        }

#       store every line of event or header

        if ($in_event || $in_header) {
                push (@event, $line) ;
        }

}

printf STDOUT "\nevents:%12d\n", $num_event ;
printf STDOUT "duplicates:%8d\n", $duplicate ;

#                       print every lines of ending

                        foreach $line (@event) {
                                printf {$filedesc{$calendar}} "%s", $line ;
                        }

close ($filedesc{$calendar}) ;
exit 0 ;
eof
$ chmod u+x duplicate.pl

Ed ecco come l'ho usato:

  1. Da Calendar , esporta un dato calendario tramite:

    File > Export > Export...

    diciamo che è: Documents/Calendar/2015/professionnal.ics

    NB .: questo sarà un backup in caso di problema, e molto più pratico di qualsiasi manipolazione di file con l'aiuto di Time Machine

  2. Installa lo script precedente come:

    ~/Documents/Calendar/src/duplicate.pl
    
  3. Vai nella directory per verificare la versione fissa, ad esempio:

    mkdir ~/Documents/Calendar/2015.fixed
    cd ~/Documents/Calendar/2015.fixed
    
  4. Esegui duplicate.pl :

    ../src/duplicate.pl <../2015/professionnal.ics
    

    che mostra il numero di eventi letti e il numero di duplicati trovati e crea qui una versione fissa del calendario:

    ~/Documents/Calendar/2015.fixed/professionnal.ics
    
  5. Confronta il risultato con la versione originale danneggiata per verificare che tutto sia OK:

     diff ../2015/professionnal.ics .
    
  6. Entro Calendar seleziona il calendario professionnal ed eliminalo attraverso:

    Edit > Delete

  7. Importa quello fisso tramite:

    File > Import > Import...

risposta data 22.09.2015 - 02:20
fonte

Leggi altre domande sui tag