~ubuntu-branches/ubuntu/gutsy/moin/gutsy

« back to all changes in this revision

Viewing changes to MoinMoin/scripts/migration/12_to_13_mig08.py

  • Committer: Bazaar Package Importer
  • Author(s): Sivan Greenberg
  • Date: 2006-07-09 19:28:02 UTC
  • Revision ID: james.westby@ubuntu.com-20060709192802-oaeuvt4v3e9300uj
Tags: 1.5.3-1ubuntu1
* Merge new debian version.
* Reapply Ubuntu changes:
    + debian/rules:
      - Comment out usage of control.ubuntu.in (doesn't fit!).
    + debian/control.in:
      - Dropped python2.3 binary package.
    + debian/control:
      - Dropped python2.3 binary, again.
      - Dropped python2.3-dev from Build-Depends-Indep.
    + debian/patches/001-attachment-xss-fix.patch:
      - Dropped this patch. It's now in upstream's distribution.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#!/usr/bin/env python
2
 
"""
3
 
    migration from moin 1.3 < patch-305 to moin 1.3 >= patch-305
4
 
    Here we fix 2 errors that crept in by use of mig1(?) and mig5:
5
 
    * the edit-log misses 1 field (missing TAB) on faked "missing editlog
6
 
      entry" entries
7
 
    * we accidently gave ATTNEW/DRW/DEL an incremented revno (although
8
 
      attaching a file doesn't change page content and revision), so we need
9
 
      to convert those entries to use revno == 99999999 and renumber the
10
 
      normal entries so we have no missing numbers in between
11
 
    * edit-log's action field sometimes was empty (default: SAVE)
12
 
    
13
 
    Steps for a successful migration:
14
 
 
15
 
        1. Stop your wiki and make a backup of old data and code
16
 
 
17
 
        2. Make a copy of the wiki's "data" directory to your working dir
18
 
 
19
 
        3. Run this script from your working dir
20
 
 
21
 
        4. If there was no error, you will find:
22
 
            data.pre-mig8 - the script renames your data directory copy to that name
23
 
            data - converted data dir
24
 
 
25
 
        5. Verify conversion results (number of pages, size of logs, attachments,
26
 
           number of backup copies) - everything should be reasonable before
27
 
           you proceed.
28
 
 
29
 
        6. Copy additional files from data.pre-mig8 to data (maybe intermaps, logs,
30
 
           etc.). Be aware that the file contents AND file names of wiki content
31
 
           may have changed, so DO NOT copy the files inside the cache/ directory,
32
 
           let the wiki refill it.
33
 
 
34
 
        7. Replace the data directory your wiki uses with the data directory
35
 
           you created by previous steps. DO NOT simply copy the converted stuff
36
 
           into the original or you will duplicate pages and create chaos!
37
 
 
38
 
        8. Test it - if something has gone wrong, you still have your backup.
39
 
 
40
 
 
41
 
    @copyright: 2004 Thomas Waldmann
42
 
    @license: GPL, see COPYING for details
43
 
"""
44
 
 
45
 
 
46
 
import os.path, sys, urllib
47
 
 
48
 
# Insert THIS moin dir first into sys path, or you would run another
49
 
# version of moin!
50
 
sys.path.insert(0, '../../..')
51
 
from MoinMoin import wikiutil
52
 
 
53
 
from migutil import opj, listdir, copy_file, move_file, copy_dir
54
 
 
55
 
# info[pagename][timestamp_usecs] = [revno_new, [...]]
56
 
# if revno_new is 99999999, we haven't assigned a new revno to this entry
57
 
info = {}
58
 
 
59
 
def gather_editlog(el_from, forcepagename=None):
60
 
    """ this gathers everything that is in edit-log into internal
61
 
        data structures, converting to the future format
62
 
    """
63
 
    if not os.path.exists(el_from): 
64
 
        return
65
 
    for l in open(el_from):
66
 
        data = l.rstrip('\n').rstrip('\r').split('\t')
67
 
        while len(data) < 9:
68
 
            data.append('')
69
 
        (timestampstr,revstr,action,pagename,ip,host,id,extra,comment) = data
70
 
        
71
 
        if forcepagename: # we use this for edit-log in pagedirs (for renamed pages!)
72
 
            pagename = forcepagename
73
 
 
74
 
        if not action: # FIX: sometimes action is empty ...
75
 
            action = 'SAVE'
76
 
 
77
 
        if action in ['ATTNEW','ATTDRW','ATTDEL',]:
78
 
            revstr = '99999999' # FIXES revno
79
 
            # use reserved value, ATT action doesn't create new rev of anything
80
 
 
81
 
        if (comment == '' and extra == '' and id == 'missing editlog entry for this page version') or \
82
 
           (extra == '' and id == '' and comment == 'missing editlog entry for this page version'):
83
 
            # FIX omitted field bug on fake entries
84
 
            comment = 'missing edit-log entry for this revision' # more precise
85
 
            extra = ''
86
 
            id = ''
87
 
            
88
 
        rev = int(revstr)
89
 
        data = [timestampstr,rev,action,pagename,ip,host,id,extra,comment]
90
 
        
91
 
        entry = info.get(pagename, {})
92
 
        timestamp = long(timestampstr) # must be long for py 2.2.x
93
 
        entry[timestamp] = [99999999, data] # new revno, data
94
 
        info[pagename] = entry
95
 
        
96
 
def gather_pagedirs(dir_from):
97
 
    """ this gathers edit-log information from the pagedirs, just to make sure
98
 
    """
99
 
    pagedir = opj(dir_from, 'pages')
100
 
    pagelist = listdir(pagedir)
101
 
    for pagename in pagelist:
102
 
        editlog_from = opj(pagedir, pagename, 'edit-log')
103
 
        gather_editlog(editlog_from, pagename)
104
 
 
105
 
 
106
 
def generate_pages(dir_from, dir_to):
107
 
    revactions = ['SAVE','SAVENEW','SAVE/REVERT',] # these actions create revisions
108
 
    for pn in info:
109
 
        entry = info.get(pn, {})
110
 
        tslist = entry.keys()
111
 
        if tslist:
112
 
            pagedir = opj(dir_to, 'pages', pn)
113
 
            revdir = opj(pagedir, 'revisions')
114
 
            os.makedirs(revdir)
115
 
            editlog_file = opj(pagedir, 'edit-log')
116
 
            f = open(editlog_file, 'w')
117
 
            revnew = 0
118
 
            tslist.sort()
119
 
            for ts in tslist:
120
 
                data = entry[ts][1]
121
 
                datanew = data[:]
122
 
                (timestamp,rev,action,pagename,ip,host,id,extra,comment) = data
123
 
                revstr = '%08d' % rev
124
 
                if action in revactions:
125
 
                    revnew += 1
126
 
                    revnewstr = '%08d' % revnew
127
 
                    entry[ts][0] = revnew # remember what new revno we chose
128
 
                else: # ATTNEW,ATTDRW,ATTDEL
129
 
                    revnewstr = '99999999'
130
 
                if action.endswith('/REVERT'):
131
 
                    # replace the old revno with the correct new revno
132
 
                    revertrevold = int(extra)
133
 
                    revertrevnew = 0
134
 
                    for ts2 in tslist:
135
 
                        data2 = entry[ts2][1]
136
 
                        (timestamp2,rev2,action2,pagename2,ip2,host2,id2,extra2,comment2) = data2
137
 
                        if rev2 == revertrevold:
138
 
                            revertrevnew = entry[ts2][0]
139
 
                    datanew[7] = '%08d' % revertrevnew
140
 
                    
141
 
                datanew[1] = revnewstr
142
 
                f.write('\t'.join(datanew)+'\n') # does make a CRLF on win32 in the file
143
 
                
144
 
                if action in revactions: # we DO have a page rev for this one
145
 
                    file_from = opj(dir_from, 'pages', pn, 'revisions', revstr)
146
 
                    file_to = opj(revdir, revnewstr)
147
 
                    copy_file(file_from, file_to)
148
 
            f.close()
149
 
            
150
 
            # check if page exists or is deleted in orig dir
151
 
            pagedir_from = opj(dir_from, 'pages', pn)
152
 
            revdir_from = opj(pagedir_from, 'revisions')
153
 
            try:
154
 
                curr_file_from = opj(pagedir_from, 'current')
155
 
                currentfrom = open(curr_file_from).read().strip() # try to access it
156
 
                page_exists = 1
157
 
            except:
158
 
                page_exists = 0
159
 
                
160
 
            # re-make correct DELETED status!
161
 
            if page_exists:
162
 
                curr_file = opj(pagedir, 'current')
163
 
                f = open(curr_file, 'w')
164
 
                f.write("%08d\n" % revnew) # we add a \n, so it is easier to hack in there manually
165
 
                f.close()
166
 
 
167
 
        att_from = opj(dir_from, 'pages', pn, 'attachments')
168
 
        if os.path.exists(att_from):
169
 
            att_to = opj(pagedir, 'attachments')
170
 
            copy_dir(att_from, att_to)
171
 
        
172
 
 
173
 
def generate_editlog(dir_from, dir_to):
174
 
    editlog = {}
175
 
    for pagename in info:
176
 
        entry = info.get(pagename, {})
177
 
        for ts in entry:
178
 
            file_from, data = entry[ts]
179
 
            editlog[ts] = data
180
 
    
181
 
    tslist = editlog.keys()
182
 
    tslist.sort()
183
 
    
184
 
    editlog_file = opj(dir_to, 'edit-log')
185
 
    f = open(editlog_file, 'w')
186
 
    for ts in tslist:
187
 
        datatmp = editlog[ts][:]
188
 
        rev = datatmp[1]
189
 
        datatmp[1] = '%08d' % rev
190
 
        f.write('\t'.join(datatmp)+'\n')
191
 
    f.close()
192
 
 
193
 
        
194
 
origdir = 'data.pre-mig8'
195
 
 
196
 
# Backup original dir and create new empty dir
197
 
try:
198
 
    os.rename('data', origdir)
199
 
    os.mkdir('data')
200
 
except OSError:
201
 
    print "You need to be in the directory where your copy of the 'data' directory is located."
202
 
    sys.exit(1)
203
 
 
204
 
#gather_editlog(opj(origdir, 'edit-log'))
205
 
gather_pagedirs(origdir)
206
 
 
207
 
generate_editlog(origdir, 'data')
208
 
generate_pages(origdir, 'data')
209
 
 
210
 
copy_dir(opj(origdir, 'plugin'), opj('data', 'plugin'))
211
 
 
212
 
copy_dir(opj(origdir, 'user'), opj('data', 'user'))
213
 
 
214
 
copy_file(opj(origdir, 'event-log'), opj('data', 'event-log'))
215
 
 
216
 
copy_file(opj(origdir, 'intermap.txt'), opj('data', 'intermap.txt'))
217
 
 
218