Package trac :: Package prefs :: Module web_ui

Source Code for Module trac.prefs.web_ui

  1  # -*- coding: utf-8 -*- 
  2  # 
  3  # Copyright (C) 2004-2020 Edgewall Software 
  4  # Copyright (C) 2004-2005 Daniel Lundin <[email protected]> 
  5  # All rights reserved. 
  6  # 
  7  # This software is licensed as described in the file COPYING, which 
  8  # you should have received as part of this distribution. The terms 
  9  # are also available at https://trac.edgewall.org/wiki/TracLicense. 
 10  # 
 11  # This software consists of voluntary contributions made by many 
 12  # individuals. For the exact contribution history, see the revision 
 13  # history and logs, available at https://trac.edgewall.org/log/. 
 14  # 
 15  # Author: Daniel Lundin <[email protected]> 
 16   
 17  import pkg_resources 
 18  import re 
 19   
 20  from genshi.builder import tag 
 21   
 22  from trac.core import * 
 23  from trac.prefs.api import IPreferencePanelProvider 
 24  from trac.util.datefmt import all_timezones, get_timezone, localtz 
 25  from trac.util.translation import _, Locale, deactivate,\ 
 26                                    get_available_locales, make_activable 
 27  from trac.web.api import HTTPNotFound, IRequestHandler 
 28  from trac.web.chrome import INavigationContributor, ITemplateProvider, \ 
 29                              add_notice, add_stylesheet 
 30   
 31   
32 -class PreferencesModule(Component):
33 """Displays the preference panels and dispatch control to the 34 individual panels""" 35 36 panel_providers = ExtensionPoint(IPreferencePanelProvider) 37 38 implements(INavigationContributor, IPreferencePanelProvider, 39 IRequestHandler, ITemplateProvider) 40 41 _form_fields = [ 42 'newsid', 'name', 'email', 'tz', 'lc_time', 'dateinfo', 43 'language', 'accesskeys', 44 'ui.use_symbols', 'ui.hide_help', 45 ] 46 47 # INavigationContributor methods 48
49 - def get_active_navigation_item(self, req):
50 return 'prefs'
51
52 - def get_navigation_items(self, req):
53 yield 'metanav', 'prefs', tag.a(_("Preferences"), 54 href=req.href.prefs())
55 56 # IRequestHandler methods 57
58 - def match_request(self, req):
59 match = re.match('/prefs(?:/([^/]+))?$', req.path_info) 60 if match: 61 req.args['panel_id'] = match.group(1) 62 return True
63
64 - def process_request(self, req):
65 xhr = req.get_header('X-Requested-With') == 'XMLHttpRequest' 66 if xhr and req.method == 'POST' and 'save_prefs' in req.args: 67 self._do_save_xhr(req) 68 69 panel_id = req.args.get('panel_id') 70 71 panels = [] 72 chosen_provider = None 73 74 for provider in self.panel_providers: 75 for name, label in provider.get_preference_panels(req) or []: 76 if name == panel_id or None: 77 chosen_provider = provider 78 panels.append((name, label)) 79 if not chosen_provider: 80 raise HTTPNotFound(_("Unknown preference panel")) 81 82 template, data = chosen_provider.render_preference_panel(req, panel_id) 83 data.update({'active_panel': panel_id, 'panels': panels}) 84 85 add_stylesheet(req, 'common/css/prefs.css') 86 return template, data, None
87 88 # IPreferencePanelProvider methods 89
90 - def get_preference_panels(self, req):
91 yield (None, _("General")) 92 yield ('datetime', _("Date & Time")) 93 yield ('keybindings', _("Keyboard Shortcuts")) 94 yield ('userinterface', _("User Interface")) 95 if Locale or 'TRAC_ADMIN' in req.perm: 96 yield ('language', _("Language")) 97 if not req.authname or req.authname == 'anonymous': 98 yield ('advanced', _("Advanced"))
99
100 - def render_preference_panel(self, req, panel):
101 if req.method == 'POST': 102 if 'restore' in req.args: 103 self._do_load(req) 104 else: 105 self._do_save(req) 106 req.redirect(req.href.prefs(panel or None)) 107 108 data = { 109 'settings': {'session': req.session, 110 'session_id': req.session.sid}, 111 'timezones': all_timezones, 112 'timezone': get_timezone, 113 'localtz': localtz, 114 'has_babel': False 115 } 116 117 if Locale: 118 locale_ids = get_available_locales() 119 locales = [Locale.parse(locale) for locale in locale_ids] 120 # use locale identifiers from get_available_locales() instead 121 # of str(locale) to prevent storing expanded locale identifier 122 # to session, e.g. zh_Hans_CN and zh_Hant_TW, since Babel 1.0. 123 # see #11258. 124 languages = sorted((id, locale.display_name) 125 for id, locale in zip(locale_ids, locales)) 126 data['locales'] = locales 127 data['languages'] = languages 128 data['has_babel'] = True 129 130 return 'prefs_%s.html' % (panel or 'general'), data
131 132 # ITemplateProvider methods 133
134 - def get_htdocs_dirs(self):
135 return []
136
137 - def get_templates_dirs(self):
138 return [pkg_resources.resource_filename('trac.prefs', 'templates')]
139 140 # Internal methods 141
142 - def _do_save_xhr(self, req):
143 for key in req.args: 144 if not key in ['save_prefs', 'panel_id', '__FORM_TOKEN']: 145 req.session[key] = req.args[key] 146 req.session.save() 147 req.send_no_content()
148
149 - def _do_save(self, req):
150 language = req.session.get('language') 151 for field in self._form_fields: 152 val = req.args.get(field, '').strip() 153 if val: 154 if field == 'tz' and 'tz' in req.session and \ 155 val not in all_timezones: 156 del req.session['tz'] 157 elif field == 'newsid': 158 req.session.change_sid(val) 159 elif field == 'accesskeys': 160 req.session[field] = '1' 161 else: 162 req.session[field] = val 163 elif field in req.session and (field in req.args or 164 field + '_cb' in req.args): 165 del req.session[field] 166 if Locale and req.session.get('language') != language: 167 # reactivate translations with new language setting when changed 168 del req.locale # for re-negotiating locale 169 deactivate() 170 make_activable(lambda: req.locale, self.env.path) 171 add_notice(req, _("Your preferences have been saved."))
172
173 - def _do_load(self, req):
174 if req.authname == 'anonymous': 175 oldsid = req.args.get('loadsid') 176 if oldsid: 177 req.session.get_session(oldsid) 178 add_notice(req, _("The session has been loaded."))
179