1 votos

Corrupciones en el Calendario: duplicados. ¿Cómo analizar su causa y solucionarlo?

Estoy usando Calendar en un Mac con MacOS X Mountain Lion (10.8.5).

Este Mac se sincroniza regularmente de forma manual con un iPhone con iOS 7.1.2.

Este Calendar almacena 15 años de eventos organizados en 9 "calendarios". Como parte de esta información es altamente sensible, profesional o privada, no la sincronizo en ningún tipo de calendario de tienda pública ( iCloud , Google Calendar ). Por otra parte, tengo muchos Time Machine copias de seguridad y copias de seguridad completas.

Hace poco descubrí, de forma bastante inesperada, que desde el verano de 2001 he duplicado eventos de un día completo dentro de Calendar en mi Mac. He podido verlos rápidamente ya que su naturaleza duplicada es directamente visible. Este no es un caso general: la mayoría de mis eventos de día completo no están duplicados. Pero todos mis 9 "calendarios" están afectados por esto corrupción . Estimo que tengo unos cientos de eventos en este caso. Veo la misma corrupción en mi iPhone.


Exporté uno de mis calendarios y extraje una de las entradas duplicadas. Aquí está la salida de un diff en el 2 .ics extractos:

••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••$

Notación: la cadena •• nombre •• significa que el "nombre" fue redactado.

Esto es lo que he encontrado dentro /var/log/system.log y que podrían estar relacionados:

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

¿Cómo puedo analizar de dónde provienen estos eventos duplicados?

¿Cómo puedo encontrar la fecha y la hora en que un evento podría haber comenzado tal corrupción de mis agendas? Sin una fecha de inicio del daño, mis copias de seguridad son de poca ayuda. Además, implicarán una reconstrucción total de los eventos correctos que ocurrieron después de el daños .

¿Cómo puedo obtener una visión correcta de esta corrupción de todos mis "calendarios"?

Y además, ¿cómo puedo arreglar esta enorme y aparentemente aleatoria corrupción de datos ?

0voto

Rich Puntos 2429

Todavía no tengo una explicación correcta de estas corrupciones, pero al menos escribí una solución para tener una visión clara del alcance del daño y arreglarlo.

Aquí hay un perl script: 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

Y esta es la forma en que lo usé:

  1. Desde Calendar exportar un determinado calendario a través de:

    File > Export > Export...

    digamos que sí: Documents/Calendar/2015/professionnal.ics

    Nota: esto será una copia de seguridad en caso de problema, y mucho más práctico que cualquier manipulación de archivos con la ayuda de Time Machine

  2. Instala el anterior script como:

    ~/Documents/Calendar/src/duplicate.pl
  3. Entra en el directorio para probar la versión fija, por ejemplo:

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

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

    que mostrará el número de eventos leídos y el número de duplicados encontrados y creará aquí una versión fija del calendario:

    ~/Documents/Calendar/2015.fixed/professionnal.ics
  5. Compare el resultado con la versión original corrupta para comprobar que todo está bien:

     diff ../2015/professionnal.ics .
  6. En Calendar seleccione el calendario professionnal y borrarlo a través de:

    Edit > Delete

  7. Importa el fijo a través de:

    File > Import > Import...

AppleAyuda.com

AppleAyuda es una comunidad de usuarios de los productos de Apple en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X