summaryrefslogblamecommitdiff
path: root/lang/updatelang.py
blob: aa36823d6c5f0e8ee7a2c91f964c9485f25c7add (plain) (tree)














































































































































































































































































































































































































                                                                                                          
#! /usr/bin/env python2.7
# -*- 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<str>[^\"]+)[\"]")
strre3 = re.compile("[\t +(]getitemlink[(][\"](?P<str>[^\"]+)[\"][)]")
strre2 = re.compile("^[^/](.+)([^\t]+)[\t](script|shop|trader|cashshop)[\t](?P<str>[^\t]+)[\t]([\w\d]+),")
strre4 = re.compile("[\t +(]lg[(][\"](?P<str>[^\"]+)[\"][)]")
strre5 = re.compile("[\t +(]getitemname[(][\"](?P<str>[^\"]+)[\"][)]")
strre6 = re.compile("[\t ]mesn[ ][\"](?P<str>[^\"]+)[\"]")
strre7 = re.compile("[\t +(]lg[(][\"](?P<str1>[^\"]+)[\"],([ ]*)[\"](?P<str2>[^\"]+)[\"]")
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")