| 1 | # -*- coding: utf-8 -*- |
|---|
| 2 | # |
|---|
| 3 | # Copyright (C) 2010-2014 Rob Guttman <guttman@alum.mit.edu> |
|---|
| 4 | # |
|---|
| 5 | # This software is licensed as described in the file COPYING, which |
|---|
| 6 | # you should have received as part of this distribution. |
|---|
| 7 | # |
|---|
| 8 | |
|---|
| 9 | from trac.ticket.api import TicketSystem |
|---|
| 10 | from trac.util import as_bool |
|---|
| 11 | |
|---|
| 12 | PREFIX = 'dynfields.' |
|---|
| 13 | PREF_DEFAULTS = { |
|---|
| 14 | '(pref)': '1', |
|---|
| 15 | '(pref:enable)': '1', |
|---|
| 16 | '(pref:enabled)': '1', |
|---|
| 17 | '(pref:disable)': '0', |
|---|
| 18 | '(pref:disabled)': '0', |
|---|
| 19 | } |
|---|
| 20 | |
|---|
| 21 | |
|---|
| 22 | class Options(dict): |
|---|
| 23 | """A thin dict wrapper of ticket-custom options to handle specifying, |
|---|
| 24 | loading and saving user preferences for any rule. User preferences |
|---|
| 25 | are specified by '(pref)' appended to a rule spec as follows: |
|---|
| 26 | |
|---|
| 27 | [ticket-custom] |
|---|
| 28 | version.show_when_type = enhancement (pref) |
|---|
| 29 | """ |
|---|
| 30 | |
|---|
| 31 | def __init__(self, env): |
|---|
| 32 | """Fills self with ticket-custom options with '(pref)' stripped |
|---|
| 33 | from values. Maintains which options/rules have been configured |
|---|
| 34 | for user preference.""" |
|---|
| 35 | super(Options, self).__init__() |
|---|
| 36 | self.env = env |
|---|
| 37 | self._pref_defaults = {} |
|---|
| 38 | for key, val in self.env.config['ticket-custom'].options(): |
|---|
| 39 | for pref, default in PREF_DEFAULTS.items(): |
|---|
| 40 | if val.endswith(pref): |
|---|
| 41 | val = val.replace(pref, '').rstrip() |
|---|
| 42 | self._pref_defaults[key] = default |
|---|
| 43 | break |
|---|
| 44 | self[key] = val |
|---|
| 45 | |
|---|
| 46 | # add built-in field types |
|---|
| 47 | for field in TicketSystem(self.env).get_ticket_fields(): |
|---|
| 48 | self[field['name']] = field['type'] |
|---|
| 49 | |
|---|
| 50 | def has_pref(self, key): |
|---|
| 51 | """Returns True if the given key is configured for user preference.""" |
|---|
| 52 | return key in self._pref_defaults |
|---|
| 53 | |
|---|
| 54 | def is_enabled(self, req, key): |
|---|
| 55 | """Returns True if there's no user preference configured for this |
|---|
| 56 | key or if there is and the user enabled the rule spec (the default).""" |
|---|
| 57 | if key not in self._pref_defaults: |
|---|
| 58 | return True |
|---|
| 59 | |
|---|
| 60 | # return the default pref value if not set |
|---|
| 61 | return req.session.get(PREFIX + key, self._pref_defaults[key]) == '1' |
|---|
| 62 | |
|---|
| 63 | def get_value_and_options(self, req, target, key): |
|---|
| 64 | """Returns the preference value for the given key if configured |
|---|
| 65 | for being set by user preference. If no user preference has been |
|---|
| 66 | set yet, the target field's default value is returned.""" |
|---|
| 67 | value = '' |
|---|
| 68 | options = [] |
|---|
| 69 | for field in TicketSystem(self.env).get_ticket_fields(): |
|---|
| 70 | if field['name'] == target: |
|---|
| 71 | value = field.get('value', value) |
|---|
| 72 | options = field.get('options', options) |
|---|
| 73 | break |
|---|
| 74 | if key in self._pref_defaults: |
|---|
| 75 | value = req.session.get(PREFIX + key + '.value', value) |
|---|
| 76 | return value, options |
|---|
| 77 | |
|---|
| 78 | def get_pref(self, req, target, key): |
|---|
| 79 | """Returns the data needed for preferences. The data returned |
|---|
| 80 | must be a dict with these keys: |
|---|
| 81 | |
|---|
| 82 | id (based on unique key) |
|---|
| 83 | label (of checkbox) |
|---|
| 84 | enabled ('1' or '0') |
|---|
| 85 | type ('none' or 'select', TODO: support 'text') |
|---|
| 86 | options (list of options if type is 'select') |
|---|
| 87 | value (saved preference or default value) |
|---|
| 88 | """ |
|---|
| 89 | value, options = self.get_value_and_options(req, target, key) |
|---|
| 90 | return { |
|---|
| 91 | 'id': PREFIX + key, |
|---|
| 92 | 'label': '%s = %s' % (key, self[key]), |
|---|
| 93 | 'enabled': req.session.get(PREFIX + key, |
|---|
| 94 | self._pref_defaults[key]), |
|---|
| 95 | 'type': 'none', |
|---|
| 96 | 'options': options, |
|---|
| 97 | 'value': value, |
|---|
| 98 | } |
|---|
| 99 | |
|---|
| 100 | def set_prefs(self, req): |
|---|
| 101 | """Saves the user's preferences.""" |
|---|
| 102 | # save checkbox settings |
|---|
| 103 | for key in self._pref_defaults: |
|---|
| 104 | req.session[PREFIX + key] = req.args.get(PREFIX + key, '0') |
|---|
| 105 | |
|---|
| 106 | # now save values |
|---|
| 107 | for arg, value in req.args.items(): |
|---|
| 108 | if not arg.startswith(PREFIX) or not arg.endswith('.value'): |
|---|
| 109 | continue |
|---|
| 110 | req.session[arg] = value |
|---|
| 111 | |
|---|
| 112 | def getbool(self, key, default=False): |
|---|
| 113 | return as_bool(self.get(key, default)) |
|---|
| 114 | |
|---|