/win32/docdiff.py

https://bitbucket.org/tortoisehg/hgtk/ · Python · 109 lines · 80 code · 13 blank · 16 comment · 17 complexity · ffcf74c685907f619a7d19d52938e8c4 MD5 · raw file

  1. '''
  2. Binary document diff wrapper script
  3. This script is converted into an executable by py2exe for use in
  4. TortoiseHg binary packages. It is then used by TortoiseHg as a visual
  5. diff application for binary document types.
  6. It takes two (diff) or four (merge) arguments, determines the file type
  7. based on the file extension, then launches the appropriate document diff
  8. script that THG has borrowed from the TortoiseSVN project.
  9. This script is quite useless outside of a TortoiseHg binary install.
  10. '''
  11. import os
  12. import sys
  13. import subprocess
  14. import shutil
  15. import win32con
  16. import win32api
  17. import win32process
  18. import locale
  19. from mercurial import util
  20. scripts = {
  21. 'doc' : ('diff-doc.js', 'merge-doc.js'), # MS Word
  22. 'docx' : ('diff-doc.js', 'merge-doc.js'),
  23. 'docm' : ('diff-doc.js', 'merge-doc.js'),
  24. 'ppt' : ('diff-ppt.js',), # MS PowerPoint
  25. 'pptx' : ('diff-ppt.js',),
  26. 'pptm' : ('diff-ppt.js',),
  27. 'xls' : ('diff-xls.vbs',), # MS Excel
  28. 'xlsx' : ('diff-xls.vbs',),
  29. 'xlsm' : ('diff-xls.vbs',),
  30. 'xlsb' : ('diff-xls.vbs',),
  31. 'xlam' : ('diff-xls.vbs',),
  32. 'ods' : ('diff-odt.vbs', 'merge-ods.vbs'), # OpenOffice Text
  33. 'odt' : ('diff-odt.vbs', 'merge-ods.vbs'),
  34. 'sxw' : ('diff-sxw.vbs', 'merge-ods.vbs'), # OpenOffice Calc
  35. 'nb' : ('diff-nb.vbs',), # Mathematica Notebook
  36. }
  37. def safe_encode(string, encoding):
  38. if isinstance(string, unicode):
  39. return string.encode(encoding)
  40. return string
  41. def main():
  42. args = sys.argv[1:]
  43. if len(args) not in (2, 4):
  44. print 'Two or four arguments expected:'
  45. print sys.argv[0], '[local] [other]'
  46. print sys.argv[0], '[local] [base] [other] [output]'
  47. sys.exit(1)
  48. elif len(args) == 2:
  49. local, other = [os.path.abspath(f) for f in args]
  50. base, ext = os.path.splitext(local)
  51. else:
  52. local, base, other, output = [os.path.abspath(f) for f in args]
  53. base, ext = os.path.splitext(output)
  54. if not ext or ext.lower()[1:] not in scripts.keys():
  55. print 'Unsupported file type', ext
  56. sys.exit(1)
  57. proc = win32api.GetCurrentProcess()
  58. try:
  59. # This will fail on windows < NT
  60. filename = win32process.GetModuleFileNameEx(proc, 0)
  61. except:
  62. filename = win32api.GetModuleFileName(0)
  63. path = os.path.join(os.path.dirname(filename), 'diff-scripts')
  64. if not os.path.isdir(path):
  65. print 'Diff scripts not found at', path
  66. sys.exit(1)
  67. use = scripts[ext.lower()[1:]]
  68. if 'xls' in use[0] and os.path.basename(local) == os.path.basename(other):
  69. # XLS hack; Excel will not diff two files if they have the same
  70. # basename.
  71. othertmp = other+'~x1'
  72. shutil.copy(other, othertmp)
  73. other = othertmp
  74. if len(args) == 2:
  75. script = os.path.join(path, use[0])
  76. cmd = ['wscript', script, other, local]
  77. elif len(use) == 1:
  78. print 'Unsupported file type for merge', local
  79. sys.exit(1)
  80. else:
  81. script = os.path.join(path, use[1])
  82. cmd = ['wscript', script, output, other, local, base]
  83. encoding = locale.getpreferredencoding(do_setlocale=True)
  84. cmd = [util.shellquote(safe_encode(arg, encoding)) for arg in cmd]
  85. cmdline = util.quotecommand(' '.join(cmd))
  86. proc = subprocess.Popen(cmdline, shell=True,
  87. creationflags=win32con.CREATE_NO_WINDOW,
  88. stderr=subprocess.PIPE,
  89. stdout=subprocess.PIPE,
  90. stdin=subprocess.PIPE)
  91. return proc.communicate()
  92. if __name__=='__main__':
  93. main()