comparison MoinMoin/action/SyncPages.py @ 1303:a0b8e78621d0

Preliminary support for items of different mime types.
author Alexander Schremmer <alex AT alexanderweb DOT de>
date Wed, 16 Aug 2006 22:09:22 +0200
parents 6bbd177f5b36
children f103cf7c371e
comparison
equal deleted inserted replaced
1302:7e0faeed44bc 1303:a0b8e78621d0
23 from MoinMoin.packages import unpackLine, packLine 23 from MoinMoin.packages import unpackLine, packLine
24 from MoinMoin.PageEditor import PageEditor, conflict_markers 24 from MoinMoin.PageEditor import PageEditor, conflict_markers
25 from MoinMoin.Page import Page 25 from MoinMoin.Page import Page
26 from MoinMoin.wikidicts import Dict, Group 26 from MoinMoin.wikidicts import Dict, Group
27 from MoinMoin.wikisync import TagStore, UnsupportedWikiException, SyncPage 27 from MoinMoin.wikisync import TagStore, UnsupportedWikiException, SyncPage
28 from MoinMoin.wikisync import MoinLocalWiki, MoinRemoteWiki, UP, DOWN, BOTH 28 from MoinMoin.wikisync import MoinLocalWiki, MoinRemoteWiki, UP, DOWN, BOTH, MIMETYPE_MOIN
29 from MoinMoin.util.bdiff import decompress, patch, compress, textdiff 29 from MoinMoin.util.bdiff import decompress, patch, compress, textdiff
30 from MoinMoin.util import diff3 30 from MoinMoin.util import diff3
31 31
32 32
33 # map sync directions 33 # map sync directions
160 | | do a sync without considering tags 160 | | do a sync without considering tags
161 with tags | with non | to ensure data integrity. 161 with tags | with non | to ensure data integrity.
162 | matching | 162 | matching |
163 | tags | 163 | tags |
164 ----------+----------+------------------------------- 164 ----------+----------+-------------------------------
165 exists | exists | already handled.
165 """ 166 """
166 _ = self.request.getText 167 _ = self.request.getText
167 direction = params["direction"] 168 direction = params["direction"]
169 local_full_iwid = packLine([local.get_iwid(), local.get_interwiki_name()])
170 remote_full_iwid = packLine([remote.get_iwid(), remote.get_interwiki_name()])
168 171
169 l_pages = local.get_pages() 172 l_pages = local.get_pages()
170 r_pages = remote.get_pages(exclude_non_writable=direction != DOWN) 173 r_pages = remote.get_pages(exclude_non_writable=direction != DOWN)
171 174
172 if params["groupList"]: 175 if params["groupList"]:
219 # XXX check the tag.normalised_name here 222 # XXX check the tag.normalised_name here
220 local_rev = newest_tag.current_rev 223 local_rev = newest_tag.current_rev
221 remote_rev = newest_tag.remote_rev 224 remote_rev = newest_tag.remote_rev
222 if remote_rev == rp.remote_rev and (direction == DOWN or local_rev == current_rev): 225 if remote_rev == rp.remote_rev and (direction == DOWN or local_rev == current_rev):
223 continue # no changes done, next page 226 continue # no changes done, next page
227 if rp.local_mime_type != MIMETYPE_MOIN and not (remote_rev == rp.remote_rev ^ local_rev == current_rev):
228 self.log_status(ActionClass.WARN, _("The item %(pagename)s cannot be merged but was changed in both wikis. Please delete it in one of both wikis and try again.") % {"pagename": rp.name})
229 continue
230 if rp.local_mime_type != rp.remote_mime_type:
231 self.log_status(ActionClass.WARN, _("The item %(pagename)s has different mime types in both wikis and cannot be merged. Please delete it in one of both wikis or unify the mime type, and try again.") % {"pagename": rp.name})
232 continue
224 old_contents = Page(self.request, local_pagename, rev=local_rev).get_raw_body_str() # YYY direct access 233 old_contents = Page(self.request, local_pagename, rev=local_rev).get_raw_body_str() # YYY direct access
225 234
226 self.log_status(ActionClass.INFO, _("Synchronising page %(pagename)s with remote page %(remotepagename)s ...") % {"pagename": local_pagename, "remotepagename": rp.remote_name}) 235 self.log_status(ActionClass.INFO, _("Synchronising page %(pagename)s with remote page %(remotepagename)s ...") % {"pagename": local_pagename, "remotepagename": rp.remote_name})
227 236
228 if direction == DOWN: 237 if direction == DOWN:
237 assert diff_result["diffversion"] == 1 246 assert diff_result["diffversion"] == 1
238 diff = diff_result["diff"] 247 diff = diff_result["diff"]
239 current_remote_rev = diff_result["current"] 248 current_remote_rev = diff_result["current"]
240 else: 249 else:
241 current_remote_rev = remote_rev 250 current_remote_rev = remote_rev
242 is_remote_conflict = wikiutil.containsConflictMarker(old_contents.decode("utf-8")) 251 if rp.local_mime_type == MIMETYPE_MOIN:
252 is_remote_conflict = wikiutil.containsConflictMarker(old_contents.decode("utf-8"))
253 else:
254 is_remote_conflict = NotImplemented
243 diff = None 255 diff = None
244 256
245 # do not sync if the conflict is remote and local, or if it is local 257 # do not sync if the conflict is remote and local, or if it is local
246 # and the page has never been syncronised 258 # and the page has never been syncronised
247 if (wikiutil.containsConflictMarker(current_page.get_raw_body()) 259 if (rp.local_mime_type == MIMETYPE_MOIN and wikiutil.containsConflictMarker(current_page.get_raw_body())
248 and (remote_rev is None or is_remote_conflict)): 260 and (remote_rev is None or is_remote_conflict)):
249 self.log_status(ActionClass.WARN, _("Skipped page %(pagename)s because of a locally or remotely unresolved conflict.") % {"pagename": local_pagename}) 261 self.log_status(ActionClass.WARN, _("Skipped page %(pagename)s because of a locally or remotely unresolved conflict.") % {"pagename": local_pagename})
250 continue 262 continue
251 263
252 if remote_rev is None and direction == BOTH: 264 if remote_rev is None and direction == BOTH:
253 self.log_status(ActionClass.INFO, _("This is the first synchronisation between this page and the remote wiki.")) 265 self.log_status(ActionClass.INFO, _("This is the first synchronisation between this page and the remote wiki."))
254 266
255 if diff is None: 267 if diff is None:
256 new_contents = old_contents.decode("utf-8") 268 new_contents = old_contents
257 else: 269 else:
258 new_contents = patch(patch_base_contents, decompress(diff)).decode("utf-8") 270 new_contents = patch(patch_base_contents, decompress(diff))
259 271
260 # here, the actual merge happens 272 if rp.local_mime_type == MIMETYPE_MOIN:
261 # XXX print "Merging %r, %r and %r" % (old_contents.decode("utf-8"), new_contents, current_page.get_raw_body()) 273 new_contents_unicode = new_contents.decode("utf-8")
262 verynewtext = diff3.text_merge(old_contents.decode("utf-8"), new_contents, current_page.get_raw_body(), 2, *conflict_markers) 274 # here, the actual merge happens
263 275 # XXX print "Merging %r, %r and %r" % (old_contents.decode("utf-8"), new_contents, current_page.get_raw_body())
264 local_full_iwid = packLine([local.get_iwid(), local.get_interwiki_name()]) 276 verynewtext = diff3.text_merge(old_contents.decode("utf-8"), new_contents_unicode, current_page.get_raw_body(), 2, *conflict_markers)
265 remote_full_iwid = packLine([remote.get_iwid(), remote.get_interwiki_name()]) 277 verynewtext_raw = verynewtext.encode("utf-8")
266 278 else:
267 diff = textdiff(new_contents.encode("utf-8"), verynewtext.encode("utf-8")) 279 if diff is None:
280 verynewtext_raw = new_contents
281 else:
282 verynewtext_raw = current_page.get_raw_body_str()
283
284 diff = textdiff(new_contents, verynewtext_raw)
268 #print "Diff against %r" % new_contents.encode("utf-8") 285 #print "Diff against %r" % new_contents.encode("utf-8")
269 286
270 comment = u"Local Merge - %r" % (remote.get_interwiki_name() or remote.get_iwid()) 287 comment = u"Local Merge - %r" % (remote.get_interwiki_name() or remote.get_iwid())
271 288
272 # XXX upgrade to write lock 289 # XXX upgrade to write lock
287 else: 304 else:
288 very_current_remote_rev = current_remote_rev 305 very_current_remote_rev = current_remote_rev
289 306
290 tags.add(remote_wiki=remote_full_iwid, remote_rev=very_current_remote_rev, current_rev=new_local_rev, direction=direction, normalised_name=rp.name) 307 tags.add(remote_wiki=remote_full_iwid, remote_rev=very_current_remote_rev, current_rev=new_local_rev, direction=direction, normalised_name=rp.name)
291 308
292 if not wikiutil.containsConflictMarker(verynewtext): 309 if rp.local_mime_type != MIMETYPE_MOIN or not wikiutil.containsConflictMarker(verynewtext):
293 self.log_status(ActionClass.INFO, _("Page successfully merged.")) 310 self.log_status(ActionClass.INFO, _("Page successfully merged."))
294 else: 311 else:
295 self.log_status(ActionClass.WARN, _("Page merged with conflicts.")) 312 self.log_status(ActionClass.WARN, _("Page merged with conflicts."))
296 313
297 # XXX release lock 314 # XXX release lock