mirror of
				https://github.com/janeczku/calibre-web
				synced 2025-10-31 15:23:02 +00:00 
			
		
		
		
	Working Locale and default language selection in user table edit
This commit is contained in:
		
							
								
								
									
										119
									
								
								cps/admin.py
									
									
									
									
									
								
							
							
						
						
									
										119
									
								
								cps/admin.py
									
									
									
									
									
								
							| @@ -31,6 +31,7 @@ from datetime import datetime, timedelta | |||||||
|  |  | ||||||
| from babel import Locale as LC | from babel import Locale as LC | ||||||
| from babel.dates import format_datetime | from babel.dates import format_datetime | ||||||
|  | from babel.core import UnknownLocaleError | ||||||
| from flask import Blueprint, flash, redirect, url_for, abort, request, make_response, send_from_directory, g | from flask import Blueprint, flash, redirect, url_for, abort, request, make_response, send_from_directory, g | ||||||
| from flask_login import login_required, current_user, logout_user, confirm_login | from flask_login import login_required, current_user, logout_user, confirm_login | ||||||
| from flask_babel import gettext as _ | from flask_babel import gettext as _ | ||||||
| @@ -39,7 +40,7 @@ from sqlalchemy.orm.attributes import flag_modified | |||||||
| from sqlalchemy.exc import IntegrityError, OperationalError, InvalidRequestError | from sqlalchemy.exc import IntegrityError, OperationalError, InvalidRequestError | ||||||
| from sqlalchemy.sql.expression import func, or_ | from sqlalchemy.sql.expression import func, or_ | ||||||
|  |  | ||||||
| from . import constants, logger, helper, services | from . import constants, logger, helper, services, isoLanguages | ||||||
| from .cli import filepicker | from .cli import filepicker | ||||||
| from . import db, calibre_db, ub, web_server, get_locale, config, updater_thread, babel, gdriveutils | from . import db, calibre_db, ub, web_server, get_locale, config, updater_thread, babel, gdriveutils | ||||||
| from .helper import check_valid_domain, send_test_mail, reset_password, generate_password_hash | from .helper import check_valid_domain, send_test_mail, reset_password, generate_password_hash | ||||||
| @@ -253,7 +254,21 @@ def list_users(): | |||||||
|         users = all_user.offset(off).limit(limit).all() |         users = all_user.offset(off).limit(limit).all() | ||||||
|         filtered_count = total_count |         filtered_count = total_count | ||||||
|  |  | ||||||
|  |     for user in users: | ||||||
|  |         # set readable locale | ||||||
|  |         #try: | ||||||
|  |         #    user.local = LC.parse(user.locale).get_language_name(get_locale()) | ||||||
|  |         #except UnknownLocaleError: | ||||||
|  |         #    # This should not happen | ||||||
|  |         #    user.local = _(isoLanguages.get(part1=user.locale).name) | ||||||
|  |         # Set default language | ||||||
|  |         if user.default_language == "all": | ||||||
|  |             user.default = _("all") | ||||||
|  |         else: | ||||||
|  |             user.default = LC.parse(user.default_language).get_language_name(get_locale()) | ||||||
|  |  | ||||||
|     table_entries = {'totalNotFiltered': total_count, 'total': filtered_count, "rows": users} |     table_entries = {'totalNotFiltered': total_count, 'total': filtered_count, "rows": users} | ||||||
|  |  | ||||||
|     js_list = json.dumps(table_entries, cls=db.AlchemyEncoder) |     js_list = json.dumps(table_entries, cls=db.AlchemyEncoder) | ||||||
|  |  | ||||||
|     response = make_response(js_list) |     response = make_response(js_list) | ||||||
| @@ -266,10 +281,32 @@ def list_users(): | |||||||
| def delete_user(): | def delete_user(): | ||||||
|     # ToDo User delete check also not last one |     # ToDo User delete check also not last one | ||||||
|     pass |     pass | ||||||
|     return |     return "" | ||||||
|  |  | ||||||
|  | @admi.route("/ajax/getlocale") | ||||||
|  | @login_required | ||||||
|  | @admin_required | ||||||
|  | def table_get_locale(): | ||||||
|  |     locale = babel.list_translations() + [LC('en')] | ||||||
|  |     ret = list() | ||||||
|  |     current_locale = get_locale() | ||||||
|  |     for loc in locale: | ||||||
|  |         ret.append({'value':str(loc),'text':loc.get_language_name(current_locale)}) | ||||||
|  |     return json.dumps(ret) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @admi.route("/ajax/getdefaultlanguage") | ||||||
|  | @login_required | ||||||
|  | @admin_required | ||||||
|  | def table_get_default_lang(): | ||||||
|  |     languages = calibre_db.speaking_language() | ||||||
|  |     ret = list() | ||||||
|  |     ret.append({'value':'all','text':_('Show All')}) | ||||||
|  |     for lang in languages: | ||||||
|  |         ret.append({'value':lang.lang_code,'text': lang.name}) | ||||||
|  |     return json.dumps(ret) | ||||||
|  |  | ||||||
|  |  | ||||||
| # @admi.route("/ajax/editlistusers/<param>", defaults={"value": 0}, methods=['POST']) |  | ||||||
| @admi.route("/ajax/editlistusers/<param>", methods=['POST']) | @admi.route("/ajax/editlistusers/<param>", methods=['POST']) | ||||||
| @login_required | @login_required | ||||||
| @admin_required | @admin_required | ||||||
| @@ -280,36 +317,56 @@ def edit_list_user(param): | |||||||
|         all_user = all_user.filter(ub.User.role.op('&')(constants.ROLE_ANONYMOUS) != constants.ROLE_ANONYMOUS) |         all_user = all_user.filter(ub.User.role.op('&')(constants.ROLE_ANONYMOUS) != constants.ROLE_ANONYMOUS) | ||||||
|     # only one user is posted |     # only one user is posted | ||||||
|     if "pk" in vals: |     if "pk" in vals: | ||||||
|         user = all_user.filter(ub.User.id == vals['pk']).one_or_none() |         users = [all_user.filter(ub.User.id == vals['pk'][0]).one_or_none()] | ||||||
|     else: |     else: | ||||||
|         # ToDo |         if "pk[]" in vals: | ||||||
|         user = all_user.filter(ub.User.id == vals['pk[]']).all() |             users = all_user.filter(ub.User.id.in_(vals['pk[]'])).all() | ||||||
|     if param =='nickname': |  | ||||||
|         if not ub.session.query(ub.User).filter(ub.User.nickname == vals['value']).scalar(): |  | ||||||
|             user.nickname = vals['value'] |  | ||||||
|         else: |         else: | ||||||
|             log.error(u"This username is already taken") |             return "" | ||||||
|             return _(u"This username is already taken"), 400 |     if 'field_index' in vals: | ||||||
|     elif param =='email': |         vals['field_index'] = vals['field_index'][0] | ||||||
|         existing_email = ub.session.query(ub.User).filter(ub.User.email == vals['value'].lower()).first() |     if 'value' in vals: | ||||||
|         if not existing_email: |         vals['value'] = vals['value'][0] | ||||||
|             user.email = vals['value'] |     else: | ||||||
|         else: |         return "" | ||||||
|             log.error(u"Found an existing account for this e-mail address.") |     for user in users: | ||||||
|             return _(u"Found an existing account for this e-mail address."), 400 |         if param =='nickname': | ||||||
|     elif param =='kindle_mail': |             if not ub.session.query(ub.User).filter(ub.User.nickname == vals['value']).scalar(): | ||||||
|         user.kindle_mail = vals['value'] |                 user.nickname = vals['value'] | ||||||
|     elif param == 'role': |             else: | ||||||
|         if vals['value'] == 'true': |                 log.error(u"This username is already taken") | ||||||
|             user.role |= int(vals['field_index']) |                 return _(u"This username is already taken"), 400 | ||||||
|         else: |         elif param =='email': | ||||||
|             user.role &= ~int(vals['field_index']) |             existing_email = ub.session.query(ub.User).filter(ub.User.email == vals['value'].lower()).first() | ||||||
|     elif param == 'sidebar_view': |             if not existing_email: | ||||||
|         if vals['value'] == 'true': |                 user.email = vals['value'] | ||||||
|             user.sidebar_view |= int(vals['field_index']) |             else: | ||||||
|         else: |                 log.error(u"Found an existing account for this e-mail address.") | ||||||
|             user.sidebar_view &= ~int(vals['field_index']) |                 return _(u"Found an existing account for this e-mail address."), 400 | ||||||
|  |         elif param =='kindle_mail': | ||||||
|  |             user.kindle_mail = vals['value'] | ||||||
|  |         elif param == 'role': | ||||||
|  |             if vals['value'] == 'true': | ||||||
|  |                 user.role |= int(vals['field_index']) | ||||||
|  |             else: | ||||||
|  |                 user.role &= ~int(vals['field_index']) | ||||||
|  |         elif param == 'sidebar_view': | ||||||
|  |             if vals['value'] == 'true': | ||||||
|  |                 user.sidebar_view |= int(vals['field_index']) | ||||||
|  |             else: | ||||||
|  |                 user.sidebar_view &= ~int(vals['field_index']) | ||||||
|  |         elif param == 'denied_tags': | ||||||
|  |                 user.denied_tags = vals['value'] | ||||||
|  |         elif param == 'allowed_tags': | ||||||
|  |                 user.allowed_tags = vals['value'] | ||||||
|  |         elif param == 'allowed_column_value': | ||||||
|  |             user.allowed_column_value = vals['value'] | ||||||
|  |         elif param == 'denied_column_value': | ||||||
|  |             user.denied_column_value = vals['value'] | ||||||
|  |         elif param == 'locale': | ||||||
|  |             user.locale = vals['value'] | ||||||
|  |         elif param == 'default_language': | ||||||
|  |             user.default_language = vals['value'] | ||||||
|     ub.session_commit() |     ub.session_commit() | ||||||
|     return "" |     return "" | ||||||
|  |  | ||||||
|   | |||||||
| @@ -67,6 +67,7 @@ def get_language_codes(locale, language_names, remainder=None): | |||||||
|         remainder.extend(language_names) |         remainder.extend(language_names) | ||||||
|     return languages |     return languages | ||||||
|  |  | ||||||
|  |  | ||||||
| def get_valid_language_codes(locale, language_names, remainder=None): | def get_valid_language_codes(locale, language_names, remainder=None): | ||||||
|     languages = list() |     languages = list() | ||||||
|     if "" in language_names: |     if "" in language_names: | ||||||
|   | |||||||
| @@ -391,6 +391,10 @@ $(function() { | |||||||
|             $('.columns [data-field]').each(function(){ |             $('.columns [data-field]').each(function(){ | ||||||
|                 var elText = $(this).next().text(); |                 var elText = $(this).next().text(); | ||||||
|                 $(this).next().empty(); |                 $(this).next().empty(); | ||||||
|  |                 var index = elText.lastIndexOf('\n', elText.length - 2); | ||||||
|  |                 if ( index > -1) { | ||||||
|  |                     elText = elText.substr(index); | ||||||
|  |                 } | ||||||
|                 $(this).next().text(elText); |                 $(this).next().text(elText); | ||||||
|             }); |             }); | ||||||
|         }, |         }, | ||||||
| @@ -567,20 +571,22 @@ function checkboxChange(checkbox, userId, field, field_index) { | |||||||
|     }); |     }); | ||||||
| } | } | ||||||
|  |  | ||||||
| function checkboxHeader(checkbox, field, field_index) { | function checkboxHeader(CheckboxState, field, field_index) { | ||||||
|     var result = $('#user-table').bootstrapTable('getSelections').map(a => a.id); |     var result = $('#user-table').bootstrapTable('getSelections').map(a => a.id); | ||||||
|     $.ajax({ |     $.ajax({ | ||||||
|         method:"post", |         method:"post", | ||||||
|         url: window.location.pathname + "/../../ajax/editlistusers/" + field, |         url: window.location.pathname + "/../../ajax/editlistusers/" + field, | ||||||
|         data:  {"pk":result, "field_index":field_index, "value": checkbox.checked} |         data:  {"pk":result, "field_index":field_index, "value": CheckboxState}, | ||||||
|     }); |         success:function() { | ||||||
|     $.ajax({ |             $.ajax({ | ||||||
|         method:"get", |                 method:"get", | ||||||
|         url: window.location.pathname + "/../../ajax/listusers", |                 url: window.location.pathname + "/../../ajax/listusers", | ||||||
|         async: true, |                 async: true, | ||||||
|         timeout: 900, |                 timeout: 900, | ||||||
|         success:function(data) { |                 success:function(data) { | ||||||
|             $("#user-table").bootstrapTable("load", data); |                     $("#user-table").bootstrapTable("load", data); | ||||||
|  |                 } | ||||||
|  |             }); | ||||||
|         } |         } | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
| @@ -600,6 +606,8 @@ function user_handle (userId) { | |||||||
|             $("#user-table").bootstrapTable("load", data); |             $("#user-table").bootstrapTable("load", data); | ||||||
|         } |         } | ||||||
|     }); |     }); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function test(){ | ||||||
|  |     console.log("hello"); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -19,18 +19,33 @@ | |||||||
|     data-formatter="checkboxFormatter"> |     data-formatter="checkboxFormatter"> | ||||||
|     <div class="form-check"> |     <div class="form-check"> | ||||||
|       <label> |       <label> | ||||||
|         <input type="radio" class="check_head" name="options_{{array_field}}" onchange="checkboxHeader(this, '{{parameter}}', {{value.get(array_field)}})" disabled>{{_('Deny')}} |         <input type="radio" class="check_head" name="options_{{array_field}}" onchange="checkboxHeader('false', '{{parameter}}', {{value.get(array_field)}})" disabled>{{_('Deny')}} | ||||||
|       </label> |       </label> | ||||||
|     </div> |     </div> | ||||||
|     <div class="form-check"> |     <div class="form-check"> | ||||||
|       <label> |       <label> | ||||||
|         <input type="radio" class="check_head" name="options_{{array_field}}" onchange="checkboxHeader(this, '{{parameter}}', {{value.get(array_field)}})" disabled>{{_('Allow')}} |         <input type="radio" class="check_head" name="options_{{array_field}}" onchange="checkboxHeader('false', '{{parameter}}', {{value.get(array_field)}})" disabled>{{_('Allow')}} | ||||||
|       </label> |       </label> | ||||||
|     </div> |     </div> | ||||||
|     {{show_text}} |     {{show_text}} | ||||||
| </th> | </th> | ||||||
| {%- endmacro %} | {%- endmacro %} | ||||||
|  |  | ||||||
|  | {% macro user_select_row(parameter, url, show_text, validate) -%} | ||||||
|  | <th data-field="{{ parameter }}" id="{{ parameter }}" data-sortable="true" | ||||||
|  |     data-name="{{ parameter }}" | ||||||
|  |     data-visible="{{visiblility.get(parameter)}}" | ||||||
|  |     data-editable-type="select" | ||||||
|  |     data-edit="true" | ||||||
|  |     data-editable-url="{{ url_for('admin.edit_list_user', param=parameter)}}" | ||||||
|  |     data-editable-source={{url}} | ||||||
|  |     {% if validate %}data-edit-validate="{{ _('This Field is Required') }}" {% endif %}> | ||||||
|  |     {{ show_text }} | ||||||
|  | </th> | ||||||
|  | <!--data-editable-source="[{'value': '1', 'text':'bootstrap-table'},{'value': '2', 'text':'bootstrap2-table'}]"--> | ||||||
|  | {%- endmacro %} | ||||||
|  |  | ||||||
|  |  | ||||||
| {% block header %} | {% block header %} | ||||||
| <link href="{{ url_for('static', filename='css/libs/bootstrap-table.min.css') }}" rel="stylesheet"> | <link href="{{ url_for('static', filename='css/libs/bootstrap-table.min.css') }}" rel="stylesheet"> | ||||||
| <link href="{{ url_for('static', filename='css/libs/bootstrap-editable.css') }}" rel="stylesheet"> | <link href="{{ url_for('static', filename='css/libs/bootstrap-editable.css') }}" rel="stylesheet"> | ||||||
| @@ -51,7 +66,13 @@ | |||||||
|             <th data-name="id" data-field="id" id="id" data-visible="false" data-switchable="false"></th> |             <th data-name="id" data-field="id" id="id" data-visible="false" data-switchable="false"></th> | ||||||
|             {{ user_table_row('nickname', _('Enter Username'), _('Username'), true) }} |             {{ user_table_row('nickname', _('Enter Username'), _('Username'), true) }} | ||||||
|             {{ user_table_row('email', _('Enter E-mail Address'), _('E-mail Address'), true) }} |             {{ user_table_row('email', _('Enter E-mail Address'), _('E-mail Address'), true) }} | ||||||
|  |             {{ user_select_row('locale', url_for('admin.table_get_locale'), _('Locale'), true) }} | ||||||
|  |             {{ user_select_row('default_language', url_for('admin.table_get_default_lang'), _('Visible Book Languages'), true) }} | ||||||
|             {{ user_table_row('kindle_mail', _('Enter Kindle E-mail Address'), _('Kindle E-mail'), true) }} |             {{ user_table_row('kindle_mail', _('Enter Kindle E-mail Address'), _('Kindle E-mail'), true) }} | ||||||
|  |             {{ user_table_row('denied_tags', _("Enter Users's Locale"), _("Denied Tags"), true) }} | ||||||
|  |             {{ user_table_row('allowed_tags', _("Edit Allowed Tags"), _("Allowed Tags"), true) }} | ||||||
|  |             {{ user_table_row('allowed_column_value', _("Edit Allowed Column Values"), _("Allowed Column Values"), true) }} | ||||||
|  |             {{ user_table_row('denied_column_value', _("Edit Denied Column Values"), _("Denied Columns Values"), true) }} | ||||||
|             {{ user_checkbox_row("role", "admin_role", _('Admin'), visiblility, all_roles)}} |             {{ user_checkbox_row("role", "admin_role", _('Admin'), visiblility, all_roles)}} | ||||||
|             {{ user_checkbox_row("role", "download_role",_('Upload'), visiblility, all_roles)}} |             {{ user_checkbox_row("role", "download_role",_('Upload'), visiblility, all_roles)}} | ||||||
|             {{ user_checkbox_row("role", "upload_role", _('Download'), visiblility, all_roles)}} |             {{ user_checkbox_row("role", "upload_role", _('Download'), visiblility, all_roles)}} | ||||||
| @@ -60,10 +81,6 @@ | |||||||
|             {{ user_checkbox_row("role", "edit_shelf_role", _('Edit Public Shelfs'), visiblility, all_roles)}} |             {{ user_checkbox_row("role", "edit_shelf_role", _('Edit Public Shelfs'), visiblility, all_roles)}} | ||||||
|             {{ user_checkbox_row("role", "delete_role", _('Delete'), visiblility, all_roles)}} |             {{ user_checkbox_row("role", "delete_role", _('Delete'), visiblility, all_roles)}} | ||||||
|             {{ user_checkbox_row("role", "viewer_role", _('View'), visiblility, all_roles)}} |             {{ user_checkbox_row("role", "viewer_role", _('View'), visiblility, all_roles)}} | ||||||
|             {{ user_table_row('denied_tags', _("Enter Users's Locale"), _("Denied Tags"), true) }} |  | ||||||
|             {{ user_table_row('allowed_tags', _("Edit Allowed Tags"), _("Allowed Tags"), true) }} |  | ||||||
|             {{ user_table_row('allowed_column_value', _("Edit Allowed Column Values"), _("Allowed Column Values"), true) }} |  | ||||||
|             {{ user_table_row('denied_column_value', _("Enter Users's Locale"), _("Denied Columns Values"), true) }} |  | ||||||
|             {{ user_checkbox_row("sidebar_view", "detail_random", _('Show Random Books in Detail View'), visiblility, sidebar_settings)}} |             {{ user_checkbox_row("sidebar_view", "detail_random", _('Show Random Books in Detail View'), visiblility, sidebar_settings)}} | ||||||
|             {{ user_checkbox_row("sidebar_view", "sidebar_language", _('Show language selection'), visiblility, sidebar_settings)}} |             {{ user_checkbox_row("sidebar_view", "sidebar_language", _('Show language selection'), visiblility, sidebar_settings)}} | ||||||
|             {{ user_checkbox_row("sidebar_view", "sidebar_series", _('Show series selection'), visiblility, sidebar_settings)}} |             {{ user_checkbox_row("sidebar_view", "sidebar_series", _('Show series selection'), visiblility, sidebar_settings)}} | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Ozzie Isaacs
					Ozzie Isaacs