#!/usr/bin/env python3 # -*- coding: utf8 -*- # # Copyright (C) 2010-2015 Evol Online # Author: Andrei Karas (4144) import os import re defaultLang = "en" filt = re.compile(".+[.]txt", re.IGNORECASE) allStrings = set() strComments = dict() strre1 = re.compile("[\t +(]l[(][\"](?P[^\"]+)[\"]") strre3 = re.compile("[\t +(]getitemlink[(][\"](?P[^\"]+)[\"][)]") strre2 = re.compile("^[^/](.+)([^\t]+)[\t](script|shop|trader|cashshop)[\t](?P[^\t]+)[\t]([\w\d]+),") strre4 = re.compile("[\t +(]lg[(][\"](?P[^\"]+)[\"][)]") strre5 = re.compile("[\t +(]getitemname[(][\"](?P[^\"]+)[\"][)]") strre6 = re.compile("[\t ]mesn[ ][\"](?P[^\"]+)[\"]") strre7 = re.compile("[\t +(]lg[(][\"](?P[^\"]+)[\"],([ ]*)[\"](?P[^\"]+)[\"]") itemsplit = re.compile(",") langFiles = dict() oldLangFiles = dict() langs = set() itemNamesByName = dict() def addStr(text, comment, fileName, lineNum, addNoC): text = text.replace("\a", "\"") allStrings.add(text) if comment[-1:] == "\n": comment = comment[:-1] if text not in strComments: strComments[text] = set() strComments[text].add("#. code: " + comment.strip() + "\n") strComments[text].add("#: " + fileName + ":" + str(lineNum) + "\n") if addNoC == True: strComments[text].add("#, no-c-format\n") def collectScriptFileStrings(codeFile, file2): global itemNamesByName with open(file2, "r") as f: cnt = -1 for line in f: cnt = cnt + 1 line = line.replace("\\\"", "\a") m = strre1.findall(line) if len(m) > 0: for str in m: addStr(str, line, codeFile, cnt, True) m = strre4.findall(line) if len(m) > 0: for str in m: addStr(str + "#0", line, codeFile, cnt, True) addStr(str + "#1", line, codeFile, cnt, True) m = strre2.search(line) if m is not None and m.group("str")[0] != "#": addStr(m.group("str"), line, codeFile, cnt, True) m = strre3.findall(line) if len(m) > 0: for str in m: if str.lower() in itemNamesByName: addStr(itemNamesByName[str.lower()], line, codeFile, cnt, True) m = strre5.findall(line) if len(m) > 0: for str in m: if str.lower() in itemNamesByName: addStr(itemNamesByName[str.lower()], line, codeFile, cnt, True) m = strre6.findall(line) if len(m) > 0: for str in m: addStr(str, line, codeFile, cnt, True) m = strre7.findall(line) if len(m) > 0: for str in m: addStr(str[0] + "#0", line, codeFile, cnt, True) addStr(str[2] + "#1", line, codeFile, cnt, True) def collectScriptStrings(parentDir, relativeDir): files = os.listdir(parentDir) for file1 in files: if file1[0] == ".": continue file2 = os.path.abspath(parentDir + os.path.sep + file1) relativeDir2 = relativeDir + os.path.sep + file1 if not os.path.isfile(file2): collectScriptStrings(file2, relativeDir2) elif filt.search(file1): codeFile = relativeDir + os.path.sep + file1 collectScriptFileStrings(codeFile, file2) def collectMessages(messagesDir): with open(messagesDir, "r") as r: cnt = -1 for line in r: cnt = cnt + 1 if line[:2] == "//": continue idx = line.find(": ") if idx < 1: continue # msgId = line[:idx] msgStr = line[idx + 2:] if msgStr[-1:] == "\n": msgStr = msgStr[:-1] addStr(msgStr, line, "conf/messages.conf", cnt, False) def loadFiles(dir): with open(dir + "/langs.txt", "r") as f: for line in f: langs.add(line[:-1]) for file in langs: langFiles[file] = parseFile(dir + "/lang_" + file + ".txt", True) oldLangFiles[file] = parseFile(dir + "/lang_" + file + ".old", False) def parseFile(name, readFirstLine): trans = dict() firstLine = None if os.path.exists(name): with open(name, "r") as f: line1 = line2 = "" for line in f: if readFirstLine is True and firstLine is None: firstLine = line continue if (line == ""): line1 = "" line2 = "" continue elif (line1 == ""): line1 = line[:-1] continue line2 = line[:-1] trans[line1] = line2 line1 = "" line2 = "" elif readFirstLine: firstLine = "Copyright (C) 2010-2015 Evol Online\n" return (trans, firstLine) def loadPoFiles(podir): files = os.listdir(podir) for name in files: if name[-3:] == ".po": parsePoFile(name[:-3], podir + "/" + name) def parsePoFile(name, path): langFile = langFiles[name][0] with open(path, "r") as f: flag = 0 line1 = "" line2 = "" for line in f: if flag == 0: idx = line.find ("msgid ") if idx == 0: line2 = "" line1 = line[len("msgid "):] line1 = line1[1:len(line1) - 2] flag = 1 elif flag == 1: idx = line.find ("msgstr ") if idx == 0: line2 = line[len("msgstr "):] line2 = line2[1:len(line2) - 2] flag = 2 if line == "\n": if flag == 2: if line1 != "": if line1 in langFile and line2 != "": langFile[line1] = line2.replace("\\\"", "\"") flag = 0 idx = line.find ("\"") if idx == 0: line = line[1:len(line) - 2] if flag == 1: line1 = line1 + line elif flag == 2: line2 = line2 + line def addMissingLines(): for trans in langFiles: newFile = langFiles[trans][0] oldFile = oldLangFiles[trans][0] for str in newFile: if str not in allStrings: # if newFile[str] != "": oldFile[str] = newFile[str] for str in oldFile: if str in newFile: del newFile[str] # print trans + ":moved to old: " + str for str in allStrings: for trans in langFiles: newFile = langFiles[trans][0] oldFile = oldLangFiles[trans][0] if str not in newFile: # print "lang: " + trans + ", str: " + str if trans == defaultLang: # print "newFile[str] = str" newFile[str] = str elif str in oldFile: newFile[str] = oldFile[str] # print "newFile[str] = oldFile[str]: " + newFile[str] else: # print "newFile[str] = """ newFile[str] = "" # print trans + ":new string: " + str def sorting(): for trans in langFiles: newFile = langFiles[trans] newFile = sortDict (newFile) langFiles[trans] = newFile oldFile = oldLangFiles[trans] oldFile = sortDict (oldFile) oldLangFiles[trans] = oldFile def sortDict(adict): d2 = [] keys = adict[0].keys() keys.sort() for key in keys: d2.append ((key, adict[0][key])) return (d2, adict[1]) def saveFiles(langDir, poDir): for trans in langFiles: writeLangFile (langDir + "/lang_" + trans + ".txt", langFiles[trans], trans, False) writeLangFile (langDir + "/lang_" + trans + ".old", oldLangFiles[trans], trans, True) writePoFile (poDir, langFiles[trans], trans) def removeGenderStr(trLine): if trLine in ("test#0", "test#1", "test1#0", "test1#1", "test2#0", "test2#1", "test1 %s#0", "test1 %s#1", "test2 %s#0", "test2 %s#1", "test1 @@#0", "test1 @@#1", "test2 @@#0", "test2 @@#1"): return trLine return trLine[:-2] def writeLangFile(langDir, texts, trans, isold): with open (langDir, "w") as f: if texts[1] is not None: f.write(texts[1]) for line in texts[0]: if not isold or (line[1] is not None and len(line[1]) > 0): f.write (line[0] + "\n") trLine = line[1] if trans == "en": if len(trLine) > 2 and (trLine[-2:] == "#0" or trLine[-2:] == "#1"): trLine = removeGenderStr(trLine) f.write (trLine + "\n\n") def writePoComments(w, comments): for line in comments: if line[:3] == "#. ": w.write (line) for line in comments: if line[:3] == "#: ": w.write (line) for line in comments: if line[:3] == "#, ": w.write (line) break def writePoFile(poDir, texts, trans): if trans == "en": langDir = poDir + "/" + trans + ".pot" else: langDir = poDir + "/" + trans + ".po" print(langDir) with open (langDir, "w") as w: w.write ("# " + texts[1] + "") w.write ("#\n\n") w.write ("msgid \"\"\n") w.write ("msgstr \"\"\n") w.write ("\"Project-Id-Version: EvolOnline\\n\"\n") w.write ("\"MIME-Version: 1.0\\n\"\n") w.write ("\"Content-Type: text/plain; charset=UTF-8\\n\"\n") w.write ("\"Content-Transfer-Encoding: 8bit\\n\"\n") w.write ("\n") for line in texts[0]: if line[0] in strComments.keys(): writePoComments(w, strComments[line[0]]) srcLine = line[0] srcLine = srcLine.replace("\\", "\\\\") srcLine = srcLine.replace("\"", "\\\"") w.write ("msgid \"" + srcLine + "\"\n") trLine = line[1] if trans == "en": trLine = "" trLine = trLine.replace("\\", "\\\\") trLine = trLine.replace("\"", "\\\"") w.write ("msgstr \"" + trLine + "\"\n\n") def stripQuotes(data): if len(data) == 0: return data if data[-1] == "\"": data = data[:-1] if data[0] == "\"": data = data[1:] if data[-1] == "'": data = data[:-1] if data[0] == "'": data = data[1:] return data def loadItemDb(dir): global itemNamesByName with open(dir + "/item_db.conf", "r") as f: cnt = -1 for line in f: line = line.strip() idx = line.find("Name: \"") if idx != 0 or line[len(line) - 1] != "\"": continue addStr(line[idx + 7: len(line) - 1], line, "item_db.conf", cnt, True) if line == "{": itemId = "" itemName = "" for line in f: line = line.strip() if len(line) < 1: continue if line[0] == "}": if itemId != "" and itemName != "": itemNamesByName[itemName.lower()] = itemName break if len(line) > 6 and line[:5] == "Name:": itemName = stripQuotes(line[5:].strip()) if len(line) > 4 and line[:3] == "Id:": itemId = stripQuotes(line[3:].strip()) def dumpTranslations(): for trans in oldLangFiles: print("old lang: " + trans) newFile = oldLangFiles[trans][0] for line in newFile: print(line) if line in newFile: print(newFile[line]) print("\n") for trans in langFiles: print("new lang: " + trans) newFile = langFiles[trans][0] for line in newFile: print(line) if line in newFile: print(newFile[line]) print("\n") def loadMobNames(dir): with open(dir + "/mob_db.conf", "r") as r: cnt = -1 for line in r: cnt = cnt + 1 if len(line) < 1 or line[0:2] == "//": continue line = line.strip() idx = line.find("Name: \"") if idx != 0 or line[len(line) - 1] != "\"": continue addStr(line[idx + 7: len(line) - 1], line, "mob_db.conf", cnt, True) rootPath = "../../server-data/" loadItemDb(rootPath + "db/pre-re") loadMobNames(rootPath + "db/pre-re") collectScriptStrings(rootPath + "/npc", "npc") collectScriptFileStrings("db/pre-re/item_db.conf", rootPath + "/db/pre-re/item_db.conf") #collectMessages(rootPath + "/conf/messages.conf") loadFiles(rootPath + "/langs") addMissingLines() loadPoFiles("in") #dumpTranslations() sorting() saveFiles(rootPath + "/langs", "out") os.rename("out/"+defaultLang+".pot", "serverdata.pot")