lifeasageek

ttfFromDocx

Jan 19th, 2012
529
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.05 KB | None | 0 0
  1. # extract .ttf files from .docx
  2.  
  3. import base64
  4. import sys
  5. import os, zipfile
  6. from BeautifulSoup import BeautifulStoneSoup as soup
  7.  
  8. def extractFontKey(files):
  9.     keys = []
  10.  
  11.     for filename in files:
  12.         if not filename.endswith("fontTable.xml"):
  13.             continue
  14.         xmlStr = open(filename).read()
  15.         xml = soup(xmlStr)
  16.         # print xml
  17.         for i, f in enumerate(xml.findAll('w:font')):
  18.             name = f['w:name']
  19.             x = soup(str(f))
  20.            
  21.             try:
  22.                 fontkey =  x.findAll('w:embedregular')[0]['w:fontkey']
  23.                 fontkey = "".join(fontkey[1:-1].split("-"))
  24.             except: # some entry does not have fontkey. skip this
  25.                 continue
  26.  
  27.             print name, fontkey
  28.             keys.append( (name, fontkey))
  29.         return keys
  30.  
  31. def deobf( fontKeyBin, obfFontStr):
  32.     fontStr = [ord(x) for x in obfFontStr]
  33.  
  34.     for i in range(16):
  35.         fontStr[i] = ord(obfFontStr[i]) ^ ord(fontKeyBin[15-i])
  36.         fontStr[i+16] = ord(obfFontStr[i+16]) ^ ord(fontKeyBin[15-i])
  37.        
  38.     fontStr = "".join( [ "%c" % x for x in fontStr])
  39.     return fontStr
  40.  
  41. def deobfAll(files, keys):
  42.     files.sort() # odttf filenames seem to be sorted as it was appeared in .xml
  43.  
  44.     i = 0
  45.     for filename in files:
  46.         if not filename.endswith(".odttf"):
  47.             continue
  48.         print filename
  49.         obfStr = open( filename, 'rb').read()
  50.         (fontname, fontkey) = keys[i]
  51.         print fontkey
  52.  
  53.         deobfStr = deobf(fontkey.decode("hex"), obfStr)
  54.  
  55.         open( fontname + ".ttf", 'wb').write(deobfStr)
  56.         i += 1
  57.  
  58. def decompress(docxFilename):
  59.     z = zipfile.ZipFile(docxFilename)
  60.    
  61.     try:
  62.         os.mkdir( "./tmp")
  63.     except:
  64.         pass
  65.  
  66.     z.extractall("./tmp")
  67.     files = ["./tmp/" + x for x in z.namelist()]
  68.     return files
  69.    
  70. if __name__ == '__main__':
  71.     docxFilename = sys.argv[1]
  72.    
  73.     files = decompress( docxFilename)
  74.     keys = extractFontKey(files)
  75.     deobfAll(files, keys)
Advertisement
Add Comment
Please, Sign In to add comment