SuperTuxKart 1.5 upstream source (from official release tarball)

This commit is contained in:
Benjamin
2026-06-11 20:04:02 +02:00
commit 2957e51aaa
8551 changed files with 1801800 additions and 0 deletions
+1
View File
@@ -0,0 +1 @@
*.sh -crlf
+3
View File
@@ -0,0 +1,3 @@
transifex
tx.exe
gui_strings.h
+6887
View File
File diff suppressed because it is too large Load Diff
+6866
View File
File diff suppressed because it is too large Load Diff
+6850
View File
File diff suppressed because it is too large Load Diff
+6847
View File
File diff suppressed because it is too large Load Diff
+6872
View File
File diff suppressed because it is too large Load Diff
+6477
View File
File diff suppressed because it is too large Load Diff
+6849
View File
File diff suppressed because it is too large Load Diff
+6866
View File
File diff suppressed because it is too large Load Diff
+6861
View File
File diff suppressed because it is too large Load Diff
+6851
View File
File diff suppressed because it is too large Load Diff
+6876
View File
File diff suppressed because it is too large Load Diff
+6483
View File
File diff suppressed because it is too large Load Diff
+6866
View File
File diff suppressed because it is too large Load Diff
+6862
View File
File diff suppressed because it is too large Load Diff
+6471
View File
File diff suppressed because it is too large Load Diff
+6475
View File
File diff suppressed because it is too large Load Diff
+98
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+6850
View File
File diff suppressed because it is too large Load Diff
+6848
View File
File diff suppressed because it is too large Load Diff
+6883
View File
File diff suppressed because it is too large Load Diff
+6476
View File
File diff suppressed because it is too large Load Diff
+6492
View File
File diff suppressed because it is too large Load Diff
+6486
View File
File diff suppressed because it is too large Load Diff
+6853
View File
File diff suppressed because it is too large Load Diff
+6869
View File
File diff suppressed because it is too large Load Diff
+6849
View File
File diff suppressed because it is too large Load Diff
+6478
View File
File diff suppressed because it is too large Load Diff
+6856
View File
File diff suppressed because it is too large Load Diff
+6474
View File
File diff suppressed because it is too large Load Diff
+6849
View File
File diff suppressed because it is too large Load Diff
+6498
View File
File diff suppressed because it is too large Load Diff
+6865
View File
File diff suppressed because it is too large Load Diff
+6460
View File
File diff suppressed because it is too large Load Diff
+6845
View File
File diff suppressed because it is too large Load Diff
+6849
View File
File diff suppressed because it is too large Load Diff
+6469
View File
File diff suppressed because it is too large Load Diff
+6501
View File
File diff suppressed because it is too large Load Diff
+6459
View File
File diff suppressed because it is too large Load Diff
+6849
View File
File diff suppressed because it is too large Load Diff
+6869
View File
File diff suppressed because it is too large Load Diff
+6475
View File
File diff suppressed because it is too large Load Diff
+6847
View File
File diff suppressed because it is too large Load Diff
+6850
View File
File diff suppressed because it is too large Load Diff
+6476
View File
File diff suppressed because it is too large Load Diff
+6854
View File
File diff suppressed because it is too large Load Diff
+6847
View File
File diff suppressed because it is too large Load Diff
+6470
View File
File diff suppressed because it is too large Load Diff
+6467
View File
File diff suppressed because it is too large Load Diff
+6869
View File
File diff suppressed because it is too large Load Diff
+6865
View File
File diff suppressed because it is too large Load Diff
+6869
View File
File diff suppressed because it is too large Load Diff
+6857
View File
File diff suppressed because it is too large Load Diff
+6873
View File
File diff suppressed because it is too large Load Diff
+6849
View File
File diff suppressed because it is too large Load Diff
+6492
View File
File diff suppressed because it is too large Load Diff
+6866
View File
File diff suppressed because it is too large Load Diff
+6467
View File
File diff suppressed because it is too large Load Diff
+6865
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+6864
View File
File diff suppressed because it is too large Load Diff
+6468
View File
File diff suppressed because it is too large Load Diff
+6476
View File
File diff suppressed because it is too large Load Diff
+6463
View File
File diff suppressed because it is too large Load Diff
+6855
View File
File diff suppressed because it is too large Load Diff
+6461
View File
File diff suppressed because it is too large Load Diff
+6500
View File
File diff suppressed because it is too large Load Diff
+236
View File
@@ -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')
+125
View File
@@ -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)
+81
View File
@@ -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 "---------------------------"
+66
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+6848
View File
File diff suppressed because it is too large Load Diff
+6849
View File
File diff suppressed because it is too large Load Diff