forked from openlp/openlp
Merge.
This commit is contained in:
commit
c2153bb6ae
@ -28,22 +28,22 @@
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
This script is used to maintain the translation files in OpenLP. It downloads
|
This script is used to maintain the translation files in OpenLP. It downloads
|
||||||
the latest translation files from the Pootle translation server, updates the
|
the latest translation files from the Transifex translation server, updates the
|
||||||
local translation files from both the source code and the files from Pootle,
|
local translation files from both the source code and the files from Transifex,
|
||||||
and can also generate the compiled translation files.
|
and can also generate the compiled translation files.
|
||||||
|
|
||||||
Create New Language
|
Create New Language
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
To create a new language, simply run this script with the ``-a`` command line
|
To create a new language, simply run this script with the ``-c`` command line
|
||||||
option::
|
option::
|
||||||
|
|
||||||
@:~$ ./translation_utils.py -a
|
@:~$ ./translation_utils.py -c
|
||||||
|
|
||||||
Update Translation Files
|
Update Translation Files
|
||||||
------------------------
|
------------------------
|
||||||
|
|
||||||
The best way to update the translations is to download the files from Pootle,
|
The best way to update the translations is to download the files from Transifex,
|
||||||
and then update the local files using both the downloaded files and the source.
|
and then update the local files using both the downloaded files and the source.
|
||||||
This is done easily via the ``-d``, ``-p`` and ``-u`` options::
|
This is done easily via the ``-d``, ``-p`` and ``-u`` options::
|
||||||
|
|
||||||
@ -51,20 +51,26 @@ This is done easily via the ``-d``, ``-p`` and ``-u`` options::
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
import os
|
import os
|
||||||
import urllib
|
import urllib2
|
||||||
import re
|
import re
|
||||||
from shutil import copy
|
from shutil import copy
|
||||||
|
from getpass import getpass
|
||||||
|
import base64
|
||||||
|
import json
|
||||||
|
import webbrowser
|
||||||
|
|
||||||
from optparse import OptionParser
|
from optparse import OptionParser
|
||||||
from PyQt4 import QtCore
|
from PyQt4 import QtCore
|
||||||
from BeautifulSoup import BeautifulSoup
|
from BeautifulSoup import BeautifulSoup
|
||||||
|
|
||||||
SERVER_URL = u'http://pootle.projecthq.biz/export/openlp/'
|
SERVER_URL = u'http://www.transifex.net/api/2/project/openlp/'
|
||||||
IGNORED_PATHS = [u'scripts']
|
IGNORED_PATHS = [u'scripts']
|
||||||
IGNORED_FILES = [u'setup.py']
|
IGNORED_FILES = [u'setup.py']
|
||||||
|
|
||||||
verbose_mode = False
|
verbose_mode = False
|
||||||
quiet_mode = False
|
quiet_mode = False
|
||||||
|
username = ''
|
||||||
|
password = ''
|
||||||
|
|
||||||
class Command(object):
|
class Command(object):
|
||||||
"""
|
"""
|
||||||
@ -172,35 +178,40 @@ def run(command):
|
|||||||
print_verbose(u'Error(s):\n%s' % process.readAllStandardError())
|
print_verbose(u'Error(s):\n%s' % process.readAllStandardError())
|
||||||
print_verbose(u'Output:\n%s' % process.readAllStandardOutput())
|
print_verbose(u'Output:\n%s' % process.readAllStandardOutput())
|
||||||
|
|
||||||
def update_export_at_pootle(source_filename):
|
|
||||||
"""
|
|
||||||
This is needed because of database and exported *.ts file can be out of sync
|
|
||||||
|
|
||||||
``source_filename``
|
|
||||||
The file to sync.
|
|
||||||
|
|
||||||
"""
|
|
||||||
language = source_filename[:-3]
|
|
||||||
REVIEW_URL = u'http://pootle.projecthq.biz/%s/openlp/review.html' % language
|
|
||||||
print_verbose(u'Accessing: %s' % (REVIEW_URL))
|
|
||||||
page = urllib.urlopen(REVIEW_URL)
|
|
||||||
page.close()
|
|
||||||
|
|
||||||
def download_translations():
|
def download_translations():
|
||||||
"""
|
"""
|
||||||
This method downloads the translation files from the Pootle server.
|
This method downloads the translation files from the Pootle server.
|
||||||
|
|
||||||
|
**Note:** URLs and headers need to remain strings, not unicode.
|
||||||
"""
|
"""
|
||||||
print_quiet(u'Download translation files from Pootle')
|
global username, password
|
||||||
page = urllib.urlopen(SERVER_URL)
|
if not username:
|
||||||
soup = BeautifulSoup(page)
|
username = raw_input(u'Transifex username: ')
|
||||||
languages = soup.findAll(text=re.compile(r'.*\.ts'))
|
if not password:
|
||||||
for language_file in languages:
|
password = getpass(u'Transifex password: ')
|
||||||
update_export_at_pootle(language_file)
|
print_quiet(u'Download translation files from Transifex')
|
||||||
for language_file in languages:
|
# First get the list of languages
|
||||||
|
url = SERVER_URL + 'resource/ents/'
|
||||||
|
base64string = base64.encodestring(
|
||||||
|
'%s:%s' % (username, password))[:-1]
|
||||||
|
auth_header = 'Basic %s' % base64string
|
||||||
|
request = urllib2.Request(url + '?details')
|
||||||
|
request.add_header('Authorization', auth_header)
|
||||||
|
print_verbose(u'Downloading list of languages from: %s' % url)
|
||||||
|
json_response = urllib2.urlopen(request)
|
||||||
|
json_dict = json.loads(json_response.read())
|
||||||
|
languages = [lang[u'code'] for lang in json_dict[u'available_languages']]
|
||||||
|
for language in languages:
|
||||||
|
lang_url = url + 'translation/%s/?file' % language
|
||||||
|
request = urllib2.Request(lang_url)
|
||||||
|
request.add_header('Authorization', auth_header)
|
||||||
filename = os.path.join(os.path.abspath(u'..'), u'resources', u'i18n',
|
filename = os.path.join(os.path.abspath(u'..'), u'resources', u'i18n',
|
||||||
language_file)
|
language + u'.ts')
|
||||||
print_verbose(u'Get Translation File: %s' % filename)
|
print_verbose(u'Get Translation File: %s' % filename)
|
||||||
urllib.urlretrieve(SERVER_URL + language_file, filename)
|
response = urllib2.urlopen(request)
|
||||||
|
fd = open(filename, u'w')
|
||||||
|
fd.write(response.read())
|
||||||
|
fd.close()
|
||||||
print_quiet(u' Done.')
|
print_quiet(u' Done.')
|
||||||
|
|
||||||
def prepare_project():
|
def prepare_project():
|
||||||
@ -252,7 +263,7 @@ def prepare_project():
|
|||||||
def update_translations():
|
def update_translations():
|
||||||
print_quiet(u'Update the translation files')
|
print_quiet(u'Update the translation files')
|
||||||
if not os.path.exists(os.path.join(os.path.abspath(u'..'), u'openlp.pro')):
|
if not os.path.exists(os.path.join(os.path.abspath(u'..'), u'openlp.pro')):
|
||||||
print u'You have no generated a project file yet, please run this ' + \
|
print u'You have not generated a project file yet, please run this ' + \
|
||||||
u'script with the -p option.'
|
u'script with the -p option.'
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
@ -274,24 +285,16 @@ def generate_binaries():
|
|||||||
print_quiet(u' Done.')
|
print_quiet(u' Done.')
|
||||||
|
|
||||||
|
|
||||||
def create_translation(language):
|
def create_translation():
|
||||||
"""
|
"""
|
||||||
This method creates a new translation file.
|
This method opens a browser to the OpenLP project page at Transifex so
|
||||||
|
that the user can request a new language.
|
||||||
``language``
|
|
||||||
The language file to create.
|
|
||||||
"""
|
"""
|
||||||
print_quiet(u'Create new Translation File')
|
print_quiet(u'Please request a new language at the OpenLP project on '
|
||||||
if not language.endswith(u'.ts'):
|
'Transifex.')
|
||||||
language += u'.ts'
|
webbrowser.open('https://www.transifex.net/projects/p/openlp/'
|
||||||
filename = os.path.join(os.path.abspath(u'..'), u'resources', u'i18n', language)
|
'resource/ents/')
|
||||||
urllib.urlretrieve(SERVER_URL + u'en.ts', filename)
|
print_quiet(u'Opening browser to OpenLP project...')
|
||||||
print_quiet(u' ** Please Note **')
|
|
||||||
print_quiet(u' In order to get this file into OpenLP and onto the '
|
|
||||||
u'Pootle translation server you will need to subscribe to the '
|
|
||||||
u'OpenLP Translators mailing list, and request that your language '
|
|
||||||
u'file be added to the project.')
|
|
||||||
print_quiet(u' Done.')
|
|
||||||
|
|
||||||
def process_stack(command_stack):
|
def process_stack(command_stack):
|
||||||
"""
|
"""
|
||||||
@ -314,23 +317,26 @@ def process_stack(command_stack):
|
|||||||
elif command == Command.Generate:
|
elif command == Command.Generate:
|
||||||
generate_binaries()
|
generate_binaries()
|
||||||
elif command == Command.Create:
|
elif command == Command.Create:
|
||||||
arguments = command_stack.arguments()
|
create_translation()
|
||||||
create_translation(*arguments)
|
|
||||||
print_quiet(u'Finished processing commands.')
|
print_quiet(u'Finished processing commands.')
|
||||||
else:
|
else:
|
||||||
print_quiet(u'No commands to process.')
|
print_quiet(u'No commands to process.')
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
global verbose_mode, quiet_mode
|
global verbose_mode, quiet_mode, username, password
|
||||||
# Set up command line options.
|
# Set up command line options.
|
||||||
usage = u'%prog [options]\nOptions are parsed in the order they are ' + \
|
usage = u'%prog [options]\nOptions are parsed in the order they are ' + \
|
||||||
u'listed below. If no options are given, "-dpug" will be used.\n\n' + \
|
u'listed below. If no options are given, "-dpug" will be used.\n\n' + \
|
||||||
u'This script is used to manage OpenLP\'s translation files.'
|
u'This script is used to manage OpenLP\'s translation files.'
|
||||||
parser = OptionParser(usage=usage)
|
parser = OptionParser(usage=usage)
|
||||||
|
parser.add_option('-U', '--username', dest='username', metavar='USERNAME',
|
||||||
|
help='Transifex username, used for authentication')
|
||||||
|
parser.add_option('-P', '--password', dest='password', metavar='PASSWORD',
|
||||||
|
help='Transifex password, used for authentication')
|
||||||
parser.add_option('-d', '--download-ts', dest='download',
|
parser.add_option('-d', '--download-ts', dest='download',
|
||||||
action='store_true', help='download language files from Pootle')
|
action='store_true', help='download language files from Transifex')
|
||||||
parser.add_option('-c', '--create', dest='create', metavar='LANG',
|
parser.add_option('-c', '--create', dest='create', action='store_true',
|
||||||
help='create a new translation file for language LANG, e.g. "en_GB"')
|
help='go to Transifex to request a new translation file')
|
||||||
parser.add_option('-p', '--prepare', dest='prepare', action='store_true',
|
parser.add_option('-p', '--prepare', dest='prepare', action='store_true',
|
||||||
help='generate a project file, used to update the translations')
|
help='generate a project file, used to update the translations')
|
||||||
parser.add_option('-u', '--update', action='store_true', dest='update',
|
parser.add_option('-u', '--update', action='store_true', dest='update',
|
||||||
@ -356,6 +362,10 @@ def main():
|
|||||||
command_stack.append(Command.Generate)
|
command_stack.append(Command.Generate)
|
||||||
verbose_mode = options.verbose
|
verbose_mode = options.verbose
|
||||||
quiet_mode = options.quiet
|
quiet_mode = options.quiet
|
||||||
|
if options.username:
|
||||||
|
username = options.username
|
||||||
|
if options.password:
|
||||||
|
password = options.password
|
||||||
if not command_stack:
|
if not command_stack:
|
||||||
command_stack.append(Command.Download)
|
command_stack.append(Command.Download)
|
||||||
command_stack.append(Command.Prepare)
|
command_stack.append(Command.Prepare)
|
||||||
|
Loading…
Reference in New Issue
Block a user