codekingpro/portable-devtools
114k
1##########################################################################2#3# pgAdmin 4 - PostgreSQL Tools4#5# Copyright (C) 2013 - 2024, The pgAdmin Development Team6# This software is released under the PostgreSQL Licence7#8##########################################################################9 10"""11Implements the routes for creating Preferences/Options Dialog on the client12side and for getting/setting preferences.13"""14 15import config16import json17from flask import render_template, url_for, Response, request, session18from flask_babel import gettext19from pgadmin.user_login_check import pga_login_required20from pgadmin.utils import PgAdminModule21from pgadmin.utils.ajax import success_return, \22 make_response as ajax_response, internal_server_error23from pgadmin.utils.ajax import make_json_response24from pgadmin.utils.preferences import Preferences25from pgadmin.utils.constants import MIMETYPE_APP_JS26from pgadmin.browser.server_groups import ServerGroupModule as sgm27 28MODULE_NAME = 'preferences'29 30 31class PreferencesModule(PgAdminModule):32 """33 PreferenceModule represets the preferences of different modules to the34 user in UI.35 36 And, allows the user to modify (not add/remove) as per their requirement.37 """38 39 def get_own_menuitems(self):40 return {}41 42 def get_exposed_url_endpoints(self):43 """44 Returns:45 list: a list of url endpoints exposed to the client.46 """47 return [48 'preferences.index',49 'preferences.get_by_name',50 'preferences.get_all',51 'preferences.get_all_cli',52 'preferences.update_pref'53 ]54 55 56blueprint = PreferencesModule(MODULE_NAME, __name__)57 58 59@blueprint.route("/preferences.js")60@pga_login_required61def script():62 """render the required javascript"""63 return Response(64 response=render_template("preferences/preferences.js", _=gettext),65 status=200,66 mimetype=MIMETYPE_APP_JS67 )68 69 70@blueprint.route("/", methods=["GET"], endpoint='index')71@blueprint.route("/<module>/<preference>", endpoint='get_by_name')72@pga_login_required73def preferences(module=None, preference=None):74 """Fetch all/or requested preferences of pgAdmin IV."""75 76 if module is not None and preference is not None:77 try:78 m = Preferences.module(module, create=False)79 if m is None:80 return Response(status=404)81 82 p = m.preference(preference)83 if p is None:84 return Response(status=404)85 86 return ajax_response(87 response=p.to_json(),88 status=20089 )90 91 except Exception as e:92 return internal_server_error(errormsg=str(e))93 94 # Load Preferences95 pref = Preferences.preferences()96 res = []97 98 def label(p):99 return gettext(p['label'])100 101 _group_pref_by_categories(pref, res, label)102 103 return ajax_response(104 response=sorted(res, key=label),105 status=200106 )107 108 109def _group_pref_by_categories(pref, res, label):110 """111 Group preference by categories type.112 :param pref: preference data.113 :param res: response for request.114 :param label: get label.115 :return:116 """117 for pref_d in pref:118 if len(pref_d['categories']):119 _iterate_categories(pref_d, label, res)120 121 122def _iterate_categories(pref_d, label, res):123 """124 Iterate preference categories.125 :param pref_d: preference data126 :param label: get label.127 :param res: response.128 :return:129 """130 om = {131 "id": pref_d['id'],132 "label": gettext(pref_d['label']),133 "inode": True,134 "open": True,135 "children": [],136 "value": gettext(pref_d['label']),137 "name": pref_d['name']138 }139 140 for c in pref_d['categories']:141 for p in c['preferences']:142 if 'label' in p and p['label'] is not None:143 p['label'] = gettext(p['label'])144 if 'help_str' in p and p['help_str'] is not None:145 p['help_str'] = gettext(p['help_str'])146 oc = {147 "id": c['id'],148 "mid": pref_d['id'],149 "name": c['name'],150 "label": gettext(c['label']),151 "value": '{0}{1}'.format(c['id'], gettext(c['label'])),152 "inode": False,153 "open": False,154 "preferences": sorted(c['preferences'], key=label),155 "showCheckbox": False156 }157 158 (om['children']).append(oc)159 om['children'] = sorted(om['children'], key=label)160 161 res.append(om)162 163 164@blueprint.route("/get_all", methods=["GET"], endpoint='get_all')165@pga_login_required166def preferences_s():167 """Fetch all preferences for caching."""168 # Load Preferences169 pref = Preferences.preferences()170 res = []171 172 for m in pref:173 if len(m['categories']):174 for c in m['categories']:175 for p in c['preferences']:176 p['module'] = m['name']177 res.append(p)178 179 return ajax_response(180 response=res,181 status=200182 )183 184 185@blueprint.route("/get_all_cli", methods=["GET"], endpoint='get_all_cli')186def get_all_cli():187 """Fetch all preferences for caching."""188 # Load Preferences189 pref = Preferences.preferences()190 res = {}191 192 for m in pref:193 if len(m['categories']):194 for c in m['categories']:195 for p in c['preferences']:196 p['module'] = m['name']197 res["{0}:{1}:{2}".format(m['label'], p['label'], c['label']198 )] = "{0}:{1}:{2}".format(199 p['module'],c['name'],p['name'])200 201 return ajax_response(202 response=res,203 status=200204 )205 206 207def get_data():208 """209 Get preferences data.210 :return: Preferences list211 :rtype: list212 """213 pref_data = request.form if request.form else json.loads(214 request.data.decode())215 216 if not pref_data:217 raise ValueError("Please provide the valid preferences data to save.")218 219 return pref_data220 221 222@blueprint.route("/", methods=["PUT"], endpoint="update")223@pga_login_required224def save():225 """226 Save a specific preference.227 """228 pref_data = get_data()229 230 for data in pref_data:231 if data['name'] in ['vw_edt_tab_title_placeholder',232 'qt_tab_title_placeholder',233 'debugger_tab_title_placeholder'] \234 and data['value'].isspace():235 data['value'] = ''236 237 res, msg = Preferences.save(238 data['mid'], data['category_id'], data['id'], data['value'])239 sgm.get_nodes(sgm)240 241 if not res:242 return internal_server_error(errormsg=msg)243 244 response = success_return()245 246 # Set cookie & session for language settings.247 # This will execute every time as could not find the better way to know248 # that which preference is getting updated.249 250 misc_preference = Preferences.module('misc')251 user_languages = misc_preference.preference(252 'user_language'253 )254 255 language = 'en'256 if user_languages:257 language = user_languages.get() or language258 259 domain = dict()260 if config.COOKIE_DEFAULT_DOMAIN and \261 config.COOKIE_DEFAULT_DOMAIN != 'localhost':262 domain['domain'] = config.COOKIE_DEFAULT_DOMAIN263 264 setattr(session, 'PGADMIN_LANGUAGE', language)265 response.set_cookie("PGADMIN_LANGUAGE", value=language,266 path=config.SESSION_COOKIE_PATH,267 secure=config.SESSION_COOKIE_SECURE,268 httponly=config.SESSION_COOKIE_HTTPONLY,269 samesite=config.SESSION_COOKIE_SAMESITE,270 **domain)271 272 return response273 274 275def save_pref(data):276 """277 Save a specific preference.278 """279 280 if data['name'] in ['vw_edt_tab_title_placeholder',281 'qt_tab_title_placeholder',282 'debugger_tab_title_placeholder'] \283 and data['value'].isspace():284 data['value'] = ''285 286 if data['value'] in ['true','false']:287 data['value'] = True if data['value'] == 'true' else False288 289 res, _ = Preferences.save_cli(290 data['mid'], data['category_id'], data['id'], data['user_id'],291 data['value'])292 293 if not res:294 return False295 return True296 297 298@blueprint.route("/update", methods=["PUT"], endpoint="update_pref")299@pga_login_required300def update():301 """302 Update a specific preference.303 """304 pref_data = get_data()305 pref_data = json.loads(pref_data['pref_data'])306 307 for data in pref_data:308 if data['name'] in ['vw_edt_tab_title_placeholder',309 'qt_tab_title_placeholder',310 'debugger_tab_title_placeholder'] \311 and data['value'].isspace():312 data['value'] = ''313 314 pref_module = Preferences.module(data['module'])315 pref = pref_module.preference(data['name'])316 # set user preferences317 pref.set(data['value'])318 319 return make_json_response(320 data={'data': 'Success'},321 status=200322 )323 