Hi,

Please find the attached updated patch.

Thanks,
Khushboo

On Fri, Mar 17, 2017 at 6:02 PM, Dave Page <dp...@pgadmin.org> wrote:

> Hi
>
> On Fri, Mar 17, 2017 at 12:17 PM, Khushboo Vashi
> <khushboo.va...@enterprisedb.com> wrote:
> > Hi,
> >
> > Please find the attached updated patch.
> >
> > Thanks,
> > Khushboo
> >
> > On Fri, Mar 17, 2017 at 4:20 PM, Dave Page <dp...@pgadmin.org> wrote:
> >>
> >> Hi
> >>
> >> On Fri, Mar 17, 2017 at 10:25 AM, Khushboo Vashi
> >> <khushboo.va...@enterprisedb.com> wrote:
> >> > Hi,
> >> >
> >> > On Mon, Mar 13, 2017 at 4:09 PM, Dave Page <dp...@pgadmin.org> wrote:
> >> >>
> >> >> Hi
> >> >>
> >> >> On Fri, Mar 10, 2017 at 1:55 PM, Khushboo Vashi
> >> >> <khushboo.va...@enterprisedb.com> wrote:
> >> >> > Hi,
> >> >> >
> >> >> > Please find the attached patch for #2190: Move language selection
> to
> >> >> > Preferences.
> >> >> >
> >> >> > Moved the user language selection into Preferences.
> >> >> >
> >> >> > For the desktop mode, if the user has selected the language from
> the
> >> >> > Preferences then that will be reflected otherwise English will be
> the
> >> >> > default language.
> >> >> > For the server mode, we have given an option on the log-in page to
> >> >> > choose
> >> >> > the language. We drop the cookie for the selected language and also
> >> >> > update
> >> >> > the preferences for the same.
> >> >> > So, the app will be loaded with the language which the user has
> >> >> > selected
> >> >> > on
> >> >> > the log-in page.
> >> >> > If the user will change the language from the preferences, then the
> >> >> > cookie
> >> >> > will be changed and also this change will be reflected on the
> log-in
> >> >> > page
> >> >> > next time.
> >> >>
> >> >> I found some issues with this patch - though it's possible those
> >> >> issues existed previously in some, perhaps all cases:
> >> >>
> >> >> - The Polish translation has a bug in it that causes a syntax error
> in
> >> >> sqleditor.js. I fixed that with:
> >> >>
> >> >> -msgstr "Całkowity czas wykonania zapytania: %s\n"
> >> >> +msgstr "Całkowity czas wykonania zapytania: %s"
> >> >>
> >> >> - If I choose a language for the first time at login, then the
> >> >> top-level menu bar isn't translated. If I completely refresh the
> page,
> >> >> then that is resolved. We haven't loaded the main page at this point
> I
> >> >> don't think, so I wouldn't expect to see this (though, maybe it is
> >> >> being cached so we need to ensure it gets invalidated)?
> >> >>
> >> > This was my code issue which I have fixed now.
> >> > When we receive the first request (after hitting Login button), I have
> >> > set
> >> > that language selection into the session.
> >> > If no session then it will pick up from the cookie.
> >> >
> >> >>
> >> >> - Like the top menu bar, the preferences panel doesn't seem to pickup
> >> >> the new language until a hard refresh is performed. For example, the
> >> >> attached screenshot is the result of me selecting Chinese at login,
> >> >> having previously used Polish. Perhaps we need to add "lang=cn" or
> >> >> similar to all URLs to force the cache to distinguish between
> >> >> languages?
> >> >>
> >> > In the preferences module, The aci-tree labels were not translated,
> that
> >> > has
> >> > been fixed now.
> >> > As I have introduced the session variable, so, I think we don't
> require
> >> > to
> >> > pass "lang=cn" to the URLS
> >> >
> >> >>
> >> >> - s/misc/Misc (the preference category).
> >> >>
> >> > I have changed it to Miscellaneous. (Like pgAdmin 3)
> >>
> >> That's much better. The only issues I see now are:
> >>
> >> - The descriptive help strings in the preferences dialogue are always
> >> shown in English
> >>
> > Fixed
>
> Nearly. I now see "None" as the help string for options that don't
> actually have a string. I'm also still seeing some that aren't
> translated - e.g. the binary paths options.
>
> Fixed

> >> - I'm seeing "miscellaneous" in all languages, not "Miscellaneous" or
> >> the translated version (e.g. "Pozostałe")
> >
> >
> > Fixed
>
> Yup :-)
>
> --
> Dave Page
> Blog: http://pgsnake.blogspot.com
> Twitter: @pgsnake
>
> EnterpriseDB UK: http://www.enterprisedb.com
> The Enterprise PostgreSQL Company
>
diff --git a/web/pgadmin/__init__.py b/web/pgadmin/__init__.py
index 1a14325..1054bde 100644
--- a/web/pgadmin/__init__.py
+++ b/web/pgadmin/__init__.py
@@ -14,7 +14,7 @@ import os, sys, time
 from collections import defaultdict
 from importlib import import_module
 
-from flask import Flask, abort, request, current_app
+from flask import Flask, abort, request, current_app, session
 from flask_babel import Babel, gettext
 from flask_htmlmin import HTMLMIN
 from flask_login import user_logged_in
@@ -29,6 +29,8 @@ from pgadmin.utils.session import create_session_interface
 from werkzeug.local import LocalProxy
 from werkzeug.utils import find_modules
 
+from pgadmin.utils.preferences import Preferences
+
 from pgadmin.model import db, Role, Server, ServerGroup, User, Version, Keys
 
 # If script is running under python3, it will not have the xrange function
@@ -189,8 +191,29 @@ def create_app(app_name=None):
 
     @babel.localeselector
     def get_locale():
-        """Get the best language for the user."""
-        language = request.accept_languages.best_match(config.LANGUAGES.keys())
+        """Get the language for the user."""
+        language = 'en'
+        if config.SERVER_MODE is False:
+            # Get the user language preference from the miscellaneous module
+            misc_preference = Preferences.module('miscellaneous', False)
+            if misc_preference:
+                user_languages = misc_preference.preference(
+                    'user_language'
+                )
+                if user_languages:
+                    language = user_languages.get() or language
+        else:
+            # If language is available in get request then return the same
+            # otherwise check the session or cookie
+            data = request.form
+            if 'language' in data:
+                language = data['language'] or language
+                setattr(session, 'PGADMIN_LANGUAGE', language)
+            elif hasattr(session, 'PGADMIN_LANGUAGE'):
+                language = getattr(session, 'PGADMIN_LANGUAGE', language)
+            elif hasattr(request.cookies, 'PGADMIN_LANGUAGE'):
+                language = getattr(request.cookies, 'PGADMIN_LANGUAGE', language)
+
         return language
 
     ##########################################################################
@@ -270,6 +293,27 @@ def create_app(app_name=None):
     driver.init_app(app)
 
     ##########################################################################
+    # Register language to the preferences after login
+    ##########################################################################
+    @user_logged_in.connect_via(app)
+    def register_language(sender, user):
+        # After logged in, set the language in the preferences if we get from
+        # the login page
+        data = request.form
+        if 'language' in data:
+            language = data['language']
+
+            # Set the user language preference
+            misc_preference = Preferences.module('miscellaneous')
+            user_languages = misc_preference.preference(
+                'user_language'
+            )
+
+            if user_languages and language:
+                language = user_languages.set(language)
+
+
+    ##########################################################################
     # Register any local servers we can discover
     ##########################################################################
     @user_logged_in.connect_via(app)
diff --git a/web/pgadmin/browser/__init__.py b/web/pgadmin/browser/__init__.py
index 18c7fbd..c801623 100644
--- a/web/pgadmin/browser/__init__.py
+++ b/web/pgadmin/browser/__init__.py
@@ -11,7 +11,8 @@ import json
 from abc import ABCMeta, abstractmethod, abstractproperty
 
 import six
-from flask import current_app, render_template, url_for, make_response, flash
+from flask import current_app, render_template, url_for, make_response, flash,\
+    Response, request
 from flask_babel import gettext
 from flask_login import current_user
 from flask_security import login_required
@@ -473,13 +474,26 @@ def index():
 
                 flash(msg, 'warning')
 
-    return render_template(
+    response = Response(render_template(
         MODULE_NAME + "/index.html",
         username=current_user.email,
         is_admin=current_user.has_role("Administrator"),
         _=gettext
+    ))
+
+    # Set the language cookie after login, so next time the user will have that
+    # same option at the login time.
+    misc_preference = Preferences.module('miscellaneous')
+    user_languages = misc_preference.preference(
+        'user_language'
     )
+    language = 'en'
+    if user_languages:
+        language = user_languages.get() or 'en'
+
+    response.set_cookie("PGADMIN_LANGUAGE", language)
 
+    return response
 
 @blueprint.route("/js/browser.js")
 @login_required
diff --git a/web/pgadmin/browser/server_groups/servers/types.py b/web/pgadmin/browser/server_groups/servers/types.py
index 02c04d6..9a82ac4 100644
--- a/web/pgadmin/browser/server_groups/servers/types.py
+++ b/web/pgadmin/browser/server_groups/servers/types.py
@@ -45,22 +45,27 @@ class ServerType(object):
 
     @classmethod
     def register_preferences(cls):
-        paths = Preferences('paths', _('Paths'))
-
-        for key in cls.registry:
-            st = cls.registry[key]
-            default_path = config.DEFAULT_BINARY_PATHS[st.stype] or ""
-
-            st.utility_path = paths.register(
-                'bin_paths', st.stype + '_bin_dir',
-                _("{0} Binary Path").format(st.desc),
-                'text', default_path, category_label=_('Binary paths'),
-                help_str=_(
-                    "Path to the directory containing the {0} utility programs (pg_dump, pg_restore etc).".format(
-                        st.desc
+        # Introduce inner function as we need to register the preferences after
+        # we get the user language and its translation.
+        def register_paths():
+            paths = Preferences('paths', _('Paths'))
+
+            for key in cls.registry:
+                st = cls.registry[key]
+                default_path = config.DEFAULT_BINARY_PATHS[st.stype] or ""
+
+                st.utility_path = paths.register(
+                    'bin_paths', st.stype + '_bin_dir',
+                    _("{0} Binary Path").format(st.desc),
+                    'text', default_path, category_label=_('Binary paths'),
+                    help_str=_(
+                        "Path to the directory containing the {0} utility"
+                        " programs (pg_dump, pg_restore etc).".format(
+                            st.desc
+                        )
                     )
                 )
-            )
+        return register_paths
 
     @property
     def priority(self):
diff --git a/web/pgadmin/misc/__init__.py b/web/pgadmin/misc/__init__.py
index e88b606..80ecd43 100644
--- a/web/pgadmin/misc/__init__.py
+++ b/web/pgadmin/misc/__init__.py
@@ -13,6 +13,7 @@ import pgadmin.utils.driver as driver
 from flask import url_for, render_template, Response
 from flask_babel import gettext as _
 from pgadmin.utils import PgAdminModule
+from pgadmin.utils.preferences import Preferences
 
 import config
 
@@ -41,6 +42,25 @@ class MiscModule(PgAdminModule):
         )
         return stylesheets
 
+    def register_preferences(self):
+        """
+        Register preferences for this module.
+        """
+        self.misc_preference = Preferences('miscellaneous', _('Miscellaneous'))
+
+        lang_options = []
+        for lang in config.LANGUAGES:
+            lang_options.append({'label': config.LANGUAGES[lang],
+                                 'value': lang})
+
+        # Register options for the User language settings
+        language = self.misc_preference.register(
+            'miscellaneous', 'user_language',
+            _("User language"), 'options', 'en',
+            category_label=_('User language'),
+            options=lang_options
+        )
+
 
 # Initialise the module
 blueprint = MiscModule(MODULE_NAME, __name__)
diff --git a/web/pgadmin/preferences/__init__.py b/web/pgadmin/preferences/__init__.py
index 9b7b362..502009e 100644
--- a/web/pgadmin/preferences/__init__.py
+++ b/web/pgadmin/preferences/__init__.py
@@ -13,7 +13,7 @@ side and for getting/setting preferences.
 """
 
 import simplejson as json
-from flask import render_template, url_for, Response, request
+from flask import render_template, url_for, Response, request, session
 from flask_babel import gettext
 from flask_login import current_user
 from flask_security import login_required
@@ -109,23 +109,28 @@ def preferences(module=None, preference=None):
     res = []
 
     def label(p):
-        return p['label']
+        return gettext(p['label'])
 
     for m in pref:
         if len(m['categories']):
             om = {
                 "id": m['id'],
-                "label": m['label'],
+                "label": gettext(m['label']),
                 "inode": True,
                 "open": True,
                 "branch": []
             }
 
             for c in m['categories']:
+                for p in c['preferences']:
+                    if 'label' in p and p['label'] is not None:
+                        p['label'] = gettext(p['label'])
+                    if 'help_str' in p and p['help_str'] is not None:
+                        p['help_str'] = gettext(p['help_str'])
                 oc = {
                     "id": c['id'],
                     "mid": m['id'],
-                    "label": c['label'],
+                    "label": gettext(c['label']),
                     "inode": False,
                     "open": False,
                     "preferences": sorted(c['preferences'], key=label)
@@ -155,4 +160,23 @@ def save(pid):
     if not res:
         return internal_server_error(errormsg=msg)
 
-    return success_return()
+    response = success_return()
+
+    # Set cookie & session for language settings.
+    # This will execute every time as could not find the better way to know
+    # that which preference is getting updated.
+
+    misc_preference = Preferences.module('miscellaneous')
+    user_languages = misc_preference.preference(
+        'user_language'
+    )
+
+    language = 'en'
+    if user_languages:
+        language = user_languages.get() or language
+
+    setattr(session, 'PGADMIN_LANGUAGE', language)
+    response.set_cookie("PGADMIN_LANGUAGE", language)
+
+    return response
+
diff --git a/web/pgadmin/preferences/templates/preferences/preferences.js b/web/pgadmin/preferences/templates/preferences/preferences.js
index 399ab01..453d207 100644
--- a/web/pgadmin/preferences/templates/preferences/preferences.js
+++ b/web/pgadmin/preferences/templates/preferences/preferences.js
@@ -219,7 +219,11 @@ define(
                   var opts = [];
                   // Convert the array to SelectControl understandable options.
                   _.each(p.options, function(o) {
-                    opts.push({'label': o, 'value': o});
+                    if('label' in o && 'value' in o){
+                      opts.push({'label': o.label, 'value': o.value});
+                    } else {
+                      opts.push({'label': o, 'value': o});
+                    }
                   });
                   p.options = opts;
                   return 'select2';
diff --git a/web/pgadmin/static/css/pgadmin.css b/web/pgadmin/static/css/pgadmin.css
index 9729d51..67e8b41 100644
--- a/web/pgadmin/static/css/pgadmin.css
+++ b/web/pgadmin/static/css/pgadmin.css
@@ -767,3 +767,16 @@ lgg-el-container[el=md] .pg-el-lg-8,
 .show_progress {
   cursor: progress;
 }
+.user-language {
+  margin-top: 10px;
+}
+.user-language label{
+  float:left;
+  font-weight: normal !important;
+}
+.user-language div{
+  float:left;
+}
+.user-language select{
+  height: 25px !important;
+}
\ No newline at end of file
diff --git a/web/pgadmin/templates/security/login_user.html b/web/pgadmin/templates/security/login_user.html
index 259c1b0..21646f4 100644
--- a/web/pgadmin/templates/security/login_user.html
+++ b/web/pgadmin/templates/security/login_user.html
@@ -3,10 +3,21 @@
 {% block panel_body %}
 <form action="{{ url_for_security('login') }}" method="POST" name="login_user_form">
     {{ login_user_form.hidden_tag() }}
+    {% set user_language = request.cookies.get('PGADMIN_LANGUAGE') or 'en' %}
     <fieldset>
         {{ render_field_with_errors(login_user_form.email, "text") }}
         {{ render_field_with_errors(login_user_form.password, "password") }}
         <input class="btn btn-lg btn-success btn-block" type="submit" value="{{ _('Login') }}">
+        <div class="pgadmin-control-group form-group pg-el-xs-12 user-language">
+            <label class="help-block pg-el-sm-3">{{ _("Continue with") }}</label>
+            <div class="pgadmin-controls pg-el-sm-9">
+                <select class="form-control" name="language" value="{{user_language}}">
+                    {% for key, lang in config.LANGUAGES.items() %}
+                    <option value="{{key}}" {% if user_language == key %}selected{% endif %}>{{lang}}</option>
+                    {% endfor %}
+                 </select>
+            </div>
+        </div>
     </fieldset>
 </form>
 <span class="help-block">{{ _('Forgotten your <a href="%(url)s">password</a>?', url=url_for('security.forgot_password')) }}</span>
diff --git a/web/pgadmin/utils/preferences.py b/web/pgadmin/utils/preferences.py
index e0da6c8..932351d 100644
--- a/web/pgadmin/utils/preferences.py
+++ b/web/pgadmin/utils/preferences.py
@@ -126,8 +126,9 @@ class _Preference(object):
                 current_app.logger.exeception(e)
                 return self.default
         if self._type == 'options':
-            if res.value in self.options:
-                return res.value
+            for opt in self.options:
+                if 'value' in opt and opt['value'] == res.value:
+                    return res.value
             return self.default
         if self._type == 'text':
             if res.value == '':
@@ -184,7 +185,12 @@ class _Preference(object):
                 current_app.logger.exeception(e)
                 return False, gettext("Invalid value for a datetime option.")
         elif self._type == 'options':
-            if value not in self.options:
+            has_value = False
+            for opt in self.options:
+                if 'value' in opt and opt['value'] == value:
+                    has_value = True
+
+            if not has_value:
                 return False, gettext("Invalid value for an options option.")
 
         pref = UserPrefTable.query.filter_by(
-- 
Sent via pgadmin-hackers mailing list (pgadmin-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgadmin-hackers

Reply via email to