Updates present messages in .po files from .pot file.
One parameter - path/name of .pot file (default folder is "locale").
## @package ul_gettext_update ## Recursively update *.po translation files with new messages from *.pot file. import sys, os, os.path, glob, re ## encoding of translation files PO_ENCODING = 'UTF8' ## .po heading pattern RE_PO_HEAD = '(.+?)\\#\\:' ## .po message pattern RE_PO_MSG = '(\\#\\:.*?)[\\r\\n]+(msgid.*?)[\\r\\n]+(msgstr.*?)[\\r\\n]+' ## .po message id pattern RE_PO_MSGID = '\\"(.*?)\\"' ## default locale directory LOCALE_DIR = 'locale' def parse_po(po_txt): ''' parses .po file to list of 3-element lists (description, msgid, msgstr) returns messages list, file heading, message ids list ''' messages = [] # messages list msgids = [] # messages ids try: heading = re.search(RE_PO_HEAD, po_txt, re.I|re.M|re.U|re.DOTALL).group(1) except: heading = '' for msg in re.finditer(RE_PO_MSG, po_txt, re.M|re.I|re.U): if msg.group(1) and msg.group(2) and msg.group(3): messages.append([msg.group(1), msg.group(2), msg.group(3)]) msgids.append(re.search(RE_PO_MSGID, msg.group(2), re.I|re.M|re.U|re.DOTALL).group(1)) return messages, heading, msgids print '.po updater.\n' print 'Usage : ' + os.path.split(sys.argv[0])[1] + ' [locale_dir/*.pot]\n\n' # custom locale dir given if len(sys.argv) > 1: LOCALE_DIR = sys.argv[1] if os.path.isdir(LOCALE_DIR): LOCALE_DIR = os.path.join(LOCALE_DIR, '*.pot') ## main .pot file pot_files = glob.glob(LOCALE_DIR) # no .pot found - show message, exit if len(pot_files) == 0: print 'Can\'t find any .pot file' exit() pot_file = pot_files[0] print 'Reading : ' + pot_file pot_name = os.path.splitext(os.path.split(pot_file)[1])[0] # .pot file name pot_messages, pot_heading, pot_msgids = parse_po(open(pot_file, 'rb').read().decode(PO_ENCODING, 'ignore')) # get .pot messages print 'Messages : ', len(pot_messages) po_name = os.path.splitext(pot_name)[0] + '.po' # .po file name LOCALE_DIR = os.path.split(pot_name)[0] # search for present .po files for root, dirs, files in os.walk(LOCALE_DIR): for file_in in files: if glob.fnmatch.fnmatch(file_in, po_name): po_pathname = os.path.join(root, file_in) po_messages, po_heading, po_msgids = parse_po(open(po_pathname, 'rb').read().decode(PO_ENCODING, 'ignore')) po_changes_plus = 0 po_changes_minus = 0 # create .po file text po_txt = po_heading # write records already present in .pot for msg_id in po_msgids: if msg_id in pot_msgids: msg_index = po_msgids.index(msg_id) msg = po_messages[msg_index][0] + '\n' +po_messages[msg_index][1] + '\n' +po_messages[msg_index][2] + '\n\n' po_txt += msg else: po_changes_minus += 1 # append records not present in .pot for msg_id in pot_msgids: if not msg_id in po_msgids: msg_index = pot_msgids.index(msg_id) msg = pot_messages[msg_index][0] + '\n' +pot_messages[msg_index][1] + '\n' +pot_messages[msg_index][2] + '\n\n' po_txt += msg po_changes_plus += 1 # if was changes, rewrite .po file if (po_changes_minus > 0) and (po_changes_plus > 0): open(po_pathname, 'wb').write(po_txt.encode(PO_ENCODING, 'ignore')) print ' ' + po_pathname + ' : -' + str(po_changes_minus) + ' +' + str(po_changes_plus) print '\nPress ENTER to exit...', raw_input()