ol-openedx-course-translations 0.1.0__py3-none-any.whl → 0.3.5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of ol-openedx-course-translations might be problematic. Click here for more details.

Files changed (40) hide show
  1. ol_openedx_course_translations/admin.py +29 -0
  2. ol_openedx_course_translations/apps.py +13 -2
  3. ol_openedx_course_translations/filters.py +39 -0
  4. ol_openedx_course_translations/glossaries/machine_learning/ar.txt +175 -0
  5. ol_openedx_course_translations/glossaries/machine_learning/de.txt +175 -0
  6. ol_openedx_course_translations/glossaries/machine_learning/el.txt +988 -0
  7. ol_openedx_course_translations/glossaries/machine_learning/es.txt +175 -0
  8. ol_openedx_course_translations/glossaries/machine_learning/fr.txt +175 -0
  9. ol_openedx_course_translations/glossaries/machine_learning/ja.txt +175 -0
  10. ol_openedx_course_translations/glossaries/machine_learning/pt-br.txt +175 -0
  11. ol_openedx_course_translations/glossaries/machine_learning/ru.txt +213 -0
  12. ol_openedx_course_translations/management/commands/sync_and_translate_language.py +1866 -0
  13. ol_openedx_course_translations/management/commands/translate_course.py +472 -475
  14. ol_openedx_course_translations/middleware.py +143 -0
  15. ol_openedx_course_translations/migrations/0001_add_translation_logs.py +84 -0
  16. ol_openedx_course_translations/migrations/__init__.py +0 -0
  17. ol_openedx_course_translations/models.py +57 -0
  18. ol_openedx_course_translations/providers/__init__.py +1 -0
  19. ol_openedx_course_translations/providers/base.py +278 -0
  20. ol_openedx_course_translations/providers/deepl_provider.py +292 -0
  21. ol_openedx_course_translations/providers/llm_providers.py +581 -0
  22. ol_openedx_course_translations/settings/cms.py +17 -0
  23. ol_openedx_course_translations/settings/common.py +58 -30
  24. ol_openedx_course_translations/settings/lms.py +38 -0
  25. ol_openedx_course_translations/tasks.py +222 -0
  26. ol_openedx_course_translations/urls.py +16 -0
  27. ol_openedx_course_translations/utils/__init__.py +0 -0
  28. ol_openedx_course_translations/utils/command_utils.py +197 -0
  29. ol_openedx_course_translations/utils/constants.py +218 -0
  30. ol_openedx_course_translations/utils/course_translations.py +608 -0
  31. ol_openedx_course_translations/utils/translation_sync.py +808 -0
  32. ol_openedx_course_translations/views.py +73 -0
  33. ol_openedx_course_translations-0.3.5.dist-info/METADATA +409 -0
  34. ol_openedx_course_translations-0.3.5.dist-info/RECORD +40 -0
  35. ol_openedx_course_translations-0.3.5.dist-info/entry_points.txt +5 -0
  36. ol_openedx_course_translations-0.1.0.dist-info/METADATA +0 -63
  37. ol_openedx_course_translations-0.1.0.dist-info/RECORD +0 -11
  38. ol_openedx_course_translations-0.1.0.dist-info/entry_points.txt +0 -2
  39. {ol_openedx_course_translations-0.1.0.dist-info → ol_openedx_course_translations-0.3.5.dist-info}/WHEEL +0 -0
  40. {ol_openedx_course_translations-0.1.0.dist-info → ol_openedx_course_translations-0.3.5.dist-info}/licenses/LICENSE.txt +0 -0
@@ -0,0 +1,73 @@
1
+ """
2
+ API Views for ol_openedx_course_translations App
3
+ """
4
+
5
+ import logging
6
+
7
+ from opaque_keys import InvalidKeyError
8
+ from opaque_keys.edx.keys import CourseKey
9
+ from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
10
+ from rest_framework import status
11
+ from rest_framework.permissions import IsAuthenticated
12
+ from rest_framework.response import Response
13
+ from rest_framework.views import APIView
14
+
15
+ log = logging.getLogger(__name__)
16
+
17
+
18
+ class CourseLanguageView(APIView):
19
+ """
20
+ API View to retrieve the language of a specified course.
21
+
22
+ Sample Request:
23
+ GET /course-translations/api/course_language/{course_key}/
24
+
25
+ Sample Response:
26
+ 200 OK
27
+ {
28
+ "language": "en"
29
+ }
30
+
31
+ Error Responses:
32
+ 400 Bad Request
33
+ {
34
+ "error": "Invalid course_key."
35
+ }
36
+ 404 Not Found
37
+ {
38
+ "error": "Course not found."
39
+ }
40
+ 400 Bad Request
41
+ {
42
+ "error": "An unexpected error occurred."
43
+ }
44
+ """
45
+
46
+ permission_classes = [IsAuthenticated]
47
+
48
+ def get(self, request, course_key_string): # noqa: ARG002
49
+ """
50
+ Retrieve the language of the specified course.
51
+ """
52
+ try:
53
+ course_key = CourseKey.from_string(course_key_string)
54
+ course = CourseOverview.get_from_id(course_key)
55
+ except InvalidKeyError:
56
+ log.info("Invalid course key %s", course_key_string)
57
+ return Response(
58
+ {"error": "Invalid course_key."},
59
+ status=status.HTTP_400_BAD_REQUEST,
60
+ )
61
+ except CourseOverview.DoesNotExist:
62
+ log.info("Course not found for key %s", course_key_string)
63
+ return Response(
64
+ {"error": "Course not found."},
65
+ status=status.HTTP_404_NOT_FOUND,
66
+ )
67
+ except Exception:
68
+ log.exception("Unexpected error retrieving course %s", course_key_string)
69
+ return Response(
70
+ {"error": "An unexpected error occurred."},
71
+ status=status.HTTP_400_BAD_REQUEST,
72
+ )
73
+ return Response({"language": course.language})
@@ -0,0 +1,409 @@
1
+ Metadata-Version: 2.4
2
+ Name: ol-openedx-course-translations
3
+ Version: 0.3.5
4
+ Summary: An Open edX plugin to translate courses
5
+ Author: MIT Office of Digital Learning
6
+ License-Expression: BSD-3-Clause
7
+ License-File: LICENSE.txt
8
+ Keywords: Python,edx
9
+ Requires-Python: >=3.11
10
+ Requires-Dist: deepl>=1.25.0
11
+ Requires-Dist: django>=4.0
12
+ Requires-Dist: djangorestframework>=3.14.0
13
+ Requires-Dist: edx-opaque-keys
14
+ Requires-Dist: gitpython>=3.1.40
15
+ Requires-Dist: litellm>=1.80.0
16
+ Requires-Dist: polib>=1.2.0
17
+ Requires-Dist: requests>=2.31.0
18
+ Requires-Dist: srt>=3.5.3
19
+ Description-Content-Type: text/x-rst
20
+
21
+ OL Open edX Course Translations
22
+ ===============================
23
+
24
+ An Open edX plugin to manage course translations.
25
+
26
+ Purpose
27
+ *******
28
+
29
+ Translate course content into multiple languages to enhance accessibility for a global audience.
30
+
31
+ Setup
32
+ =====
33
+
34
+ For detailed installation instructions, please refer to the `plugin installation guide <../../docs#installation-guide>`_.
35
+
36
+ Installation required in:
37
+
38
+ * Studio (CMS)
39
+ * LMS (for auto language selection feature)
40
+
41
+ Configuration
42
+ =============
43
+
44
+ - Add the following configuration values to the config file in Open edX. For any release after Juniper, that config file is ``/edx/etc/lms.yml`` and ``/edx/etc/cms.yml``. If you're using ``private.py``, add these values to ``lms/envs/private.py`` and ``cms/envs/private.py``. These should be added to the top level. **Ask a fellow developer for these values.**
45
+
46
+ .. code-block:: python
47
+
48
+ # Enable auto language selection
49
+ ENABLE_AUTO_LANGUAGE_SELECTION: true
50
+
51
+ # Translation providers configuration
52
+ TRANSLATIONS_PROVIDERS: {
53
+ "default_provider": "mistral", # Default provider to use
54
+ "deepl": {
55
+ "api_key": "<YOUR_DEEPL_API_KEY>",
56
+ },
57
+ "openai": {
58
+ "api_key": "<YOUR_OPENAI_API_KEY>",
59
+ "default_model": "gpt-5.2",
60
+ },
61
+ "gemini": {
62
+ "api_key": "<YOUR_GEMINI_API_KEY>",
63
+ "default_model": "gemini-3-pro-preview",
64
+ },
65
+ "mistral": {
66
+ "api_key": "<YOUR_MISTRAL_API_KEY>",
67
+ "default_model": "mistral-large-latest",
68
+ },
69
+ }
70
+ TRANSLATIONS_GITHUB_TOKEN: <YOUR_GITHUB_TOKEN>
71
+ TRANSLATIONS_REPO_PATH: ""
72
+ TRANSLATIONS_REPO_URL: "https://github.com/mitodl/mitxonline-translations.git"
73
+ LITE_LLM_REQUEST_TIMEOUT: 120 # Timeout for LLM API requests in seconds
74
+
75
+ - For Tutor installations, these values can also be managed through a `custom Tutor plugin <https://docs.tutor.edly.io/tutorials/plugin.html#plugin-development-tutorial>`_.
76
+
77
+ Translation Providers
78
+ =====================
79
+
80
+ The plugin supports multiple translation providers:
81
+
82
+ - DeepL
83
+ - OpenAI (GPT models)
84
+ - Gemini (Google)
85
+ - Mistral
86
+
87
+ **Configuration**
88
+
89
+ All providers are configured through the ``TRANSLATIONS_PROVIDERS`` dictionary in your settings:
90
+
91
+ .. code-block:: python
92
+
93
+ TRANSLATIONS_PROVIDERS = {
94
+ "default_provider": "mistral", # Optional: default provider for commands
95
+ "deepl": {
96
+ "api_key": "<YOUR_DEEPL_API_KEY>",
97
+ },
98
+ "openai": {
99
+ "api_key": "<YOUR_OPENAI_API_KEY>",
100
+ "default_model": "gpt-5.2", # Optional: used when model not specified
101
+ },
102
+ "gemini": {
103
+ "api_key": "<YOUR_GEMINI_API_KEY>",
104
+ "default_model": "gemini-3-pro-preview",
105
+ },
106
+ "mistral": {
107
+ "api_key": "<YOUR_MISTRAL_API_KEY>",
108
+ "default_model": "mistral-large-latest",
109
+ },
110
+ }
111
+
112
+ **Important Notes:**
113
+
114
+ 1. **DeepL Configuration**: DeepL must be configured in ``TRANSLATIONS_PROVIDERS['deepl']['api_key']``.
115
+
116
+ 2. **DeepL for Subtitle Repair**: DeepL is used as a fallback repair mechanism for subtitle translations when LLM providers fail validation. Even if you use LLM providers for primary translation, you should configure DeepL to enable automatic repair.
117
+
118
+ 3. **Default Models**: The ``default_model`` in each provider's configuration is used when you specify a provider without a model (e.g., ``openai`` instead of ``openai/gpt-5.2``).
119
+
120
+ **Provider Selection**
121
+
122
+ You can specify providers in three ways:
123
+
124
+ 1. **Provider only** (uses default model from settings):
125
+
126
+ .. code-block:: bash
127
+
128
+ ./manage.py cms translate_course \
129
+ --target-language AR \
130
+ --course-dir /path/to/course.tar.gz \
131
+ --content-translation-provider openai \
132
+ --srt-translation-provider gemini
133
+
134
+ 2. **Provider with specific model**:
135
+
136
+ .. code-block:: bash
137
+
138
+ ./manage.py cms translate_course \
139
+ --target-language AR \
140
+ --course-dir /path/to/course.tar.gz \
141
+ --content-translation-provider openai/gpt-5.2 \
142
+ --srt-translation-provider gemini/gemini-3-pro-preview
143
+
144
+ 3. **DeepL** (no model needed):
145
+
146
+ .. code-block:: bash
147
+
148
+ ./manage.py cms translate_course \
149
+ --target-language AR \
150
+ --course-dir /path/to/course.tar.gz \
151
+ --content-translation-provider deepl \
152
+ --srt-translation-provider deepl
153
+
154
+ **Note:** If you specify a provider without a model (e.g., ``openai`` instead of ``openai/gpt-5.2``), the system will use the ``default_model`` configured in ``TRANSLATIONS_PROVIDERS`` for that provider.
155
+
156
+ Translating a Course
157
+ ====================
158
+ 1. Open the course in Studio.
159
+ 2. Go to Tools -> Export Course.
160
+ 3. Export the course as a .tar.gz file.
161
+ 4. Go to the CMS shell
162
+ 5. Run the management command to translate the course:
163
+
164
+ .. code-block:: bash
165
+
166
+ ./manage.py cms translate_course \
167
+ --source-language EN \
168
+ --target-language AR \
169
+ --course-dir /path/to/course.tar.gz \
170
+ --content-translation-provider openai \
171
+ --srt-translation-provider gemini \
172
+ --glossary-dir /path/to/glossary
173
+
174
+ **Command Options:**
175
+
176
+ - ``--source-language``: Source language code (default: EN)
177
+ - ``--target-language``: Target language code (required)
178
+ - ``--course-dir``: Path to exported course tar.gz file (required)
179
+ - ``--content-translation-provider``: Translation provider for content (XML/HTML and text) (required).
180
+
181
+ Format:
182
+
183
+ - ``deepl`` - uses DeepL (no model needed)
184
+ - ``PROVIDER`` - uses provider with default model from settings (e.g., ``openai``, ``gemini``, ``mistral``)
185
+ - ``PROVIDER/MODEL`` - uses provider with specific model (e.g., ``openai/gpt-5.2``, ``gemini/gemini-3-pro-preview``, ``mistral/mistral-large-latest``)
186
+
187
+ - ``--srt-translation-provider``: Translation provider for SRT subtitles (required). Same format as ``--content-translation-provider``
188
+ - ``--glossary-dir``: Path to glossary directory (optional)
189
+
190
+ **Examples:**
191
+
192
+ .. code-block:: bash
193
+
194
+ # Use DeepL for both content and subtitles
195
+ ./manage.py cms translate_course \
196
+ --target-language AR \
197
+ --course-dir /path/to/course.tar.gz \
198
+ --content-translation-provider deepl \
199
+ --srt-translation-provider deepl
200
+
201
+ # Use OpenAI and Gemini with default models from settings
202
+ ./manage.py cms translate_course \
203
+ --target-language FR \
204
+ --course-dir /path/to/course.tar.gz \
205
+ --content-translation-provider openai \
206
+ --srt-translation-provider gemini
207
+
208
+ # Use OpenAI with specific model for content, Gemini with default for subtitles
209
+ ./manage.py cms translate_course \
210
+ --target-language FR \
211
+ --course-dir /path/to/course.tar.gz \
212
+ --content-translation-provider openai/gpt-5.2 \
213
+ --srt-translation-provider gemini
214
+
215
+ # Use Mistral with specific model and glossary
216
+ ./manage.py cms translate_course \
217
+ --target-language ES \
218
+ --course-dir /path/to/course.tar.gz \
219
+ --content-translation-provider mistral/mistral-large-latest \
220
+ --srt-translation-provider mistral/mistral-large-latest \
221
+ --glossary-dir /path/to/glossary
222
+
223
+ **Glossary Support:**
224
+
225
+ Create language-specific glossary files in the glossary directory:
226
+
227
+ .. code-block:: bash
228
+
229
+ glossaries/machine_learning/
230
+ ├── ar.txt # Arabic glossary
231
+ ├── fr.txt # French glossary
232
+ └── es.txt # Spanish glossary
233
+
234
+ Format: One term per line as "source_term : translated_term"
235
+
236
+ .. code-block:: text
237
+
238
+ # ES HINTS
239
+ ## TERM MAPPINGS
240
+ These are preferred terminology choices for this language. Use them whenever they sound natural; adapt freely if context requires.
241
+
242
+ - 'accuracy' : 'exactitud'
243
+ - 'activation function' : 'función de activación'
244
+ - 'artificial intelligence' : 'inteligencia artificial'
245
+ - 'AUC' : 'AUC'
246
+
247
+ Subtitle Translation and Validation
248
+ ====================================
249
+
250
+ The course translation system includes robust subtitle (SRT) translation with automatic validation and repair mechanisms to ensure high-quality translations with preserved timing information.
251
+
252
+ **Translation Process**
253
+
254
+ The subtitle translation follows a multi-stage process with built-in quality checks:
255
+
256
+ 1. **Initial Translation**: Subtitles are translated using your configured provider (DeepL or LLM)
257
+ 2. **Validation**: Timestamps, subtitle count, and content are validated to ensure integrity
258
+ 3. **Automatic Retry**: If validation fails, the system automatically retries translation (up to 1 additional attempt)
259
+ 4. **DeepL Repair Fallback**: If retries fail, the system automatically falls back to DeepL for repair
260
+
261
+ **Why DeepL for Repair?**
262
+
263
+ When subtitle translations fail validation (mismatched timestamps, incorrect subtitle counts, or blank translations), the system automatically uses **DeepL as a repair mechanism**, regardless of which provider was initially used. This design choice is based on extensive testing and production experience:
264
+
265
+ - **Higher Reliability**: LLMs frequently fail to preserve subtitle structure and timestamps correctly, even with detailed prompting
266
+ - **Consistent Formatting**: DeepL's specialized subtitle translation API maintains timing precision through XML tag handling
267
+ - **Lower Failure Rate**: DeepL demonstrates significantly better success rates for subtitle translation compared to LLMs
268
+ - **Timestamp Preservation**: DeepL's built-in XML tag handling ensures start and end times remain intact during translation
269
+
270
+
271
+ **Validation Rules**
272
+
273
+ The system validates subtitle translations against these criteria:
274
+
275
+ - **Subtitle Count**: Translated file must have the same number of subtitle blocks as the original
276
+ - **Index Matching**: Each subtitle block index must match the original (e.g., if original has blocks 1-100, translation must have blocks 1-100 in the same order)
277
+ - **Timestamp Preservation**: Start and end times for each subtitle block must remain unchanged
278
+ - **Content Validation**: Non-empty original subtitles must have non-empty translations (blank translations are flagged as errors)
279
+
280
+ **Example Validation Process:**
281
+
282
+ .. code-block:: text
283
+
284
+ 1. Initial Translation (using OpenAI):
285
+ ✓ 150 subtitle blocks translated
286
+ ✗ Validation failed: 3 blocks have mismatched timestamps
287
+
288
+ 2. Retry Attempt:
289
+ ✓ 150 subtitle blocks translated
290
+ ✗ Validation failed: 2 blocks still have issues
291
+
292
+ 3. DeepL Repair:
293
+ ✓ 150 subtitle blocks retranslated using DeepL
294
+ ✓ Validation passed: All timestamps and content validated
295
+ ✅ Translation completed successfully
296
+
297
+ **Failure Handling**
298
+
299
+ If subtitle repair fails after all attempts (including DeepL fallback):
300
+
301
+ - The translation task will fail with a ``ValueError``
302
+ - The entire course translation will be aborted to prevent incomplete translations
303
+ - The translated course directory will be automatically cleaned up
304
+ - An error message will indicate which subtitle file caused the failure
305
+ - No partial or corrupted translation files will be left behind
306
+
307
+ Auto Language Selection
308
+ =======================
309
+
310
+ The plugin includes an auto language selection feature that automatically sets the user's language preference based on the course language. When enabled, users will see the static site content in the course's configured language.
311
+
312
+ To enable auto language selection:
313
+
314
+ 1. Set ``ENABLE_AUTO_LANGUAGE_SELECTION`` to ``true`` in your settings.
315
+
316
+ 2. Set ``SHARED_COOKIE_DOMAIN`` to your domain (e.g., ``.local.openedx.io`` for local tutor setup) to allow cookies to be shared between LMS and CMS.
317
+
318
+ **How it works:**
319
+
320
+ - **LMS**: The ``CourseLanguageCookieMiddleware`` automatically detects course URLs and sets the language preference based on the course's configured language.
321
+ - **CMS**: The ``CourseLanguageCookieResetMiddleware`` ensures Studio always uses English for the authoring interface.
322
+ - **Admin areas**: Admin URLs (``/admin``, ``/sysadmin``, instructor dashboards) are forced to use English regardless of course language.
323
+
324
+ MFE Integration
325
+ ===============
326
+
327
+ To make auto language selection work with Micro-Frontends (MFEs), you need to use a custom Footer component that handles language detection and switching.
328
+
329
+ **Setup:**
330
+
331
+ 1. Use the Footer component from `src/bridge/settings/openedx/mfe/slot_config/Footer.jsx <https://github.com/mitodl/ol-infrastructure/blob/main/src/bridge/settings/openedx/mfe/slot_config/Footer.jsx>`_ in the `ol-infrastructure <https://github.com/mitodl/ol-infrastructure>`_ repository.
332
+
333
+ 2. Enable auto language selection in each MFE by adding the following to their ``.env.development`` file:
334
+
335
+ .. code-block:: bash
336
+
337
+ ENABLE_AUTO_LANGUAGE_SELECTION="true"
338
+
339
+ 3. This custom Footer component:
340
+ - Detects the current course context in MFEs
341
+ - Automatically switches the MFE language based on the course's configured language
342
+ - Ensures consistent language experience across the platform
343
+
344
+ 4. Configure your MFE slot overrides to use this custom Footer component instead of the default one.
345
+
346
+ **Note:** The custom Footer is required because MFEs run as separate applications and need their own mechanism to detect and respond to course language settings. The environment variable must be set in each MFE's configuration for the feature to work properly.
347
+
348
+ Generating static content translations
349
+ ======================================
350
+
351
+ This command synchronizes translation keys from edx-platform and MFE's, translates empty keys using LLM, and automatically creates a pull request in the translations repository.
352
+
353
+ **What it does:**
354
+
355
+ 1. Syncs translation keys from edx-platform and MFE's to the translations repository
356
+ 2. Extracts empty translation keys that need translation
357
+ 3. Translates empty keys using the specified LLM provider and model
358
+ 4. Applies translations to JSON and PO files
359
+ 5. Commits changes to a new branch
360
+ 6. Creates a pull request with translation statistics
361
+
362
+ **Usage:**
363
+
364
+ 1. Go to the CMS shell
365
+ 2. Run the management command:
366
+
367
+ .. code-block:: bash
368
+
369
+ ./manage.py cms sync_and_translate_language <LANGUAGE_CODE> [OPTIONS]
370
+
371
+ **Required arguments:**
372
+
373
+ - ``LANGUAGE_CODE``: Language code (e.g., ``el``, ``fr``, ``es_ES``)
374
+
375
+ **Optional arguments:**
376
+
377
+ - ``--iso-code``: ISO code for JSON files (default: same as language code)
378
+ - ``--provider``: Translation provider (``openai``, ``gemini``, ``mistral``). Default is taken from ``TRANSLATIONS_PROVIDERS['default_provider']`` setting
379
+ - ``--model``: LLM model name. If not specified, uses the ``default_model`` for the selected provider from ``TRANSLATIONS_PROVIDERS``. Examples: ``gpt-5.2``, ``gemini-3-pro-preview``, ``mistral-large-latest``
380
+ - ``--repo-path``: Path to mitxonline-translations repository (can also be set via ``TRANSLATIONS_REPO_PATH`` setting or environment variable)
381
+ - ``--repo-url``: GitHub repository URL (default: ``https://github.com/mitodl/mitxonline-translations.git``, can also be set via ``TRANSLATIONS_REPO_URL`` setting or environment variable)
382
+ - ``--glossary``: Use glossary from plugin glossaries folder (looks for ``{plugin_dir}/glossaries/machine_learning/{lang_code}.txt``)
383
+ - ``--batch-size``: Number of keys to translate per API request (default: 200, recommended: 200-300 for most models)
384
+ - ``--mfe``: Filter by specific MFE(s). Use ``edx-platform`` for backend translations
385
+ - ``--dry-run``: Run without committing or creating PR
386
+
387
+ **Examples:**
388
+
389
+ .. code-block:: bash
390
+
391
+ # Use default provider (from TRANSLATIONS_PROVIDERS['default_provider']) with its default model
392
+ ./manage.py cms sync_and_translate_language el
393
+
394
+ # Use OpenAI provider with its default model (gpt-5.2)
395
+ ./manage.py cms sync_and_translate_language el --provider openai
396
+
397
+ # Use OpenAI provider with a specific model
398
+ ./manage.py cms sync_and_translate_language el --provider openai --model gpt-5.2
399
+
400
+ # Use Mistral provider with a specific model and glossary
401
+ ./manage.py cms sync_and_translate_language el --provider mistral --model mistral-large-latest --glossary --batch-size 250
402
+
403
+ License
404
+ *******
405
+
406
+ The code in this repository is licensed under the AGPL 3.0 unless
407
+ otherwise noted.
408
+
409
+ Please see `LICENSE.txt <LICENSE.txt>`_ for details.
@@ -0,0 +1,40 @@
1
+ ol_openedx_course_translations/__init__.py,sha256=qddojx2E0sw3CdZ_iyjwt3iTN_oTPCo1iPtRMSEgyHA,50
2
+ ol_openedx_course_translations/admin.py,sha256=MXtJCUydPjG6xoAc8oebtkQrmRZH-9IV8y6luzvrIlg,827
3
+ ol_openedx_course_translations/apps.py,sha256=__HhrdS6Tb4A0cVF9kZlJSs1JKhMeLNVnWXPx91k2oo,1057
4
+ ol_openedx_course_translations/filters.py,sha256=m7Gth09EWZelR_5pZGavmxczQ63fsFbCDbogl1-5lMY,1505
5
+ ol_openedx_course_translations/middleware.py,sha256=f5D6ZHlFhsdiOHForrPwHc--ZJWMygVhjXpFpwUJxMs,4608
6
+ ol_openedx_course_translations/models.py,sha256=muqwNYBtbON3Ru6Uq9krorYF1JmbIGOiBzWC-X7CBoU,1787
7
+ ol_openedx_course_translations/tasks.py,sha256=fxxd4mMV8HxtOY-y6kvM-oNjoif4iJE-V2aVyFua0OE,8071
8
+ ol_openedx_course_translations/urls.py,sha256=wDlOrRTtV_YRXAA1lpIhjEEf_fNkyfZUtmVPMD1PEi8,385
9
+ ol_openedx_course_translations/views.py,sha256=ESDmgSFAvyHKQE9s2hthyNgRZmMuLNWvfrGkR4isoec,2173
10
+ ol_openedx_course_translations/glossaries/machine_learning/ar.txt,sha256=f8Ga8GV3qXFVvmlYx3JAfBC-HNIMW5FbLrqTR_jIwWM,9065
11
+ ol_openedx_course_translations/glossaries/machine_learning/de.txt,sha256=dEQx_qeeMc5DMAwKM4liRuGor0ZJu0zxsseD3npJyeE,7865
12
+ ol_openedx_course_translations/glossaries/machine_learning/el.txt,sha256=i8dtMpI0S1sYcjej-kvzdXCXnoAsjETiPx43kvVsOT8,67171
13
+ ol_openedx_course_translations/glossaries/machine_learning/es.txt,sha256=mM5PAW6Jv7qd--saDJdVRwvPHnOe1RPnd3uUX_ckfOQ,7694
14
+ ol_openedx_course_translations/glossaries/machine_learning/fr.txt,sha256=q3JEPWa-C6GeY2vZhB528vERmhgUTgYiRmRn1vSsJCI,7892
15
+ ol_openedx_course_translations/glossaries/machine_learning/ja.txt,sha256=Xa83zxPdwfN05QB2H4NfzkFZyYsKoruoJ3e9D-ka2fY,8028
16
+ ol_openedx_course_translations/glossaries/machine_learning/pt-br.txt,sha256=68_mu_IEZpC-jswmrpEDiq3R86IF0zMdJ6Km7kCiDM4,7507
17
+ ol_openedx_course_translations/glossaries/machine_learning/ru.txt,sha256=d-p1UcxBy7cz0MJfB35sBQIOHV27PK9nIXpFfVEDGMU,11984
18
+ ol_openedx_course_translations/management/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
+ ol_openedx_course_translations/management/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
+ ol_openedx_course_translations/management/commands/sync_and_translate_language.py,sha256=E2sLaXYBTI1qCYcocV022Q-06y9iIA1YTMN5rHsb078,70176
21
+ ol_openedx_course_translations/management/commands/translate_course.py,sha256=QFSR63sO07urXU9BWYj0iv4Xy1Xd94RkV5nvUjpJdeI,22633
22
+ ol_openedx_course_translations/migrations/0001_add_translation_logs.py,sha256=nitP-DJjDIeK9F3IcA1HvE5jpFaGCaoDP00XQxrjcSc,2876
23
+ ol_openedx_course_translations/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
24
+ ol_openedx_course_translations/providers/__init__.py,sha256=ZTWIG9KsYXYElfr-QwMsId7l6Sh6MypDKCWTivk3PME,48
25
+ ol_openedx_course_translations/providers/base.py,sha256=-1QV7w-6Wpwz4EMzCiOOuWOG2kDw4b2gZ1KSK6GFVLM,9264
26
+ ol_openedx_course_translations/providers/deepl_provider.py,sha256=hPuLVEZLU3Dm6a9H-8ztpcX53K9gUA8e57jUzn_HsKU,10076
27
+ ol_openedx_course_translations/providers/llm_providers.py,sha256=BIijQgVudTytxtrCvB-NTN9FvA8YPMFiB-77pAHjP-4,19953
28
+ ol_openedx_course_translations/settings/cms.py,sha256=SzoTxVUlvlWvjQ58GCoVygHjoMNAH3InME7T9K6dTQ4,392
29
+ ol_openedx_course_translations/settings/common.py,sha256=NXrBo-GmL-nMZzQvDH-S7p8jy3SIR7spuOI8dZuexe0,1788
30
+ ol_openedx_course_translations/settings/lms.py,sha256=381QL_84D-GxD97rZcsUsdjoYRUqcxWbbrzndkliRRY,1320
31
+ ol_openedx_course_translations/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
32
+ ol_openedx_course_translations/utils/command_utils.py,sha256=GRSGIBKm6ZnRCnv5oVRzxhS6UFwvjmNeJkvCEpLCks0,6482
33
+ ol_openedx_course_translations/utils/constants.py,sha256=geIe61KP4N1piXw-kr8QuACkw79pd8T1xeROq17LHyA,8171
34
+ ol_openedx_course_translations/utils/course_translations.py,sha256=ZGh6YKNFR0MlNeYC1oCABCe0cbAWxLslpXj6jvO7WSs,21639
35
+ ol_openedx_course_translations/utils/translation_sync.py,sha256=IQL-auVk5GwSfUfyeGICUDhd1KPxZs_bthAzRYm9LSs,26739
36
+ ol_openedx_course_translations-0.3.5.dist-info/METADATA,sha256=e08wH5Ldm9qovRG2QTCVGCrc-iG9qwr0Xc135sx0m4I,16828
37
+ ol_openedx_course_translations-0.3.5.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
38
+ ol_openedx_course_translations-0.3.5.dist-info/entry_points.txt,sha256=FPeAXhaGYIZqafskkDD8xPiljXJ6djil27_kTuNP0BI,239
39
+ ol_openedx_course_translations-0.3.5.dist-info/licenses/LICENSE.txt,sha256=iVk4rSDx0SwrA7AriwFblTY0vUxpuVib1oqJEEeejN0,1496
40
+ ol_openedx_course_translations-0.3.5.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ [cms.djangoapp]
2
+ ol_openedx_course_translations = ol_openedx_course_translations.apps:OLOpenedXCourseTranslationsConfig
3
+
4
+ [lms.djangoapp]
5
+ ol_openedx_course_translations = ol_openedx_course_translations.apps:OLOpenedXCourseTranslationsConfig
@@ -1,63 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: ol-openedx-course-translations
3
- Version: 0.1.0
4
- Summary: An Open edX plugin to translate courses
5
- Author: MIT Office of Digital Learning
6
- License-Expression: BSD-3-Clause
7
- License-File: LICENSE.txt
8
- Keywords: Python,edx
9
- Requires-Python: >=3.11
10
- Requires-Dist: deepl>=1.25.0
11
- Requires-Dist: django>=4.0
12
- Requires-Dist: djangorestframework>=3.14.0
13
- Description-Content-Type: text/x-rst
14
-
15
- OL Open edX Course Translations
16
- ===============================
17
-
18
- An Open edX plugin to manage course translations.
19
-
20
- Purpose
21
- *******
22
-
23
- Translate course content into multiple languages to enhance accessibility for a global audience.
24
-
25
- Setup
26
- =====
27
-
28
- For detailed installation instructions, please refer to the `plugin installation guide <../../docs#installation-guide>`_.
29
-
30
- Installation required in:
31
-
32
- * Studio (CMS)
33
-
34
- Configuration
35
- =============
36
-
37
- - Add the following configuration values to the config file in Open edX. For any release after Juniper, that config file is ``/edx/etc/lms.yml``. If you're using ``private.py``, add these values to ``lms/envs/private.py``. These should be added to the top level. **Ask a fellow developer for these values.**
38
-
39
- .. code-block:: python
40
-
41
- DEEPL_API_KEY: <YOUR_DEEPL_API_KEY_HERE>
42
-
43
- - For Tutor installations, these values can also be managed through a `custom Tutor plugin <https://docs.tutor.edly.io/tutorials/plugin.html#plugin-development-tutorial>`_.
44
-
45
- Usage
46
- ====================
47
- 1. Open the course in Studio.
48
- 2. Go to Tools -> Export Course.
49
- 3. Export the course as a .tar.gz file.
50
- 4. Go to the CMS shell
51
- 5. Run the management command to translate the course:
52
-
53
- .. code-block:: bash
54
-
55
- ./manage.py cms translate_course --source-language <SOURCE_LANGUAGE_CODE, defaults to `EN`> --translation-language <TRANSLATION_LANGUAGE_CODE i.e. AR> --course-dir <PATH_TO_EXPORTED_COURSE_TAR_GZ>
56
-
57
- License
58
- *******
59
-
60
- The code in this repository is licensed under the AGPL 3.0 unless
61
- otherwise noted.
62
-
63
- Please see `LICENSE.txt <LICENSE.txt>`_ for details.
@@ -1,11 +0,0 @@
1
- ol_openedx_course_translations/__init__.py,sha256=qddojx2E0sw3CdZ_iyjwt3iTN_oTPCo1iPtRMSEgyHA,50
2
- ol_openedx_course_translations/apps.py,sha256=AUjqONJsiuip2qG4R_CmQ1IIXoFvdEt-_G64-YWtntU,637
3
- ol_openedx_course_translations/management/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- ol_openedx_course_translations/management/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
- ol_openedx_course_translations/management/commands/translate_course.py,sha256=0H4jFC-9zbE3uMl325HW6kCXUnA4MgiS2X6Osg8xKB8,21781
6
- ol_openedx_course_translations/settings/common.py,sha256=lzxBIJ1K8upO8Zv6WESl42NUX0xnX5otd0eEa_ko_-c,1074
7
- ol_openedx_course_translations-0.1.0.dist-info/METADATA,sha256=s2ujGEgFhgJpWUoVxWWgNdmx1FKNSC66-Fc-vXV0G2A,1994
8
- ol_openedx_course_translations-0.1.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
9
- ol_openedx_course_translations-0.1.0.dist-info/entry_points.txt,sha256=07_M_0RSXTPpCQcstKi9xP27jZY-pSwZeeMrGX0mEf8,119
10
- ol_openedx_course_translations-0.1.0.dist-info/licenses/LICENSE.txt,sha256=iVk4rSDx0SwrA7AriwFblTY0vUxpuVib1oqJEEeejN0,1496
11
- ol_openedx_course_translations-0.1.0.dist-info/RECORD,,
@@ -1,2 +0,0 @@
1
- [cms.djangoapp]
2
- ol_openedx_course_translations = ol_openedx_course_translations.apps:OLOpenedXCourseTranslationsConfig