Transmogrifier: Migrating to Plone with less pain

33
Transmogrifier Lennart Regebro Plone Conference 2009, Budapest

description

Transmogrifier is a migration framework written by Martijn Pieters, Jarn, that makes migrating to Plone fun again. This talk gives an introduction to Transmogrifier, an explanation of how it works and some hints for usage.

Transcript of Transmogrifier: Migrating to Plone with less pain

Page 1: Transmogrifier: Migrating to Plone with less pain

Transmogrifier

Lennart Regebro

Plone Conference 2009, Budapest

Page 2: Transmogrifier: Migrating to Plone with less pain

collective.transmogrifier

Created by Martijn Pieters, Jarn

in 2008

Released inversion 1.0

August 2009

Page 3: Transmogrifier: Migrating to Plone with less pain

collective.transmogrifier

Import/migration framework

Both from Plone 2 and from other websites or data

Page 4: Transmogrifier: Migrating to Plone with less pain

Super-simple architecture

You set up a pipeline of sections

Each section send items to the next

section.

Sections do something with the

items (or not)

Page 5: Transmogrifier: Migrating to Plone with less pain

What are you talking about?

Page 6: Transmogrifier: Migrating to Plone with less pain

A simple example

1. A section that reads a CSV file with a list of events and creates items based on that data

2. A section that will generate some plone-specific data for each item, like path and type.

3. A section that creates the Plone event4. A section that updates the Archetypes fields5. A section that publishes the event

Page 7: Transmogrifier: Migrating to Plone with less pain

The CSV file

title,startDate,endDatePlone Conference,2009-10-28 09:00,2009-10-30 18:00Christmas,2009-12-24 00:00,2009-12-26:23:59

Page 8: Transmogrifier: Migrating to Plone with less pain

Setting it up

1. Define a pipeline in a .cfg file

2. Register it as a name in ZCML

3. Call Transmogrifier from Python

Page 9: Transmogrifier: Migrating to Plone with less pain

The configuration file[transmogrifier]pipeline = section1 section2

[section1]blueprint = name.of.the.blueprintsize = 5

[section2]blueprint = another.blueprint

Page 10: Transmogrifier: Migrating to Plone with less pain

ZCML

<configure xmlns:transmogrifier= "http://namespaces.plone.org/transmogrifier"> <transmogrifier:registerConfig name="Zap event import" title="Import of events" description="" configuration="transmogrifier.cfg" />

</configure>

Page 11: Transmogrifier: Migrating to Plone with less pain

setuphandlers.py

from collective.transmogrifier.transmogrifier import \ Transmogrifier

def setupVarious(context):

if context.readDataFile('zap_various.txt') is None: return

transmogrifier = Transmogrifier(context.getSite()) transmogrifier('Zap event import')

Page 12: Transmogrifier: Migrating to Plone with less pain

What is a generator

def my_generator(): i = 1 while i < 1000: yield i i = i * 2

for x in my_generator(): print x

Page 13: Transmogrifier: Migrating to Plone with less pain

Never ending story

def my_generator(): i = 1 while True: yield i i = i * 2

for x in my_generator(): print x

Page 14: Transmogrifier: Migrating to Plone with less pain

EventSource

class EventSource(object): def __iter__(self): for event is csv.DictReader(open(self.options['csvfile'])) yield event

for item in self.previous: yield item

Page 15: Transmogrifier: Migrating to Plone with less pain

EventSource

class EventSource(object): def __iter__(self): for event is csv.DictReader(open(self.options['csvfile'])) yield event

for item in self.previous: yield item

Page 16: Transmogrifier: Migrating to Plone with less pain

EventSource

class EventSource(object): def __iter__(self): for event is csv.DictReader(open(self.options['csvfile'])) yield event

for item in self.previous: yield item

Page 17: Transmogrifier: Migrating to Plone with less pain

The item

{ 'title': 'Plone Conference', 'startDate': '2009-10-27 09:00', 'endDate': '2009-10-30 18:00',}

Page 18: Transmogrifier: Migrating to Plone with less pain

EventUpdater

class EventUpdater(object): def __iter__(self): for item in self.previous: id = item['title'].lower().replace(' ', '-') item['_path'] = '/events/'+id item['_type'] = 'Event' item['_transitions'] = ('publish',) yield item

Page 19: Transmogrifier: Migrating to Plone with less pain

The item

{ '_type': 'Event', '_path': '/events/plone-conference', '_transitions': ('publish,), 'title': 'Plone Conference', 'startDate': '2009-10-27 09:00', 'endDate': '2009-10-30 18:00',}

Page 20: Transmogrifier: Migrating to Plone with less pain

Registering the section

<utility component=".eventsource.EventSource" name="zap.eventsource" />

<utility component=".eventsource.EventUpdater" name="zap.eventupdater" />

Page 21: Transmogrifier: Migrating to Plone with less pain

The configuration file[transmogrifier]pipeline = eventsource eventupdater

[eventsource]blueprint = zap.eventsourcecsvfile = /path/to/events.csv

[eventupdater]blueprint = zap.eventupdater

Page 22: Transmogrifier: Migrating to Plone with less pain

The configuration file cont.

[constructor]blueprint = collective.transmogrifier.sections.constructor

[schemaupdater]blueprint = plone.app.transmogrifier.atschemaupdater

[workflow]blueprint = plone.app.transmogrifier.workflowupdater

Page 23: Transmogrifier: Migrating to Plone with less pain

The configuration file cont.

[transmogrifier]pipeline = eventsource eventupdater constructor schemaupdater workflow

Page 24: Transmogrifier: Migrating to Plone with less pain

SectionsCreate items

Modify items

Drop items

Split the pipeline in two

Construct content

Modify content

Page 25: Transmogrifier: Migrating to Plone with less pain

Migrating from another CMS

Similar to the simple examplebut using SQL instead of CSV

Page 26: Transmogrifier: Migrating to Plone with less pain

Migration from Plone 2

1. Write an export script2. Write an import section

Page 27: Transmogrifier: Migrating to Plone with less pain

Migrate from Plone 2

importsourceconstructor

criterionadderschemaupdaterbrowserdefault

workflowsavepoint

Page 28: Transmogrifier: Migrating to Plone with less pain

Migrating from HTML

1. Get HTML from web

2. Extract fields like title, publish date, etc.

3. Make all urls either relative or into UID's

Page 29: Transmogrifier: Migrating to Plone with less pain

From small to huge

Largest migration:28 sections

527 lines of configuration16 custom sections

Page 30: Transmogrifier: Migrating to Plone with less pain

Caveat Emptor

Don't migrate from HTML on disk

Page 31: Transmogrifier: Migrating to Plone with less pain

Caveat Emptor

Newly created objects are not indexed.

Page 32: Transmogrifier: Migrating to Plone with less pain

Caveat Emptor

Debugging is backwards

Page 33: Transmogrifier: Migrating to Plone with less pain

Lennart Regebro

[email protected]

IRC nick: regebro