Преглед на файлове

[refactor] Language is now a doctype (#2003)

version-14
Rushabh Mehta преди 8 години
committed by GitHub
родител
ревизия
f30a6b8360
променени са 23 файла, в които са добавени 1965 реда и са изтрити 1590 реда
  1. +0
    -3
      frappe/build.py
  2. +0
    -0
      frappe/core/doctype/language/__init__.py
  3. +8
    -0
      frappe/core/doctype/language/language.js
  4. +160
    -0
      frappe/core/doctype/language/language.json
  5. +33
    -0
      frappe/core/doctype/language/language.py
  6. +12
    -0
      frappe/core/doctype/language/test_language.py
  7. +0
    -1
      frappe/core/doctype/system_settings/system_settings.js
  8. +4
    -3
      frappe/core/doctype/system_settings/system_settings.json
  9. +0
    -3
      frappe/core/doctype/translation/translation.js
  10. +0
    -2
      frappe/core/doctype/user/user.js
  11. +1472
    -1472
      frappe/core/doctype/user/user.json
  12. +0
    -57
      frappe/data/languages.txt
  13. +8
    -8
      frappe/desk/page/setup_wizard/setup_wizard.py
  14. +1
    -0
      frappe/geo/country_info.json
  15. +230
    -0
      frappe/geo/languages.json
  16. +3
    -0
      frappe/migrate.py
  17. +1
    -1
      frappe/public/css/docs.css
  18. +1
    -0
      frappe/public/css/form_grid.css
  19. +1
    -7
      frappe/public/js/frappe/translate.js
  20. +1
    -0
      frappe/public/less/form_grid.less
  21. +1
    -1
      frappe/templates/generators/web_form.html
  22. +29
    -31
      frappe/translate.py
  23. +0
    -1
      test_sites/languages.txt

+ 0
- 3
frappe/build.py Целия файл

@@ -77,9 +77,6 @@ def build(no_compress=False, verbose=False):
for target, sources in get_build_maps().iteritems():
pack(os.path.join(assets_path, target), sources, no_compress, verbose)

shutil.copy(os.path.join(os.path.dirname(os.path.abspath(frappe.__file__)), 'data', 'languages.txt'), frappe.local.sites_path)
# reset_app_html()

def get_build_maps():
"""get all build.jsons with absolute paths"""
# framework js and css files


+ 0
- 0
frappe/core/doctype/language/__init__.py Целия файл


+ 8
- 0
frappe/core/doctype/language/language.js Целия файл

@@ -0,0 +1,8 @@
// Copyright (c) 2016, Frappe Technologies and contributors
// For license information, please see license.txt

frappe.ui.form.on('Language', {
refresh: function(frm) {

}
});

+ 160
- 0
frappe/core/doctype/language/language.json Целия файл

@@ -0,0 +1,160 @@
{
"allow_copy": 0,
"allow_import": 0,
"allow_rename": 0,
"autoname": "field:language_code",
"beta": 0,
"creation": "2014-08-22 16:12:17.249590",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "Setup",
"editable_grid": 0,
"fields": [
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"fieldname": "language_code",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Language Code",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"fieldname": "language_name",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Language Name",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"fieldname": "flag",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Flag",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"fieldname": "based_on",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Based On",
"length": 0,
"no_copy": 0,
"options": "Language",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
}
],
"hide_heading": 0,
"hide_toolbar": 0,
"icon": "icon-globe",
"idx": 0,
"image_view": 0,
"in_create": 0,
"in_dialog": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2016-08-23 15:06:32.827147",
"modified_by": "Administrator",
"module": "Core",
"name": "Language",
"name_case": "",
"owner": "Administrator",
"permissions": [
{
"amend": 0,
"apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 1,
"email": 0,
"export": 0,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 0,
"read": 1,
"report": 0,
"role": "System Manager",
"set_user_permissions": 0,
"share": 0,
"submit": 0,
"write": 1
}
],
"quick_entry": 0,
"read_only": 0,
"read_only_onload": 0,
"search_fields": "language_name",
"sort_field": "modified",
"sort_order": "DESC",
"title_field": "language_name",
"track_seen": 0
}

+ 33
- 0
frappe/core/doctype/language/language.py Целия файл

@@ -0,0 +1,33 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2015, Frappe Technologies and contributors
# For license information, please see license.txt

from __future__ import unicode_literals
import frappe, json
from frappe.model.document import Document

class Language(Document):
pass

def export_languages_json():
'''Export list of all languages'''
languages = frappe.db.get_all('Language', fields=['name', 'language_name'])
languages = [{'name': d.language_name, 'code': d.name} for d in languages]

languages.sort(lambda a,b: 1 if a['code'] > b['code'] else -1)

with open(frappe.get_app_path('frappe', 'geo', 'languages.json'), 'w') as f:
f.write(frappe.as_json(languages))

def sync_languages():
'''Sync frappe/geo/languages.json with Language'''
with open(frappe.get_app_path('frappe', 'geo', 'languages.json'), 'r') as f:
data = json.loads(f.read())

for l in data:
if not frappe.db.exists('Language', l['code']):
frappe.get_doc({
'doctype': 'Language',
'language_code': l['code'],
'language_name': l['name']
}).insert()

+ 12
- 0
frappe/core/doctype/language/test_language.py Целия файл

@@ -0,0 +1,12 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2015, Frappe Technologies and Contributors
# See license.txt
from __future__ import unicode_literals

import frappe
import unittest

# test_records = frappe.get_test_records('Language')

class TestLanguage(unittest.TestCase):
pass

+ 0
- 1
frappe/core/doctype/system_settings/system_settings.js Целия файл

@@ -1,5 +1,4 @@
frappe.ui.form.on("System Settings", "refresh", function(frm) {
frappe.setup_language_field(frm);
frappe.call({
method: "frappe.core.doctype.system_settings.system_settings.load",
callback: function(data) {


+ 4
- 3
frappe/core/doctype/system_settings/system_settings.json Целия файл

@@ -8,6 +8,7 @@
"docstatus": 0,
"doctype": "DocType",
"document_type": "System",
"editable_grid": 0,
"fields": [
{
"allow_on_submit": 0,
@@ -64,7 +65,7 @@
"bold": 0,
"collapsible": 0,
"fieldname": "language",
"fieldtype": "Select",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -73,7 +74,7 @@
"label": "Language",
"length": 0,
"no_copy": 0,
"options": "Loading...",
"options": "Language",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
@@ -621,7 +622,7 @@
"issingle": 1,
"istable": 0,
"max_attachments": 0,
"modified": "2016-06-25 19:25:20.090354",
"modified": "2016-08-23 15:12:00.582281",
"modified_by": "Administrator",
"module": "Core",
"name": "System Settings",


+ 0
- 3
frappe/core/doctype/translation/translation.js Целия файл

@@ -3,9 +3,6 @@


frappe.ui.form.on('Translation', {
before_load: function(frm) {
frappe.setup_language_field(frm);
},
language: function(frm) {
frm.events.update_language_code(frm);
},


+ 0
- 2
frappe/core/doctype/user/user.js Целия файл

@@ -1,7 +1,5 @@
frappe.ui.form.on('User', {
before_load: function(frm) {
frappe.setup_language_field(frm);

var update_tz_select = function(user_language) {
frm.set_df_property("time_zone", "options", [""].concat(frappe.all_timezones));
}


+ 1472
- 1472
frappe/core/doctype/user/user.json
Файловите разлики са ограничени, защото са твърде много
Целия файл


+ 0
- 57
frappe/data/languages.txt Целия файл

@@ -1,57 +0,0 @@
ar العربية
bg bǎlgarski
bn বাংলা
bo ལྷ་སའི་སྐད་
bs bosanski
ca català
cs česky
da dansk
da-DK dansk (Danmark)
de deutsch
el ελληνικά
en english
es español
es-PE Español (Perú)
et eesti
fa پارسی
fi suomalainen
fr français
gu ગુજરાતી
he עברית
hi हिंदी
hr hrvatski
hu magyar
id Indonesia
is íslenska
it italiano
ja 日本語
km ភាសាខ្មែរ
kn ಕನ್ನಡ
ko 한국의
lv latviešu valoda
mk македонски
ml മലയാളം
mr मराठी
ms Melayu
my မြန်မာ
nl nederlands
no norsk
pl polski
pt português
pt-BR português brasileiro
ro român
ru русский
sk slovenčina (Slovak)
sl slovenščina (Slovene)
sv svenska
sq shqiptar
sr српски
ta தமிழ்
te తెలుగు
th ไทย
tr Türk
uk українська
ur اردو
vi việt
zh-cn 簡體中文
zh-tw 正體中文

+ 8
- 8
frappe/desk/page/setup_wizard/setup_wizard.py Целия файл

@@ -6,8 +6,7 @@ from __future__ import unicode_literals
import frappe, json, os
from frappe.utils import strip, cint
from frappe import _
from frappe.translate import (set_default_language, get_dict,
get_lang_dict, send_translations, get_language_from_code)
from frappe.translate import (set_default_language, get_dict, send_translations)
from frappe.geo.country_info import get_country_info
from frappe.utils.file_manager import save_file
from frappe.utils.password import update_password
@@ -25,7 +24,7 @@ def setup_complete(args):

try:
if args.language and args.language != "english":
set_default_language(args.language)
set_default_language(get_language_code(args.lang))

frappe.clear_cache()

@@ -67,7 +66,7 @@ def update_system_settings(args):
system_settings = frappe.get_doc("System Settings", "System Settings")
system_settings.update({
"country": args.get("country"),
"language": args.get("language"),
"language": get_language_code(args.get("language")),
"time_zone": args.get("timezone"),
"float_precision": 3,
'date_format': frappe.db.get_value("Country", args.get("country"), "date_format"),
@@ -151,7 +150,7 @@ def load_messages(language):
"""Load translation messages for given language from all `setup_wizard_requires`
javascript files"""
frappe.clear_cache()
set_default_language(language)
set_default_language(get_language_code(language))
m = get_dict("page", "setup-wizard")

for path in frappe.get_hooks("setup_wizard_requires"):
@@ -166,8 +165,8 @@ def load_messages(language):
@frappe.whitelist()
def load_languages():
return {
"default_language": get_language_from_code(frappe.local.lang),
"languages": sorted(get_lang_dict().keys())
"default_language": frappe.db.get_value('Language', frappe.local.lang, 'language_name') or frappe.local.lang,
"languages": sorted(frappe.db.sql_list('select language_name from tabLanguage'))
}


@@ -235,4 +234,5 @@ def email_setup_wizard_exception(traceback, args):
message=message,
delayed=False)


def get_language_code(lang):
return frappe.db.get_value('Language', {'language_name':lang})

+ 1
- 0
frappe/geo/country_info.json Целия файл

@@ -1,6 +1,7 @@
{
"Afghanistan": {
"code": "af",
"currency": "AFN",
"currency_fraction": "Pul",
"currency_fraction_units": 100,
"currency_symbol": "\u060b",


+ 230
- 0
frappe/geo/languages.json Целия файл

@@ -0,0 +1,230 @@
[
{
"code": "ar",
"name": "\u0627\u0644\u0639\u0631\u0628\u064a\u0629"
},
{
"code": "bg",
"name": "b\u01celgarski"
},
{
"code": "bn",
"name": "\u09ac\u09be\u0982\u09b2\u09be"
},
{
"code": "bo",
"name": "\u0f63\u0fb7\u0f0b\u0f66\u0f60\u0f72\u0f0b\u0f66\u0f90\u0f51\u0f0b"
},
{
"code": "bs",
"name": "bosanski"
},
{
"code": "ca",
"name": "catal\u00e0"
},
{
"code": "cs",
"name": "\u010desky"
},
{
"code": "da",
"name": "dansk"
},
{
"code": "da-DK",
"name": "dansk (Danmark)"
},
{
"code": "de",
"name": "deutsch"
},
{
"code": "el",
"name": "\u03b5\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u03ac"
},
{
"code": "en",
"name": "english"
},
{
"code": "es",
"name": "espa\u00f1ol"
},
{
"code": "es-PE",
"name": "Espa\u00f1ol (Per\u00fa)"
},
{
"code": "et",
"name": "eesti"
},
{
"code": "fa",
"name": "\u067e\u0627\u0631\u0633\u06cc"
},
{
"code": "fi",
"name": "suomalainen"
},
{
"code": "fr",
"name": "fran\u00e7ais"
},
{
"code": "gu",
"name": "\u0a97\u0ac1\u0a9c\u0ab0\u0abe\u0aa4\u0ac0"
},
{
"code": "he",
"name": "\u05e2\u05d1\u05e8\u05d9\u05ea"
},
{
"code": "hi",
"name": "\u0939\u093f\u0902\u0926\u0940"
},
{
"code": "hr",
"name": "hrvatski"
},
{
"code": "hu",
"name": "magyar"
},
{
"code": "id",
"name": "Indonesia"
},
{
"code": "is",
"name": "\u00edslenska"
},
{
"code": "it",
"name": "italiano"
},
{
"code": "ja",
"name": "\u65e5\u672c\u8a9e"
},
{
"code": "km",
"name": "\u1797\u17b6\u179f\u17b6\u1781\u17d2\u1798\u17c2\u179a"
},
{
"code": "kn",
"name": "\u0c95\u0ca8\u0ccd\u0ca8\u0ca1"
},
{
"code": "ko",
"name": "\ud55c\uad6d\uc758"
},
{
"code": "lv",
"name": "latvie\u0161u valoda"
},
{
"code": "mk",
"name": "\u043c\u0430\u043a\u0435\u0434\u043e\u043d\u0441\u043a\u0438"
},
{
"code": "ml",
"name": "\u0d2e\u0d32\u0d2f\u0d3e\u0d33\u0d02"
},
{
"code": "mr",
"name": "\u092e\u0930\u093e\u0920\u0940"
},
{
"code": "ms",
"name": "Melayu"
},
{
"code": "my",
"name": "\u1019\u103c\u1014\u103a\u1019\u102c"
},
{
"code": "nl",
"name": "nederlands"
},
{
"code": "no",
"name": "norsk"
},
{
"code": "pl",
"name": "polski"
},
{
"code": "pt",
"name": "portugu\u00eas"
},
{
"code": "pt-BR",
"name": "portugu\u00eas brasileiro"
},
{
"code": "ro",
"name": "rom\u00e2n"
},
{
"code": "ru",
"name": "\u0440\u0443\u0441\u0441\u043a\u0438\u0439"
},
{
"code": "sk",
"name": "sloven\u010dina (Slovak)"
},
{
"code": "sl",
"name": "sloven\u0161\u010dina (Slovene)"
},
{
"code": "sq",
"name": "shqiptar"
},
{
"code": "sr",
"name": "\u0441\u0440\u043f\u0441\u043a\u0438"
},
{
"code": "sv",
"name": "svenska"
},
{
"code": "ta",
"name": "\u0ba4\u0bae\u0bbf\u0bb4\u0bcd"
},
{
"code": "te",
"name": "\u0c24\u0c46\u0c32\u0c41\u0c17\u0c41"
},
{
"code": "th",
"name": "\u0e44\u0e17\u0e22"
},
{
"code": "tr",
"name": "T\u00fcrk"
},
{
"code": "uk",
"name": "\u0443\u043a\u0440\u0430\u0457\u043d\u0441\u044c\u043a\u0430"
},
{
"code": "ur",
"name": "\u0627\u0631\u062f\u0648"
},
{
"code": "vi",
"name": "vi\u1ec7t"
},
{
"code": "zh-cn",
"name": "\u7c21\u9ad4\u4e2d\u6587"
},
{
"code": "zh-tw",
"name": "\u6b63\u9ad4\u4e2d\u6587"
}
]

+ 3
- 0
frappe/migrate.py Целия файл

@@ -12,6 +12,7 @@ from frappe.sessions import clear_global_cache
from frappe.desk.notifications import clear_notifications
from frappe.website import render
from frappe.desk.doctype.desktop_icon.desktop_icon import sync_desktop_icons
from frappe.core.doctype.language.language import sync_languages

def migrate(verbose=True, rebuild_website=False):
'''Migrate all apps to the latest version, will:
@@ -30,6 +31,8 @@ def migrate(verbose=True, rebuild_website=False):
frappe.translate.clear_cache()
sync_fixtures()
sync_desktop_icons()
sync_languages()

frappe.get_doc('Portal Settings', 'Portal Settings').sync_menu()

# syncs statics


+ 1
- 1
frappe/public/css/docs.css Целия файл

@@ -79,7 +79,7 @@
.dropdown-help .dropdown-menu {
width: 350px !important;
max-height: 440px;
overflow: scroll;
overflow: auto;
}
.dropdown-help .dropdown-menu .input-group {
width: 100%;


+ 1
- 0
frappe/public/css/form_grid.css Целия файл

@@ -39,6 +39,7 @@
}
.grid-body .data-row {
font-size: 12px;
overflow: hidden;
}
.grid-empty,
.list-loading {


+ 1
- 7
frappe/public/js/frappe/translate.js Целия файл

@@ -25,10 +25,4 @@ frappe.get_languages = function() {
frappe.languages = frappe.languages.sort(function(a, b) { return (a.value < b.value) ? -1 : 1 });
}
return frappe.languages;
};

frappe.setup_language_field = function(frm, fieldname) {
if (!fieldname) fieldname = 'language';
frm.set_df_property(fieldname, "options", [''].concat(frappe.get_languages()) || ["", "english"]);
frm.get_field(fieldname).set_input(frm.doc[fieldname] || '');
}
};

+ 1
- 0
frappe/public/less/form_grid.less Целия файл

@@ -52,6 +52,7 @@

.grid-body .data-row {
font-size: 12px;
overflow: hidden;
}

.grid-empty, .list-loading {


+ 1
- 1
frappe/templates/generators/web_form.html Целия файл

@@ -276,7 +276,7 @@ frappe.ready(function() {
.html('{{ success_message }}<p><a href="{{ success_url }}">{{ _("Continue") }}</a></p>')
.removeClass("hide");
} else {
frappe.msgprint(__('Successfully Updated. Redirecting...'));
frappe.msgprint(__('Successfully Updated'));
setTimeout(function() {
window.location.href = "{{ success_url }}";
}, 3000);


+ 29
- 31
frappe/translate.py Целия файл

@@ -52,12 +52,9 @@ def get_user_lang(user=None):
if not lang:

# if defined in user profile
user_lang = frappe.db.get_value("User", user, "language")
if user_lang and user_lang!="Loading...":
lang = get_lang_code(user_lang)
else:
default_lang = frappe.db.get_default("lang")
lang = get_lang_code(default_lang)
lang = frappe.db.get_value("User", user, "language")
if not lang:
lang = frappe.db.get_default("lang")

if not lang:
lang = frappe.local.lang or 'en'
@@ -67,29 +64,24 @@ def get_user_lang(user=None):
return lang

def get_lang_code(lang):
return get_lang_dict().get(lang, lang)
return frappe.db.get_value('Language', {'language_name': lang}) or lang

def set_default_language(language):
def set_default_language(lang):
"""Set Global default language"""
lang = get_lang_dict().get(language, language)
frappe.db.set_default("lang", lang)
frappe.local.lang = lang

def get_all_languages():
"""Returns all language codes ar, ch etc"""
return [a.split()[0] for a in get_lang_info()]
def _get():
if not frappe.db:
frappe.connect()
return frappe.db.sql_list('select name from tabLanguage')
return frappe.cache().get_value('languages', _get)

def get_lang_dict():
"""Returns all languages in dict format, full name is the key e.g. `{"english":"en"}`"""
return dict([[a[1], a[0]] for a in [a.split(None, 1) for a in get_lang_info()]])

def get_language_from_code(lang):
return dict(a.split(None, 1) for a in get_lang_info()).get(lang)

def get_lang_info():
"""Returns a listified version of `apps/languages.txt`"""
return frappe.cache().get_value("langinfo",
lambda:frappe.get_file_items(os.path.join(frappe.local.sites_path, "languages.txt")))
return dict(frappe.db.sql('select language_name, name from tabLanguage'))

def get_dict(fortype, name=None):
"""Returns translation dict for a type of object.
@@ -183,13 +175,7 @@ def get_full_dict(lang):
if frappe.local.lang_full_dict is not None:
return frappe.local.lang_full_dict

frappe.local.lang_full_dict = frappe.cache().hget("lang_full_dict", lang)

if frappe.local.lang_full_dict is None:
frappe.local.lang_full_dict = load_lang(lang)

# only cache file translations in this
frappe.cache().hset("lang_full_dict", lang, frappe.local.lang_full_dict)
frappe.local.lang_full_dict = load_lang(lang)

try:
# get user specific transaltion data
@@ -203,11 +189,23 @@ def get_full_dict(lang):
return frappe.local.lang_full_dict

def load_lang(lang, apps=None):
"""Combine all translations from `.csv` files in all `apps`"""
out = {}
for app in (apps or frappe.get_all_apps(True)):
path = os.path.join(frappe.get_pymodule_path(app), "translations", lang + ".csv")
out.update(get_translation_dict_from_file(path, lang, app))
"""Combine all translations from `.csv` files in all `apps`.
For derivative languages (es-GT), take translations from the
base language (es) and then update translations from the child (es-GT)"""

out = frappe.cache().hget("lang_full_dict", lang)
if not out:
out = {}
for app in (apps or frappe.get_all_apps(True)):
path = os.path.join(frappe.get_pymodule_path(app), "translations", lang + ".csv")
out.update(get_translation_dict_from_file(path, lang, app))

if '-' in lang:
parent = lang.split('-')[0]
out = load_lang(parent).update(out)

frappe.cache().hset("lang_full_dict", lang, out)

return out

def get_translation_dict_from_file(path, lang, app):


+ 0
- 1
test_sites/languages.txt Целия файл

@@ -1 +0,0 @@
en english

Зареждане…
Отказ
Запис