Mostrando entradas con la etiqueta ooodiff. Mostrar todas las entradas
Mostrando entradas con la etiqueta ooodiff. Mostrar todas las entradas

16 feb 2011

oodiff reloaded

Although there exists alread oodiff, it's a bit limited. What's about any format or image changes not reflected in the diff?

I had a oodiff before, but some day it stopped working. Now I renamed it to ooodiff.
Thanks to some notes from here I corrected it. This version should work well with subversion. Here's the code (PEP8/Pyflakes compatible):


#!/usr/bin/python
# Requires python-uno
# Code originally gotten from:
# http://people.warp.es/~xtor/blog/?p=166
# See also: (google for "openoffice uno compare documents")
# http://win32com.goermezer.de/content/view/193/274/
# http://nxsy.org/blog/447.html
# http://www-verimag.imag.fr/~moy/opendocument/


PORT = 2526
OOFFICE = 'ooffice'

# General imports
import filecmp
import os
import shutil
import sys
import time

# pyuno imports
import uno
from com.sun.star.connection import NoConnectException


class OOUnoConnectionError(Exception):
pass


def getRevision(filename, revision, save_as):
"""Export a revision of a document."""
os.system('svn export -r%s "%s" "%s"' % (revision, filename, save_as))
return save_as


def compare(filename, oldrev='', newrev='', force=False):
"""Compare two revisions of a document."""
if not oldrev:
oldrev = 'BASE'
newfilename = '%s%s%s%s' % (filename, '.' + oldrev,
'.' + (newrev or 'workingcopy'), '.diff.tmp')
if not newrev:
shutil.copyfile(filename, newfilename)
else:
getRevision(filename, newrev, newfilename)
oldfilename = '%s%s%s' % (filename, '.' + oldrev, '.tmp')
getRevision(filename, oldrev, oldfilename)
if not force and filecmp.cmp(newfilename, oldfilename):
print ("The files seem to be the same. "
"There are no changes. Use --force run the diff in OO.")
else:
oo = OO()
doc = oo.open(newfilename)
oo.compareCurrentDocument(doc, oldfilename)


class OO:
"""A small class to abstract OpenOffice application."""
def __init__(self, filename=''):
# start OO
print "Starting OO"
os.system("soffice -nodefault "
"'-accept=socket,host=localhost,port=%s;urp;'" % PORT)

# Get the uno component context from the PyUNO runtime
localctx = uno.getComponentContext()
# Create the UnoUrlResolver on the Python side.
resolver = localctx.ServiceManager.createInstanceWithContext(
"com.sun.star.bridge.UnoUrlResolver", localctx)

cnxstr = ("uno:socket,host=localhost,port=%s;urp;"
"StarOffice.ComponentContext")
cnxstr = cnxstr % PORT
# try to connect to OO
ctx = None
retries = 5
while retries:
retries -= 1
try:
ctx = resolver.resolve(cnxstr)
except NoConnectException:
time.sleep(1)
if not ctx:
raise OOUnoConnectionError("Can't connect to OpenOffice")

# Get the ServiceManager object
smgr = ctx.ServiceManager

# Create the Desktop instance
desktop = smgr.createInstance("com.sun.star.frame.Desktop")
# save objects
self.desktop = desktop
self.smgr = smgr
self.ctx = ctx
if filename:
self.open(filename)

def open(self, filename, **kwargs):
"""Open a file."""
print "Opening: %s" % filename
properties = []
for key, value in kwargs.items():
properties.append(self.getProperty(key, value))
properties = tuple(properties)
doc = self.desktop.loadComponentFromURL(
self.convertToURL(filename), "_blank", 0, properties)
return doc

def compareCurrentDocument(self, doc, filename):
"""Compare the current document to the specified one."""
print "Comparing to: %s" % filename

# Sometimes, after opening OO or loading a doc
# we've still not access to the dispatcher or current frame
# so we wait here a bit.
# Get the dispatcher
dispatcher = self.smgr.createInstance("com.sun.star.frame."
"DispatchHelper")

# Show tracked changes and compare documents
frame = doc.getCurrentController().getFrame()
property = self.getProperty('URL', self.convertToURL(filename))
dispatcher.executeDispatch(frame, ".uno:CompareDocuments", "", 0,
(property,))
property = self.getProperty("ShowTrackedChanges", True)
dispatcher.executeDispatch(frame, ".uno:ShowTrackedChanges", "", 0,
(property,))

def getProperty(name, value):
"""Read a OO property."""
prop = uno.createUnoStruct("com.sun.star.beans.PropertyValue")
prop.Name, prop.Value = name, value
return prop
getProperty = staticmethod(getProperty)

def convertToURL(filename):
"""Convert a local filename to URL required by OO."""
return uno.systemPathToFileUrl(os.path.abspath(filename))
convertToURL = staticmethod(convertToURL)


if __name__ == '__main__':
oldrev = newrev = ''
force = '--force' in sys.argv
filename = ''
for arg in sys.argv[1:]:
if arg.startswith('-r'):
if not ':' in arg:
arg += ':'
oldrev, newrev = arg[2:].split(':')
elif not arg.startswith('-'):
filename = arg
if filename:
compare(filename, oldrev, newrev, force)
else:
print """
Usage: oodiff [--force] [-r[:]]
: the file to comparte
--force: force comparison, although files seem the same
-r : same as subversion. If not specified, -rPREV assumed.

This command:
- may not work if OpenOffice.org is already running (because
it has to start with a listening port for UNO to work).

- will create some temporary files (*.tmp). You have delete them
manually when you are finished.
"""