From a3974f48a0244f8fdadee3086e62ee2cbf60d0d6 Mon Sep 17 00:00:00 2001 From: Yorik van Havre Date: Fri, 23 Jan 2015 00:00:47 -0200 Subject: [PATCH] Added utility script to manage crowdin stuff --- src/Tools/updatecrowdin.py | 184 +++++++++++++++++++++++++++++++++++++ 1 file changed, 184 insertions(+) create mode 100755 src/Tools/updatecrowdin.py diff --git a/src/Tools/updatecrowdin.py b/src/Tools/updatecrowdin.py new file mode 100755 index 0000000000..c53f4d9d32 --- /dev/null +++ b/src/Tools/updatecrowdin.py @@ -0,0 +1,184 @@ +#!/usr/bin/python + +#*************************************************************************** +#* * +#* Copyright (c) 2015 Yorik van Havre * +#* * +#* This program is free software; you can redistribute it and/or modify * +#* it under the terms of the GNU Library General Public License (LGPL) * +#* as published by the Free Software Foundation; either version 2 of * +#* the License, or (at your option) any later version. * +#* for detail see the LICENCE text file. * +#* * +#* This program is distributed in the hope that it will be useful, * +#* but WITHOUT ANY WARRANTY; without even the implied warranty of * +#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +#* GNU Library General Public License for more details. * +#* * +#* You should have received a copy of the GNU Library General Public * +#* License along with this program; if not, write to the Free Software * +#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +#* USA * +#* * +#*************************************************************************** + + +''' +This utility offers several commands to interact with the FreeCAD project on crowdin. +For it to work, you need a .crowdin-freecad file in your user's folder, that contains +the API key that gives access to the crowdin FreeCAD project. + +Usage: + + updatecrowdin.py command + +Available commands: + + status: prints a status of the translations + update: updates crowdin the current version of .ts files found in the source code + build: builds a new downloadable package on crowdin with all trasnlated strings + download: downloads the latest build + +Example: + + ./updatecrowdin.py update + +''' + +# See crowdin API docs at https://crowdin.com/page/api + + + +import sys,os,xml.sax,pycurl,StringIO + + +files = [ ["Arch.ts", "/Mod/Arch/Resources/translations/Arch.ts"], + ["Assembly.ts", "/Mod/Assembly/Gui/Resources/translations/Assembly_de.ts"], + ["Complete.ts", "/Mod/Complete/Gui/Resources/translations/Complete_de.ts"], + ["draft.ts", "/Mod/Draft/Resources/translations/Draft.ts"], + ["Drawing.ts", "/Mod/Drawing/Gui/Resources/translations/Drawing_de.ts"], + ["Fem.ts", "/Mod/Fem/Gui/Resources/translations/Fem_de.ts"], + ["FreeCAD.ts", "/Gui/Language/FreeCAD.ts"], + ["Image.ts", "/Mod/Image/Gui/Resources/translations/Image_de.ts"], + ["Mesh.ts", "/Mod/Mesh/Gui/Resources/translations/Mesh_de.ts"], + ["MeshPart.ts", "/Mod/MeshPart/Gui/Resources/translations/MeshPart_de.ts"], + ["OpenSCAD.ts", "/Mod/OpenSCAD/Resources/translations/OpenSCAD.ts"], + ["Part.ts", "/Mod/Part/Gui/Resources/translations/Part_de.ts"], + ["PartDesign.ts", "/Mod/PartDesign/Gui/Resources/translations/PartDesign_de.ts"], + ["Plot.ts", "/Mod/Plot/resources/translations/Plot.ts"], + ["Points.ts", "/Mod/Points/Gui/Resources/translations/Points_de.ts"], + ["Raytracing.ts", "/Mod/Raytracing/Gui/Resources/translations/Raytracing_de.ts"], + ["ReverseEngineering.ts","/Mod/ReverseEngineering/Gui/Resources/translations/ReverseEngineering_de.ts"], + ["Robot.ts", "/Mod/Robot/Gui/Resources/translations/Robot_de.ts"], + ["Ship.ts", "/Mod/Ship/resources/translations/Ship.ts"], + ["Sketcher.ts", "/Mod/Sketcher/Gui/Resources/translations/Sketcher_de.ts"], + ["StartPage.ts", "/Mod/Start/Gui/Resources/translations/StartPage.ts"], + ["Test.ts", "/Mod/Test/Gui/Resources/translations/Test_de.ts"], + ["Web.ts", "/Mod/Web/Gui/Resources/translations/Web.ts"] ] + + +# handler for the command responses +class ResponseHandler( xml.sax.ContentHandler ): + + def __init__(self): + self.current = "" + self.data = "" + self.translated = 1 + self.total = 1 + + def startElement(self, tag, attributes): + self.current = tag + if tag == "file": + self.data += attributes["status"] + elif tag == "error": + self.data == "Error: " + + def endElement(self, tag): + if self.current in ["language","success","error"]: + self.data = "" + self.translated = 1 + self.total = 1 + self.current = "" + + def characters(self, content): + if self.current == "name": + self.data += content + elif self.current == "phrases": + self.total = int(content) + elif self.current == "translated": + self.translated = int(content) + pc = int((float(self.translated)/self.total)*100) + self.data += " : " + str(pc) + "%\n" + elif self.current == "message": + self.data += content + + + +if __name__ == "__main__": + + # only one argument allowed + arg = sys.argv[1:] + if len(arg) != 1: + print __doc__ + sys.exit() + arg = arg[0] + + # getting API key stored in ~/.crowdin-freecad + configfile = os.path.expanduser("~")+os.sep+".crowdin-freecad" + if not os.path.exists(configfile): + print "Config file not found!" + sys.exit() + f = open(configfile) + url = "https://api.crowdin.com/api/project/freecad/" + key = "?key="+f.read().strip() + f.close() + + if arg == "status": + c = pycurl.Curl() + c.setopt(pycurl.URL, url+"status"+key+"&xml") + b = StringIO.StringIO() + c.setopt(pycurl.WRITEFUNCTION, b.write) + c.perform() + c.close() + handler = ResponseHandler() + xml.sax.parseString(b.getvalue(),handler) + print handler.data + + elif arg == "build": + print "Building (warning, this can be invoked only once per 30 minutes)..." + c = pycurl.Curl() + c.setopt(pycurl.URL, url+"export"+key) + b = StringIO.StringIO() + c.setopt(pycurl.WRITEFUNCTION, b.write) + c.perform() + c.close() + handler = ResponseHandler() + xml.sax.parseString(b.getvalue(),handler) + print handler.data + + elif arg == "download": + print "Downloading all.zip in current directory..." + cmd = "wget "+url+"download/all.zip"+key + os.system(cmd) + + elif arg == "update": + basepath = os.path.dirname(os.path.abspath(".")) + for f in files: + print "Sending ",f[0],"..." + c = pycurl.Curl() + fields = [('files['+f[0]+']', (c.FORM_FILE, basepath+f[1]))] + c.setopt(pycurl.URL, url+"update-file"+key) + c.setopt(pycurl.HTTPPOST, fields) + b = StringIO.StringIO() + c.setopt(pycurl.WRITEFUNCTION, b.write) + c.perform() + c.close() + print b.getvalue() + handler = ResponseHandler() + xml.sax.parseString(b.getvalue(),handler) + print handler.data + + else: + print __doc__ + +