SuperTuxKart 1.5 upstream source (from official release tarball)
This commit is contained in:
@@ -0,0 +1 @@
|
||||
*.sh -crlf
|
||||
@@ -0,0 +1,3 @@
|
||||
transifex
|
||||
tx.exe
|
||||
gui_strings.h
|
||||
+6887
File diff suppressed because it is too large
Load Diff
+6866
File diff suppressed because it is too large
Load Diff
+6850
File diff suppressed because it is too large
Load Diff
+6847
File diff suppressed because it is too large
Load Diff
+6872
File diff suppressed because it is too large
Load Diff
+6477
File diff suppressed because it is too large
Load Diff
+6849
File diff suppressed because it is too large
Load Diff
+6866
File diff suppressed because it is too large
Load Diff
+6861
File diff suppressed because it is too large
Load Diff
+6851
File diff suppressed because it is too large
Load Diff
+6876
File diff suppressed because it is too large
Load Diff
+6483
File diff suppressed because it is too large
Load Diff
+6866
File diff suppressed because it is too large
Load Diff
+6862
File diff suppressed because it is too large
Load Diff
+6471
File diff suppressed because it is too large
Load Diff
+6475
File diff suppressed because it is too large
Load Diff
Executable
+98
@@ -0,0 +1,98 @@
|
||||
import xml.dom.minidom
|
||||
import sys
|
||||
import codecs
|
||||
|
||||
f = open('./data/po/gui_strings.h', 'w')
|
||||
f.write(codecs.BOM_UTF8.decode('utf-8'))
|
||||
|
||||
def traverse(file, node, isChallenge, isGP, isKart, isTrack, isAchievements, level=0):
|
||||
|
||||
for e in node.childNodes:
|
||||
if e.localName == None:
|
||||
continue
|
||||
|
||||
#print ' '*level, e.localName
|
||||
|
||||
comment = None
|
||||
if e.hasAttribute("I18N"):
|
||||
comment = e.getAttribute("I18N")
|
||||
|
||||
if e.localName == "subtitle" and e.hasAttribute("text") and len(e.getAttribute("text")) > 0:
|
||||
#print "Label=", e.getAttribute("name"), " Comment=", comment
|
||||
line = ""
|
||||
if comment == None:
|
||||
line += "//I18N: Cutscene subtitle from " + file + "\n_(\"" + e.getAttribute("text") + "\")\n\n"
|
||||
else:
|
||||
line += "//I18N: Cutscene subtitle from " + file + "\n//I18N: " + comment + "\n_(\"" + e.getAttribute("text") + "\");\n\n"
|
||||
|
||||
f.write(line)
|
||||
|
||||
if isChallenge or isGP or isKart or isTrack or isAchievements:
|
||||
if isTrack and e.hasAttribute("internal") and e.getAttribute("internal") == "Y": continue
|
||||
if e.hasAttribute("name") and len(e.getAttribute("name")) > 0:
|
||||
#print "Label=", e.getAttribute("name"), " Comment=", comment
|
||||
line = ""
|
||||
if comment == None:
|
||||
line += "//I18N: " + file + "\n_(\"" + e.getAttribute("name") + "\")\n\n"
|
||||
else:
|
||||
line += "//I18N: File : " + file + "\n//I18N: " + comment + "\n_(\"" + e.getAttribute("name") + "\");\n\n"
|
||||
|
||||
f.write(line)
|
||||
|
||||
# challenges and GPs can have a description file; karts don't
|
||||
if e.hasAttribute("description") and len(e.getAttribute("description")) > 0:
|
||||
# print "Label=", e.getAttribute("description"), " Comment=", comment
|
||||
line = ""
|
||||
if comment == None:
|
||||
line += "//I18N: " + file + "\n_(\"" + e.getAttribute("description") + "\")\n\n"
|
||||
else:
|
||||
line += "//I18N: File : " + file + "\n//I18N: " + comment + "\n_(\"" + e.getAttribute("description") + "\");\n\n"
|
||||
|
||||
f.write(line)
|
||||
else:
|
||||
if e.nodeName == "string" and e.hasAttribute("name") and e.getAttribute("name").startswith("po_") and e.firstChild is not None:
|
||||
line = "//I18N: In Android UI, " + e.getAttribute("name") + "\n_(\"" + e.firstChild.nodeValue + "\")\n\n"
|
||||
f.write(line)
|
||||
elif e.hasAttribute("text") and len(e.getAttribute("text")) > 0:
|
||||
# print "Label=", e.getAttribute("text"), " Comment=", comment
|
||||
line = ""
|
||||
if comment == None:
|
||||
line += "//I18N: " + file + "\n_(\"" + e.getAttribute("text").replace("\"", "\\\"") + "\")\n\n"
|
||||
else:
|
||||
line += "//I18N: " + file + "\n//I18N: " + comment + "\n_(\"" + e.getAttribute("text") + "\");\n\n"
|
||||
f.write(line)
|
||||
|
||||
# don't recurse in children nodes for karts, they can contain sounds, etc. that should not be translated
|
||||
if not isKart:
|
||||
traverse(file, e, isChallenge, isGP, isKart, isTrack, isAchievements, level+1)
|
||||
|
||||
filenames = sys.argv[1:]
|
||||
for file in filenames:
|
||||
#print "Parsing", file
|
||||
|
||||
isChallenge = False
|
||||
isGP = False
|
||||
isKart = False
|
||||
isTrack = False
|
||||
isAchievements = False
|
||||
|
||||
if file.endswith(".challenge"):
|
||||
isChallenge = True
|
||||
if file.endswith(".grandprix"):
|
||||
isGP = True
|
||||
if file.endswith("kart.xml"):
|
||||
isKart = True
|
||||
if file.endswith("track.xml"):
|
||||
isTrack = True
|
||||
if file.endswith("achievements.xml"):
|
||||
isAchievements = True
|
||||
|
||||
try:
|
||||
doc = xml.dom.minidom.parse(file)
|
||||
except Exception as ex:
|
||||
print("============================================")
|
||||
print("/!\\ Expat doesn't like ", file, "! Error=", type(ex), " (", ex.args, ")")
|
||||
print("============================================")
|
||||
|
||||
traverse(file, doc, isChallenge, isGP, isKart, isTrack, isAchievements)
|
||||
|
||||
+6470
File diff suppressed because it is too large
Load Diff
+6850
File diff suppressed because it is too large
Load Diff
+6848
File diff suppressed because it is too large
Load Diff
+6883
File diff suppressed because it is too large
Load Diff
+6476
File diff suppressed because it is too large
Load Diff
+6492
File diff suppressed because it is too large
Load Diff
+6486
File diff suppressed because it is too large
Load Diff
+6853
File diff suppressed because it is too large
Load Diff
+6869
File diff suppressed because it is too large
Load Diff
+6849
File diff suppressed because it is too large
Load Diff
+6478
File diff suppressed because it is too large
Load Diff
+6856
File diff suppressed because it is too large
Load Diff
+6474
File diff suppressed because it is too large
Load Diff
+6849
File diff suppressed because it is too large
Load Diff
+6498
File diff suppressed because it is too large
Load Diff
+6865
File diff suppressed because it is too large
Load Diff
+6460
File diff suppressed because it is too large
Load Diff
+6845
File diff suppressed because it is too large
Load Diff
+6849
File diff suppressed because it is too large
Load Diff
+6469
File diff suppressed because it is too large
Load Diff
+6501
File diff suppressed because it is too large
Load Diff
+6459
File diff suppressed because it is too large
Load Diff
+6849
File diff suppressed because it is too large
Load Diff
+6869
File diff suppressed because it is too large
Load Diff
+6475
File diff suppressed because it is too large
Load Diff
+6847
File diff suppressed because it is too large
Load Diff
+6850
File diff suppressed because it is too large
Load Diff
+6476
File diff suppressed because it is too large
Load Diff
+6854
File diff suppressed because it is too large
Load Diff
+6847
File diff suppressed because it is too large
Load Diff
+6470
File diff suppressed because it is too large
Load Diff
+6467
File diff suppressed because it is too large
Load Diff
+6869
File diff suppressed because it is too large
Load Diff
+6865
File diff suppressed because it is too large
Load Diff
+6869
File diff suppressed because it is too large
Load Diff
+6857
File diff suppressed because it is too large
Load Diff
+6873
File diff suppressed because it is too large
Load Diff
+6849
File diff suppressed because it is too large
Load Diff
+6492
File diff suppressed because it is too large
Load Diff
+6866
File diff suppressed because it is too large
Load Diff
+6467
File diff suppressed because it is too large
Load Diff
+6865
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+6864
File diff suppressed because it is too large
Load Diff
+6468
File diff suppressed because it is too large
Load Diff
+6476
File diff suppressed because it is too large
Load Diff
+6463
File diff suppressed because it is too large
Load Diff
+6855
File diff suppressed because it is too large
Load Diff
+6461
File diff suppressed because it is too large
Load Diff
+6500
File diff suppressed because it is too large
Load Diff
Executable
+236
@@ -0,0 +1,236 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
|
||||
def traslate_po(po, translation):
|
||||
search = 'msgid "' + translation + '"'
|
||||
idx = po.find(search)
|
||||
if idx == -1:
|
||||
return ''
|
||||
# 9 characters after msgid "xxx" for the translated message
|
||||
begin = idx + len(search) + 9
|
||||
# Search next " with newline
|
||||
end = po.find('"\n', begin)
|
||||
if end == -1:
|
||||
return ''
|
||||
return po[begin : end]
|
||||
|
||||
STK_DESCRIPTION = 'A 3D open-source kart racing game'
|
||||
STK_DESKTOP_FILE_P1 = """[Desktop Entry]
|
||||
"""
|
||||
# Split it to avoid SuperTuxKart being translated
|
||||
STK_DESKTOP_FILE_P2 = """Name=SuperTuxKart
|
||||
Icon=supertuxkart
|
||||
"""
|
||||
STK_DESKTOP_FILE_P3 = """#I18N: Generic name in desktop file entry, summary in AppData and short description in Google Play
|
||||
GenericName=""" + STK_DESCRIPTION + """
|
||||
Exec=supertuxkart
|
||||
Terminal=false
|
||||
StartupNotify=false
|
||||
Type=Application
|
||||
Categories=Game;ArcadeGame;
|
||||
#I18N: Keywords in desktop entry, translators please keep it separated with semicolons
|
||||
Keywords=tux;game;race;
|
||||
PrefersNonDefaultGPU=true
|
||||
"""
|
||||
|
||||
desktop_file = open('supertuxkart.desktop', 'w')
|
||||
desktop_file.write(STK_DESKTOP_FILE_P1 + STK_DESKTOP_FILE_P3)
|
||||
desktop_file.close()
|
||||
|
||||
STK_APPDATA_P1 = 'Karts. Nitro. Action! SuperTuxKart is a 3D open-source arcade racer \
|
||||
with a variety of characters, tracks, and modes to play. \
|
||||
Our aim is to create a game that is more fun than realistic, \
|
||||
and provide an enjoyable experience for all ages.'
|
||||
STK_APPDATA_P2 = 'We have several tracks with various themes for players to enjoy, \
|
||||
from driving underwater, rural farmlands, jungles or even in space! \
|
||||
Try your best while avoiding other karts as they may overtake you, \
|
||||
but don\'t eat the bananas! Watch for bowling balls, plungers, bubble gum, \
|
||||
and cakes thrown by your opponents.'
|
||||
STK_APPDATA_P3 = 'You can do a single race against other karts, \
|
||||
compete in one of several Grand Prix, \
|
||||
try to beat the high score in time trials on your own, \
|
||||
play battle mode against the computer or your friends, \
|
||||
and more! For a greater challenge, join online and meet players from all over the world \
|
||||
and prove your racing skills!'
|
||||
# Used in google play only for now
|
||||
STK_APPDATA_P4 = 'This game has no ads.'
|
||||
# Used in google play beta only for now
|
||||
STK_APPDATA_P5 = 'This is an unstable version of SuperTuxKart that contains latest improvements. \
|
||||
It is released mainly for testing, to make stable STK as good as possible.'
|
||||
STK_APPDATA_P6 = 'This version can be installed in parallel with the stable version on the device.'
|
||||
STK_APPDATA_P7 = 'If you need more stability, consider using the stable version: %s'
|
||||
STK_STABLE_URL = 'https://play.google.com/store/apps/details?id=org.supertuxkart.stk'
|
||||
|
||||
STK_APPDATA_FILE_1 = """<?xml version=\"1.0\" encoding=\"UTF-8\"?>
|
||||
<component type=\"desktop-application\">
|
||||
<id>net.supertuxkart.SuperTuxKart</id>
|
||||
<metadata_license>CC0-1.0</metadata_license>
|
||||
<project_license>GPL-3.0+</project_license>
|
||||
<launchable type="desktop-id">supertuxkart.desktop</launchable>
|
||||
"""
|
||||
# Split it to avoid SuperTuxKart being translated
|
||||
STK_APPDATA_FILE_2 = """ <name>SuperTuxKart</name>
|
||||
"""
|
||||
STK_APPDATA_FILE_3 = """ <summary>""" + STK_DESCRIPTION + """</summary>
|
||||
<description>
|
||||
<p>
|
||||
""" + STK_APPDATA_P1 + """
|
||||
</p>
|
||||
<p>
|
||||
""" + STK_APPDATA_P2 + """
|
||||
</p>
|
||||
<p>
|
||||
""" + STK_APPDATA_P3 + """
|
||||
</p>
|
||||
"""
|
||||
STK_APPDATA_FILE_4 = """ <p>
|
||||
""" + STK_APPDATA_P4 + """
|
||||
</p>
|
||||
<p>
|
||||
""" + STK_APPDATA_P5 + """
|
||||
</p>
|
||||
<p>
|
||||
""" + STK_APPDATA_P6 + """
|
||||
</p>
|
||||
<p>
|
||||
""" + STK_APPDATA_P7 + """
|
||||
</p>
|
||||
"""
|
||||
STK_APPDATA_FILE_5 = """ </description>
|
||||
<screenshots>
|
||||
<screenshot type=\"default\">
|
||||
<image>https://supertuxkart.net/assets/wiki/STK1.3_1.jpg</image>
|
||||
<caption>Normal Race</caption>
|
||||
</screenshot>
|
||||
<screenshot>
|
||||
<image>https://supertuxkart.net/assets/wiki/STK1.3_5.jpg</image>
|
||||
<caption>Battle</caption>
|
||||
</screenshot>
|
||||
<screenshot>
|
||||
<image>https://supertuxkart.net/assets/wiki/STK1.3_6.jpg</image>
|
||||
<caption>Soccer</caption>
|
||||
</screenshot>
|
||||
</screenshots>
|
||||
<developer_name>SuperTuxKart Team</developer_name>
|
||||
<update_contact>supertuxkart-devel@lists.sourceforge.net</update_contact>
|
||||
<url type=\"homepage\">https://supertuxkart.net</url>
|
||||
<url type=\"bugtracker\">https://github.com/supertuxkart/stk-code/issues</url>
|
||||
<url type=\"donation\">https://supertuxkart.net/Donate</url>
|
||||
<url type=\"help\">https://supertuxkart.net/Community</url>
|
||||
<url type=\"translate\">https://supertuxkart.net/Translating_STK</url>
|
||||
<url type="faq">https://supertuxkart.net/FAQ</url>
|
||||
<url type="vcs-browser">https://github.com/supertuxkart/stk-code</url>
|
||||
<url type="contribute">https://supertuxkart.net/Community</url>
|
||||
<content_rating type=\"oars-1.1\">
|
||||
<content_attribute id=\"violence-cartoon\">mild</content_attribute>
|
||||
<content_attribute id=\"social-chat\">intense</content_attribute>
|
||||
</content_rating>
|
||||
<languages>
|
||||
"""
|
||||
STK_APPDATA_FILE_6 = """ </languages>
|
||||
<provides>
|
||||
<binary>supertuxkart</binary>
|
||||
</provides>
|
||||
<supports>
|
||||
<control>pointing</control>
|
||||
<control>keyboard</control>
|
||||
<control>gamepad</control>
|
||||
</supports>
|
||||
<requires>
|
||||
<memory>1024</memory>
|
||||
</requires>
|
||||
</component>
|
||||
"""
|
||||
|
||||
appdata_file = open('net.supertuxkart.SuperTuxKart.metainfo.xml', 'w')
|
||||
appdata_file.write(STK_APPDATA_FILE_1 + STK_APPDATA_FILE_3 + STK_APPDATA_FILE_4 \
|
||||
+ STK_APPDATA_FILE_5 + STK_APPDATA_FILE_6)
|
||||
appdata_file.close()
|
||||
|
||||
os.system('xgettext -j -d supertuxkart --add-comments=\"I18N:\" \
|
||||
-p ./data/po -o supertuxkart.pot \
|
||||
--package-name=supertuxkart supertuxkart.desktop net.supertuxkart.SuperTuxKart.metainfo.xml')
|
||||
|
||||
desktop_file = open('supertuxkart.desktop', 'w')
|
||||
desktop_file.write(STK_DESKTOP_FILE_P1 + STK_DESKTOP_FILE_P2 + STK_DESKTOP_FILE_P3)
|
||||
desktop_file.close()
|
||||
|
||||
appdata = STK_APPDATA_FILE_1 + STK_APPDATA_FILE_2 + STK_APPDATA_FILE_3
|
||||
# Skip google play message
|
||||
appdata += STK_APPDATA_FILE_5
|
||||
|
||||
# Manually copy zh_TW to zh_HK for fallback
|
||||
shutil.copyfile('./data/po/zh_TW.po', './data/po/zh_HK.po')
|
||||
shutil.rmtree('./google_play_msg', ignore_errors = True)
|
||||
|
||||
lingas = open('./data/po/LINGUAS', 'w')
|
||||
po_list = [f for f in os.listdir('./data/po/') if f.endswith('.po')]
|
||||
po_list.sort(reverse = False);
|
||||
fr_percentage = 0
|
||||
for po_filename in po_list:
|
||||
po_file = open('./data/po/' + po_filename, 'r')
|
||||
po = po_file.read()
|
||||
po_file.close()
|
||||
# Remove all newlines in msgid
|
||||
po = po.replace('"\n"', '')
|
||||
|
||||
cur_lang = po_filename.removesuffix('.po')
|
||||
if cur_lang != 'en':
|
||||
lingas.write(cur_lang + '\n')
|
||||
total_str = po.count('msgid "')
|
||||
untranslated_str = po.count('msgstr ""')
|
||||
translated_str = total_str - untranslated_str
|
||||
percentage = int(translated_str / total_str * 100.0)
|
||||
|
||||
# Special handling for fr_CA, list has been sorted
|
||||
if cur_lang == 'fr':
|
||||
fr_percentage = percentage
|
||||
elif cur_lang == 'fr_CA':
|
||||
percentage = fr_percentage
|
||||
|
||||
if percentage == 0:
|
||||
continue
|
||||
elif percentage != 100:
|
||||
appdata += ' <lang percentage="' + str(percentage) + '">' + cur_lang +'</lang>\n'
|
||||
else:
|
||||
appdata += ' <lang>' + cur_lang +'</lang>\n'
|
||||
|
||||
if cur_lang != 'fr_CA' and len(sys.argv) == 2 and sys.argv[1] == '--generate-google-play-msg':
|
||||
desc = traslate_po(po, STK_DESCRIPTION)
|
||||
p1 = traslate_po(po, STK_APPDATA_P1)
|
||||
p2 = traslate_po(po, STK_APPDATA_P2)
|
||||
p3 = traslate_po(po, STK_APPDATA_P3)
|
||||
p4 = traslate_po(po, STK_APPDATA_P4)
|
||||
p5 = traslate_po(po, STK_APPDATA_P5)
|
||||
p6 = traslate_po(po, STK_APPDATA_P6)
|
||||
p7 = traslate_po(po, STK_APPDATA_P7)
|
||||
if desc and p1 and p2 and p3 and p4 and p5 and p6 and p7:
|
||||
os.makedirs('./google_play_msg/' + cur_lang)
|
||||
p7 = p7.replace('%s', STK_STABLE_URL)
|
||||
short = open('./google_play_msg/' + cur_lang + '/short.txt', 'w')
|
||||
short.write(desc)
|
||||
short.close()
|
||||
full = open('./google_play_msg/' + cur_lang + '/full.txt', 'w')
|
||||
full.write(p1 + '\n\n' + p2 + '\n\n' + p3 + '\n\n' + p4)
|
||||
full.close()
|
||||
full_beta = open('./google_play_msg/' + cur_lang + '/full_beta.txt', 'w')
|
||||
full_beta.write(p1 + '\n\n' + p2 + '\n\n' + p3 + '\n\n' + p4 +
|
||||
'\n\n---\n\n' + p5 + '\n\n' + p6 + '\n\n' + p7)
|
||||
full_beta.close()
|
||||
|
||||
lingas.close()
|
||||
appdata += STK_APPDATA_FILE_6
|
||||
appdata_file = open('net.supertuxkart.SuperTuxKart.metainfo.xml', 'w')
|
||||
appdata_file.write(appdata)
|
||||
appdata_file.close()
|
||||
|
||||
os.system('msgfmt --desktop -d data/po --template supertuxkart.desktop -o data/supertuxkart.desktop')
|
||||
os.system('msgfmt --xml -d data/po --template net.supertuxkart.SuperTuxKart.metainfo.xml -o data/net.supertuxkart.SuperTuxKart.metainfo.xml')
|
||||
os.remove('./supertuxkart.desktop')
|
||||
os.remove('./net.supertuxkart.SuperTuxKart.metainfo.xml')
|
||||
os.remove('./data/po/LINGUAS')
|
||||
os.remove('./data/po/zh_HK.po')
|
||||
Executable
+125
@@ -0,0 +1,125 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
# A simple script that adds all authors from transifex, which are
|
||||
# listed in comments at the beginning of the file, to the
|
||||
# 'translator-credits' translations - where launchpad added them
|
||||
# and which are shown in stk.
|
||||
#
|
||||
# First rename the transifex files:
|
||||
# for i in supertuxkartpot_*; do mv $i ${i##supertuxkartpot_}; done
|
||||
#
|
||||
# Usage: update_po_authors.py PATH_TO/LANGUAGE.po
|
||||
#
|
||||
# IMPORTANT note: this script must be run on a file downloaded
|
||||
# from transifex, not on a file on which this script had
|
||||
# been run before (otherwise the transifex authors would
|
||||
# be added again and again)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
#
|
||||
# Less important note: The specified file is overwritten without
|
||||
# a backup! Make sure the git status is unmodified.
|
||||
#
|
||||
|
||||
|
||||
import re
|
||||
import sys
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) < 2:
|
||||
print("Usage: getpo_authors.py PATH_TO_PO_FILE")
|
||||
sys.exit(-1)
|
||||
|
||||
for filename in sys.argv[1:]:
|
||||
print("Processing file %s" % filename)
|
||||
f = open(filename, "r")
|
||||
if not f:
|
||||
print("Can not find", filename)
|
||||
exit
|
||||
lines = f.readlines()
|
||||
|
||||
f.close()
|
||||
|
||||
# There are two sources of contributors:
|
||||
# 1) Entries in the header from transifex (after "Translators:"
|
||||
# till the first msgid string.
|
||||
# 2) Entries as "translator-credits". These shouldn't be there,
|
||||
# but sometimes occur (e.g. because an old version of this
|
||||
# script was used that did not support these entries).
|
||||
# Assemble all those entries in one line
|
||||
|
||||
found = 0
|
||||
contributions = ""
|
||||
line_count = 0
|
||||
new_authors = []
|
||||
author_list = []
|
||||
|
||||
# Find new and old authors with a simple finite state machine:
|
||||
# ============================================================
|
||||
i = 0
|
||||
while i < len(lines):
|
||||
line = lines[i][:-1] # remove \n
|
||||
i = i + 1
|
||||
if line=="# Translators:":
|
||||
while i <len(lines) and lines[i][:5]!="msgid":
|
||||
line = lines[i][:-1] # remove \n
|
||||
if line [:14]!="# FIRST AUTHOR":
|
||||
new_authors.append(line[2:])
|
||||
author_list.append(line[2:])
|
||||
i = i + 1
|
||||
|
||||
elif line[:26] == "msgid \"translator-credits\"":
|
||||
line = lines[i][:-2] # remove \"\n at end of line
|
||||
# Ignore the fist entry (which is "msgstr ...").
|
||||
authors = line.split("\\n")[1:]
|
||||
for j in range(len(authors)):
|
||||
s = authors[j].strip()
|
||||
if s!="":
|
||||
author_list.append(s)
|
||||
# Then remove the msgid and msgstr
|
||||
del lines[i] # msgstr
|
||||
del lines[i-1] # msgid
|
||||
del lines[i-2] # filename/line number info
|
||||
del lines[i-3] # empty line
|
||||
|
||||
|
||||
# Delete all email addresses and URLs (esp. old launchpads)
|
||||
# ---------------------------------------------------------
|
||||
email = re.compile(r" *[^ ]+@[^ ]+ *")
|
||||
url = re.compile(r" *https?://[^ ]*")
|
||||
for i, author in enumerate(author_list):
|
||||
g = email.search(author)
|
||||
if g:
|
||||
author_list[i] = author[:g.start()] +", " \
|
||||
+ author[g.end():]
|
||||
g = url.search(author)
|
||||
if g:
|
||||
author_list[i] = author[:g.start()] \
|
||||
+ author[g.end():]
|
||||
|
||||
# Remove duplicated entries
|
||||
# -------------------------
|
||||
d = {}
|
||||
new_list = []
|
||||
for i, author in enumerate(author_list):
|
||||
if not d.get(author, None):
|
||||
new_list.append(author)
|
||||
d[author]=1
|
||||
author_list = new_list
|
||||
|
||||
all_authors_string = reduce(lambda x,y: x+"\\n"+y, author_list, "")
|
||||
|
||||
credits_line = "msgstr \"Launchpad Contributions:%s\"\n"%all_authors_string
|
||||
|
||||
lines.append("\n")
|
||||
lines.append("#: src/states_screens/credits.cpp:209\n")
|
||||
lines.append("msgid \"translator-credits\"\n")
|
||||
lines.append(credits_line)
|
||||
|
||||
|
||||
# Overwrite old file
|
||||
f = open(filename, "w")
|
||||
for i in lines:
|
||||
f.write(i)
|
||||
f.close()
|
||||
|
||||
print("Done with %s,"% filename)
|
||||
|
||||
Executable
+81
@@ -0,0 +1,81 @@
|
||||
# run this script from the root directory to re-generate the .pot file
|
||||
#
|
||||
# ./data/po/update_pot.sh
|
||||
if [ -z "$PYTHON" ]; then
|
||||
PYTHON="python"
|
||||
fi
|
||||
|
||||
CPP_FILE_LIST="`find ./src \
|
||||
-name '*.cpp' -or \
|
||||
-name '*.c' -or \
|
||||
-name '*.hpp' -or \
|
||||
-name "*.h" | sort -n \
|
||||
`"
|
||||
XML_FILE_LIST="`find ./data \
|
||||
../stk-assets/tracks \
|
||||
../stk-assets/karts \
|
||||
../supertuxkart-assets/tracks \
|
||||
../supertuxkart-assets/karts \
|
||||
./android/res/values \
|
||||
-name 'achievements.xml' -or \
|
||||
-name 'tips.xml' -or \
|
||||
-name 'kart.xml' -or \
|
||||
-name 'track.xml' -or \
|
||||
-name 'scene.xml' -or \
|
||||
-name '*.challenge' -or \
|
||||
-name '*.grandprix' -or \
|
||||
-name 'strings.xml' -or \
|
||||
-name '*.stkgui' | sort -n \
|
||||
`"
|
||||
ANGELSCRIPT_FILE_LIST="`find ./data \
|
||||
../stk-assets/tracks \
|
||||
../supertuxkart-assets/tracks \
|
||||
-name '*.as' | sort -n \
|
||||
`"
|
||||
|
||||
echo "--------------------"
|
||||
echo " Source Files :"
|
||||
echo "--------------------"
|
||||
echo $CPP_FILE_LIST
|
||||
echo $ANGELSCRIPT_FILE_LIST
|
||||
|
||||
echo "--------------------"
|
||||
echo " XML Files :"
|
||||
echo "--------------------"
|
||||
echo $XML_FILE_LIST
|
||||
|
||||
# XML Files
|
||||
eval '$PYTHON ./data/po/extract_strings_from_XML.py $XML_FILE_LIST'
|
||||
|
||||
|
||||
|
||||
echo "---------------------------"
|
||||
echo " Generating .pot file..."
|
||||
|
||||
# XML Files
|
||||
xgettext -d supertuxkart --keyword=_ --add-comments="I18N:" \
|
||||
-p ./data/po -o supertuxkart.pot \
|
||||
--no-location --from-code=UTF-8 ./data/po/gui_strings.h \
|
||||
--package-name=supertuxkart
|
||||
|
||||
# C++ Files
|
||||
xgettext -j -d supertuxkart --keyword=_ --keyword=N_ --keyword=_LTR \
|
||||
--keyword=_C:1c,2 --keyword=_P:1,2 \
|
||||
--keyword=_CP:1c,2,3 --add-comments="I18N:" \
|
||||
-p ./data/po -o supertuxkart.pot $CPP_FILE_LIST \
|
||||
--package-name=supertuxkart
|
||||
|
||||
# Angelscript files (xgettext doesn't support AS so pretend it's c++)
|
||||
xgettext -j -d supertuxkart --keyword="translate" --add-comments="I18N:" \
|
||||
-p ./data/po -o supertuxkart.pot $ANGELSCRIPT_FILE_LIST \
|
||||
--package-name=supertuxkart --language=c++
|
||||
|
||||
# Desktop file and AppData
|
||||
if [ "$1" = "--generate-google-play-msg" ]; then
|
||||
data/po/update_desktop_file_appdata.py "--generate-google-play-msg"
|
||||
else
|
||||
data/po/update_desktop_file_appdata.py
|
||||
fi
|
||||
|
||||
echo " Done"
|
||||
echo "---------------------------"
|
||||
Executable
+66
@@ -0,0 +1,66 @@
|
||||
#!/usr/bin/env python
|
||||
# usage: update_translation.py [transifex token]
|
||||
import os
|
||||
import requests
|
||||
import sys
|
||||
import threading
|
||||
import time
|
||||
|
||||
text_headers = {
|
||||
"accept": "*/*",
|
||||
"content-type": "text/plain",
|
||||
"authorization": "Bearer " + sys.argv[1]
|
||||
}
|
||||
|
||||
json_headers = {
|
||||
"accept": "application/vnd.api+json",
|
||||
"content-type": "application/vnd.api+json",
|
||||
"authorization": "Bearer " + sys.argv[1]
|
||||
}
|
||||
|
||||
def get_translation(lang):
|
||||
payload = '{\"data\":{\"attributes\":{\"callback_url\":null,\"content_encoding\":\"text\",\"file_type\":\"default\",\"mode\":\"default\",\"pseudo\":false},\"relationships\":{\"language\":{\"data\":{\"type\":\"languages\",\"id\":\"l:' + lang + '\"}},\"resource\":{\"data\":{\"type\":\"resources\",\"id\":\"o:supertuxkart:p:supertuxkart:r:supertuxkartpot\"}}},\"type\":\"resource_translations_async_downloads\"}}'
|
||||
url = "https://rest.api.transifex.com/resource_translations_async_downloads"
|
||||
response = requests.post(url, data=payload, headers=json_headers)
|
||||
if not "data" in response.json().keys():
|
||||
return
|
||||
|
||||
if response.status_code == 202:
|
||||
location = response.headers["Content-Location"]
|
||||
if location:
|
||||
po_file = open(lang + ".po", "w")
|
||||
po_file.write(requests.get(location, headers=text_headers).text)
|
||||
po_file.close()
|
||||
print("Saving " + lang + ".po",)
|
||||
return
|
||||
|
||||
for t in range(0, 10):
|
||||
response = requests.get(url + "/" + response.json()["data"]["id"], headers=json_headers)
|
||||
if "application/json" in response.headers.get("Content-Type", ""):
|
||||
json = response.json()
|
||||
status = ""
|
||||
if "data" in json.keys():
|
||||
status = json["data"]["attributes"]["status"]
|
||||
if status == "failed" or t == 9:
|
||||
print(lang + " failed to download")
|
||||
break
|
||||
else:
|
||||
time.sleep(1)
|
||||
else:
|
||||
po_file = open(lang + ".po", "w")
|
||||
po_file.write(response.text)
|
||||
po_file.close()
|
||||
print("Saving " + lang + ".po",)
|
||||
break
|
||||
|
||||
threads = []
|
||||
for f in os.listdir("./"):
|
||||
if not f.endswith(".po"):
|
||||
continue
|
||||
lang = os.path.splitext(f)[0]
|
||||
threads.append(threading.Thread(target=get_translation, args=[lang]))
|
||||
|
||||
for t in threads:
|
||||
t.start()
|
||||
for t in threads:
|
||||
t.join()
|
||||
+6843
File diff suppressed because it is too large
Load Diff
+6848
File diff suppressed because it is too large
Load Diff
+6849
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user