From eb670d5640f6e7e4b756d923f8d492e0c26926c3 Mon Sep 17 00:00:00 2001 From: Michael Gallaspy Date: Tue, 31 Mar 2015 16:58:48 -0700 Subject: [PATCH 1/9] Stop using deprecated command, update requirements, fix import --- kalite/distributed/management/commands/screenshots.py | 3 ++- sphinx-docs/requirements.txt | 1 + sphinx-docs/screenshot.py | 4 ++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/kalite/distributed/management/commands/screenshots.py b/kalite/distributed/management/commands/screenshots.py index 908a976d43..0d523abf12 100644 --- a/kalite/distributed/management/commands/screenshots.py +++ b/kalite/distributed/management/commands/screenshots.py @@ -18,7 +18,8 @@ from fle_utils.general import ensure_dir from kalite.testing.base import KALiteBrowserTestCase -from kalite.testing.mixins import FacilityMixins, BrowserActionMixins +from kalite.testing.mixins.facility_mixins import FacilityMixins +from kalite.testing.mixins.browser_mixins import BrowserActionMixins from kalite.distributed.management.commands.katest import unregister_distributed_server USER_TYPE_ADMIN = "admin" diff --git a/sphinx-docs/requirements.txt b/sphinx-docs/requirements.txt index 0bd349f553..380b7f922c 100644 --- a/sphinx-docs/requirements.txt +++ b/sphinx-docs/requirements.txt @@ -1,2 +1,3 @@ +sphinx # Required by screenshots.py to take screenshots in headless manner pyvirtualdisplay diff --git a/sphinx-docs/screenshot.py b/sphinx-docs/screenshot.py index a42e9ab6d1..deb1ebdbbf 100644 --- a/sphinx-docs/screenshot.py +++ b/sphinx-docs/screenshot.py @@ -25,11 +25,11 @@ USER_ROLES = ["guest", "coach", "admin", "learner"] SS_DUMP_DIR = ".screenshot_dump" OUTPUT_PATH = os.path.realpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), SS_DUMP_DIR)) -MANAGE_PATH = os.path.realpath(os.path.join(os.path.dirname(os.path.abspath(__file__)),"..","kalite","manage.py")) +KALITE_BIN_PATH = os.path.realpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "bin", "kalite")) # Formatted from subprocess.Popen # Trying to import call_command to execute a Django mgmt command gets you # into a weird import hell, probably because of import_all_child_modules... -SCREENSHOT_COMMAND = [sys.executable, MANAGE_PATH, "screenshots"] +SCREENSHOT_COMMAND = [KALITE_BIN_PATH, "manage", "screenshots"] SCREENSHOT_COMMAND_OPTS = ["-v", "0", "--output-dir", OUTPUT_PATH] # These keys are css styles but they need to be camelCased FOCUS_CSS_STYLES = { "borderStyle": "solid", From 8ffa4d2b2fdbf49cd3ed460f00fa04f2331b0158 Mon Sep 17 00:00:00 2001 From: Michael Gallaspy Date: Tue, 31 Mar 2015 18:15:12 -0700 Subject: [PATCH 2/9] use absolute path in kalitectl.py, update screenshot command The screenshot directive for building the docs has now been updated to use the recommended management command invocation, and an error in kalitectl.py has been fixed so that the python path is set correctly. --- kalitectl.py | 4 +++- sphinx-docs/screenshot.py | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/kalitectl.py b/kalitectl.py index d22ef93b22..d94914ce14 100644 --- a/kalitectl.py +++ b/kalitectl.py @@ -55,6 +55,7 @@ import sys import os +import pdb; pdb.set_trace() # KALITE_DIR set, so probably called from bin/kalite if 'KALITE_DIR' in os.environ: sys.path = [ @@ -63,7 +64,8 @@ ] + sys.path # KALITE_DIR not set, so called from some other source else: - sys.path = ['python-packages', 'kalite'] + sys.path + filedir = os.path.dirname(__file__) + sys.path = [os.path.join(filedir, 'python-packages'), os.path.join(filedir, 'kalite')] + sys.path from django.core.management import ManagementUtility, get_commands diff --git a/sphinx-docs/screenshot.py b/sphinx-docs/screenshot.py index deb1ebdbbf..48ed50407a 100644 --- a/sphinx-docs/screenshot.py +++ b/sphinx-docs/screenshot.py @@ -25,11 +25,11 @@ USER_ROLES = ["guest", "coach", "admin", "learner"] SS_DUMP_DIR = ".screenshot_dump" OUTPUT_PATH = os.path.realpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), SS_DUMP_DIR)) -KALITE_BIN_PATH = os.path.realpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "bin", "kalite")) +KALITECTL_PATH = os.path.realpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "kalitectl.py")) # Formatted from subprocess.Popen # Trying to import call_command to execute a Django mgmt command gets you # into a weird import hell, probably because of import_all_child_modules... -SCREENSHOT_COMMAND = [KALITE_BIN_PATH, "manage", "screenshots"] +SCREENSHOT_COMMAND = [sys.executable, KALITECTL_PATH, "manage", "screenshots"] SCREENSHOT_COMMAND_OPTS = ["-v", "0", "--output-dir", OUTPUT_PATH] # These keys are css styles but they need to be camelCased FOCUS_CSS_STYLES = { "borderStyle": "solid", From ea857a6f23f34c7bd5ebabbdcbef98ec43f4a444 Mon Sep 17 00:00:00 2001 From: Michael Gallaspy Date: Wed, 1 Apr 2015 10:54:01 -0700 Subject: [PATCH 3/9] Remove errant pdb.set_trace --- kalitectl.py | 1 - 1 file changed, 1 deletion(-) diff --git a/kalitectl.py b/kalitectl.py index d94914ce14..9c3d156cce 100644 --- a/kalitectl.py +++ b/kalitectl.py @@ -55,7 +55,6 @@ import sys import os -import pdb; pdb.set_trace() # KALITE_DIR set, so probably called from bin/kalite if 'KALITE_DIR' in os.environ: sys.path = [ From 3ae33e74a893962ed6a1af83904529c592d5eff1 Mon Sep 17 00:00:00 2001 From: Michael Gallaspy Date: Wed, 1 Apr 2015 18:42:26 -0700 Subject: [PATCH 4/9] Add language option to screenshots management command Conflicts: kalite/distributed/management/commands/screenshots.py --- .../management/commands/screenshots.py | 32 +++++++++++++++++-- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/kalite/distributed/management/commands/screenshots.py b/kalite/distributed/management/commands/screenshots.py index 0d523abf12..81f1869f5e 100644 --- a/kalite/distributed/management/commands/screenshots.py +++ b/kalite/distributed/management/commands/screenshots.py @@ -1,10 +1,8 @@ -import errno +#TODO-BLOCKER(MCGallaspy): Better Exception handling in this file. import glob import json import os -import re from optparse import make_option -from selenium import webdriver from selenium.webdriver.common.keys import Keys from django.conf import settings @@ -57,6 +55,11 @@ class Command(BaseCommand): dest='no_del', default=None, help='Don\'t delete existing screenshots.'), + make_option('--lang', + action='store', + dest='language', + default=None, + help='Specify the language of the session, set by the "set_default_language" api endpoint.'), ) def handle(self, *args, **options): @@ -211,10 +214,33 @@ def __init__(self, *args, **kwargs): self.browser.set_window_size(1024, 768) self.browser.implicitly_wait(15) + # After initializing the server (with setUp) and a browser, set the language + self.set_session_language(kwargs['language']) + self.loginfo("==> Browser %s successfully setup with live_server_url %s." % (self.browser.name, self.live_server_url,)) self.loginfo("==> Saving screenshots to %s ..." % (settings.SCREENSHOTS_OUTPUT_PATH,)) + + def set_session_language(self, lang_code): + """ Uses the "set_default_language" api endpoint to set the language for the session. + The language pack should already be downloaded, or the behavior is undefined. + TODO: Handle the case when the language pack is not downloaded. + + :param lang_code: A string with the language code or None. Value None is a no-op + """ + if not lang_code: + return + + self.browser.get(reverse("homepage")) + self.browser.wait_for_js_object_exists("$") + data = json.dumps({"lang": lang_code}) + self.browser.execute_script("window.SUCCESS=false; $.ajax({type: \"POST\", url: \"%s\", data: \"%s\", contentType: \"application/json\", success: function(){window.SUCCESS=true}})" % (reverse("set_default_language"), data)) + self.browser.wait_for_js_condition("window.SUCCESS") + # Ensure the changes are loaded + self.browser.get(reverse("homepage")) + + def validate_json_keys(self, shot): """ Validates a json item if keys are valid or not, raises an exception if keys are found. From 35105669d6715e0b23fd03e6980c1a0e9651864f Mon Sep 17 00:00:00 2001 From: Michael Gallaspy Date: Thu, 2 Apr 2015 12:05:21 -0700 Subject: [PATCH 5/9] Fix language option on screenshot mgmt command --- kalite/distributed/management/commands/screenshots.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/kalite/distributed/management/commands/screenshots.py b/kalite/distributed/management/commands/screenshots.py index 81f1869f5e..c7f34d00f3 100644 --- a/kalite/distributed/management/commands/screenshots.py +++ b/kalite/distributed/management/commands/screenshots.py @@ -231,14 +231,13 @@ def set_session_language(self, lang_code): """ if not lang_code: return - - self.browser.get(reverse("homepage")) - self.browser.wait_for_js_object_exists("$") + self.browser.get(self.live_server_url + reverse("homepage")) + self.browser_wait_for_js_object_exists("$") data = json.dumps({"lang": lang_code}) - self.browser.execute_script("window.SUCCESS=false; $.ajax({type: \"POST\", url: \"%s\", data: \"%s\", contentType: \"application/json\", success: function(){window.SUCCESS=true}})" % (reverse("set_default_language"), data)) - self.browser.wait_for_js_condition("window.SUCCESS") + self.browser.execute_script("window.SUCCESS=false; $.ajax({type: \"POST\", url: \"%s\", data: '%s', contentType: \"application/json\", success: function(){window.SUCCESS=true}})" % (reverse("set_default_language"), data)) + self.browser_wait_for_js_condition("window.SUCCESS") # Ensure the changes are loaded - self.browser.get(reverse("homepage")) + self.browser.get(self.live_server_url + reverse("homepage")) def validate_json_keys(self, shot): From 3d273f25d51e11c9d1f990ead4db31918b0a2358 Mon Sep 17 00:00:00 2001 From: Michael Gallaspy Date: Thu, 2 Apr 2015 13:59:57 -0700 Subject: [PATCH 6/9] Set up docs for translation. Need translated pofiles. --- sphinx-docs/README.md | 12 +++++++++++- sphinx-docs/conf.py | 3 +++ sphinx-docs/requirements.txt | 1 + sphinx-docs/screenshot.py | 8 ++++++-- 4 files changed, 21 insertions(+), 3 deletions(-) diff --git a/sphinx-docs/README.md b/sphinx-docs/README.md index 745714d274..d3f61e8341 100644 --- a/sphinx-docs/README.md +++ b/sphinx-docs/README.md @@ -21,9 +21,19 @@ Then, install following python packages: pip install sphinx ``` -## Builiding Documentation +## Building Documentation Change your current working directory to `sphinx-docs` directory under `ka-lite` root and execute following command: ``` make html ``` If the above command executes successfully, docs should be found under `sphinx-docs/_build` directory inside `ka-lite`. + +## Building translated docs +1. Make sure you have the sphinx-intl dependency (run the command `pip install -r requirements` in this directory). +2. Extract the translatable messages into pot files using the command `make gettext`. The pot files are then found in `_build/locale directory`. +3. Setup po files for your target language with the command `sphinx-intl update -p _build/locale -l xx`, where xx is the language code of your target language (i.e. "de" or "eo"). TODO: Setup process on the central server to create po files and include them. (Look at update_pot on central server.) +4. Translate the po files in `locale/xx/LC_MESSAGES`. TODO: Automate this. +5. Build the mo files with `sphinx-intl build` +6. Make the docs in the target language with the command `make -e SPHINXOPTS="-Dlanguage='xx'" html` +7. Party time! + diff --git a/sphinx-docs/conf.py b/sphinx-docs/conf.py index 6b4ac5c829..ae785e76a9 100644 --- a/sphinx-docs/conf.py +++ b/sphinx-docs/conf.py @@ -288,3 +288,6 @@ # Example configuration for intersphinx: refer to the Python standard library. intersphinx_mapping = {'http://docs.python.org/': None} +# sphinx-intl options +locale_dirs = ['locale/'] +gettext_compact = False diff --git a/sphinx-docs/requirements.txt b/sphinx-docs/requirements.txt index 380b7f922c..984f8b343c 100644 --- a/sphinx-docs/requirements.txt +++ b/sphinx-docs/requirements.txt @@ -1,3 +1,4 @@ sphinx +sphinx-intl # Required by screenshots.py to take screenshots in headless manner pyvirtualdisplay diff --git a/sphinx-docs/screenshot.py b/sphinx-docs/screenshot.py index 48ed50407a..a70b6e1395 100644 --- a/sphinx-docs/screenshot.py +++ b/sphinx-docs/screenshot.py @@ -54,7 +54,12 @@ def process_screenshots(app, env): return all_args = map(lambda x: x['from_str_arg'], env.screenshot_all_screenshots) - subprocess = Popen(SCREENSHOT_COMMAND + SCREENSHOT_COMMAND_OPTS + ["--from-str", json.dumps(all_args)]) + # If building in a different language, start the server in a different language + command = SCREENSHOT_COMMAND + SCREENSHOT_COMMAND_OPTS + ["--from-str", json.dumps(all_args)] + language = env.config.language + if language: + command += ["--lang", language] + subprocess = Popen(command) subprocess.wait() if display: display.stop() @@ -219,7 +224,6 @@ def run(self): Build language can be accessed from the BuildEnvironment. """ self.env = self.state.document.settings.env - language = self.env.config.language return_nodes = [] if not hasattr(self.env, 'screenshot_all_screenshots'): self.env.screenshot_all_screenshots = [] From ab8bc62ec3c4169dd6e1cfce3c08c8aac6111024 Mon Sep 17 00:00:00 2001 From: Michael Gallaspy Date: Thu, 2 Apr 2015 15:31:41 -0700 Subject: [PATCH 7/9] Don't build screenshots when making messages --- sphinx-docs/screenshot.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sphinx-docs/screenshot.py b/sphinx-docs/screenshot.py index a70b6e1395..f9a921c537 100644 --- a/sphinx-docs/screenshot.py +++ b/sphinx-docs/screenshot.py @@ -52,7 +52,10 @@ def purge_screenshots(app, env, docname): def process_screenshots(app, env): if not hasattr(env, 'screenshot_all_screenshots'): return - + # Don't bother building screenshots if we're just collecting messages. + # Just checks if we invoked the build command with "gettext" in there somewhere + if "gettext" in sys.argv: + return all_args = map(lambda x: x['from_str_arg'], env.screenshot_all_screenshots) # If building in a different language, start the server in a different language command = SCREENSHOT_COMMAND + SCREENSHOT_COMMAND_OPTS + ["--from-str", json.dumps(all_args)] From 263e52b39bb170c29d32b4ce6ba032e0018330e8 Mon Sep 17 00:00:00 2001 From: Michael Gallaspy Date: Mon, 6 Apr 2015 15:30:49 -0700 Subject: [PATCH 8/9] Update README --- sphinx-docs/README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sphinx-docs/README.md b/sphinx-docs/README.md index d3f61e8341..0563e54946 100644 --- a/sphinx-docs/README.md +++ b/sphinx-docs/README.md @@ -31,9 +31,8 @@ If the above command executes successfully, docs should be found under `sphinx-d ## Building translated docs 1. Make sure you have the sphinx-intl dependency (run the command `pip install -r requirements` in this directory). 2. Extract the translatable messages into pot files using the command `make gettext`. The pot files are then found in `_build/locale directory`. -3. Setup po files for your target language with the command `sphinx-intl update -p _build/locale -l xx`, where xx is the language code of your target language (i.e. "de" or "eo"). TODO: Setup process on the central server to create po files and include them. (Look at update_pot on central server.) +3. Setup po files for your target language with the command `sphinx-intl update -p _build/locale -l xx`, where xx is the language code of your target language (i.e. "de" or "eo"). (Note: running the `update_pot` command from the central server will generate po files and grab them for uploading.) 4. Translate the po files in `locale/xx/LC_MESSAGES`. TODO: Automate this. 5. Build the mo files with `sphinx-intl build` 6. Make the docs in the target language with the command `make -e SPHINXOPTS="-Dlanguage='xx'" html` 7. Party time! - From b0a9d48020911025b4ad05c2edfa055c35c6d1a7 Mon Sep 17 00:00:00 2001 From: Michael Gallaspy Date: Tue, 7 Apr 2015 14:42:09 -0700 Subject: [PATCH 9/9] Add dep for python 2.6 --- sphinx-docs/requirements.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sphinx-docs/requirements.txt b/sphinx-docs/requirements.txt index 984f8b343c..6b2415330d 100644 --- a/sphinx-docs/requirements.txt +++ b/sphinx-docs/requirements.txt @@ -1,4 +1,6 @@ sphinx sphinx-intl +# Required for sphinx-intl in python 2.6 +ordereddict # Required by screenshots.py to take screenshots in headless manner pyvirtualdisplay