Dans le cadre des activités admin sys de l’April, je suis parfois amené à changer les logiciels, et donc à convertir les données d’un logiciel vers un autre. Ici, il s’agissait de passer de dotproject à OwnCloud. Dotproject ne fournit pas d’interface pour exporter les événements, je suis donc allé les chercher dans la base de données pour les sortir en csv.

select event_title, event_start_date, event_end_date, event_description from events
  into outfile event.csv
  fields terminated by ',' 
  enclosed by '"'
  escaped by '\\' 
  lines terminated by '\n' ;

À ce stade là, l’entrée ne correspond pas encore tout à fait pour deux raisons : certains ” sont mal échappés et ne permettent pas une lecture correcte des champs CSV. Nous pouvons donc remédier à ça avec sed -i.bak 's/\\"/«/g' events.csv qu’on oublira pas de convertir en utf-8 avec iconv -f latin1 -t utf-8.

Pour finir, voici une moulinette python qui permet de transformer ce CSV en iCal :

import csv
from icalendar import Calendar, Event, LocalTimezone
from datetime import datetime, timedelta
from random import randint
import sys
#from __future__ import print_function

reader_builder = list(csv.DictReader(open('events.csv', 'Ub'), skipinitialspace = True))

headers = reader_builder[0].keys()

# Start calendar file
cal = Calendar()
cal.add('prodid', 'dotproject.april.org')
cal.add('version', '2.0')

reader = reader_builder

rownum = 0

try:
    for row in reader:
        event = Event()
        event.add('summary', row['event_title'])
        event.add('dtstart', datetime.strptime(row['event_start_date'],'%Y-%m-%d %H:%M:%S'))
                #.strftime('%Y%m%dT%H%M%SZ'))
        event.add('dtend', datetime.strptime(row['event_end_date'],'%Y-%m-%d %H:%M:%S'))
        event.add('description',row['event_description'])
        event['uid'] = str(randint(1,10**30)) + datetime.now().strftime('%Y%m%dT%H%M%S') + '___dotproject.april.org'

        cal.add_component(event)
        rownum += 1

except Exception, e:
    if rownum > 0:
        print('I had a problem with an event. I think I might have gotten through about {0} events and had trouble with an event with subject: {1} . Sorry!'.format(rownum, row['event_title']))
    else:
        print("N'arrivera pas")
    #sys.exit(2)

f = open('./dotp_events.ics','wb')
f.write(cal.to_ical())
f.close()

Attention, pas mla de choses sont traitées de façon rudimentaires. En particulier, il faut finir avec un sed -i.bak s/;VALUE=DATE-TIME// dotp_events.ics.

Et voilà !