Example #1
0
    def _get_script_data(self, req, data, dateinfo):
        plural_forms = self._get_plural_forms()
        script_data = {
            'units': self._get_units(plural_forms[0]),
            'pluralexpr': plural_forms[1],
            'starttime': format_datetime(format='iso8601', tzinfo=req.tz),
        }
        if data.get('pretty_dateinfo'): # 1.0+
            in_future = datetime.now(req.tz) + timedelta(days=1)
            in_future = data['pretty_dateinfo'](in_future, format='absolute',
                                                dateonly=True).tag != 'a'
            absolute = {'past': dgettext('messages',
                                         "See timeline %(relativetime)s ago") \
                                .replace('%(relativetime)s', '%(relative)s')}
            if in_future:
                # 1.1+
                relative = {'past': dgettext('messages', "%(relative)s ago")}
                absolute['future'] = relative['future'] = \
                                        dgettext('messages', "in %(relative)s")
            else:
                absolute['future'] = absolute['past']
                relative = dgettext('messages', "%(relativetime)s ago") \
                           .replace('%(relativetime)s', '%(relative)s')
                relative = {'future': relative, 'past': relative}

            script_data.update({'format': dateinfo, 'relative': relative,
                                'absolute': absolute})
        return script_data
Example #2
0
    def expand_macro(self, formatter, name, args):
        from trac.config import ConfigSection, Option
        section_filter = key_filter = ''
        args, kw = parse_args(args)
        if args:
            section_filter = args.pop(0).strip()
        if args:
            key_filter = args.pop(0).strip()

        registry = ConfigSection.get_registry(self.compmgr)
        sections = dict(
            (name, dgettext(section.doc_domain, to_unicode(section.__doc__)))
            for name, section in registry.iteritems()
            if name.startswith(section_filter))

        registry = Option.get_registry(self.compmgr)
        options = {}
        for (section, key), option in registry.iteritems():
            if section.startswith(section_filter):
                options.setdefault(section, {})[key] = option
                sections.setdefault(section, '')

        def default_cell(option):
            default = option.default
            if default is True:
                default = 'true'
            elif default is False:
                default = 'false'
            elif default == 0:
                default = '0.0' if isinstance(default, float) else '0'
            elif default:
                default = ', '.join(to_unicode(val) for val in default) \
                          if isinstance(default, (list, tuple)) \
                          else to_unicode(default)
            else:
                return tag.td(_("(no default)"), class_='nodefault')
            return tag.td(tag.code(default), class_='default')

        return tag.div(class_='tracini')(
            (tag.h3(tag.code('[%s]' % section), id='%s-section' % section),
             format_to_html(self.env, formatter.context, section_doc),
             tag.table(class_='wiki')(tag.tbody(
                 tag.tr(
                     tag.td(tag.tt(option.name)),
                     tag.td(
                         format_to_oneliner(
                             self.env, formatter.context,
                             dgettext(option.doc_domain,
                                      to_unicode(option.__doc__)))),
                     default_cell(option))
                 for option in sorted(options.get(section, {}).itervalues(),
                                      key=lambda o: o.name)
                 if option.name.startswith(key_filter))))
            for section, section_doc in sorted(sections.iteritems()))
Example #3
0
    def expand_macro(self, formatter, name, args):
        from trac.config import ConfigSection, Option
        section_filter = key_filter = ''
        args, kw = parse_args(args)
        if args:
            section_filter = args.pop(0).strip()
        if args:
            key_filter = args.pop(0).strip()

        registry = ConfigSection.get_registry(self.compmgr)
        sections = dict((name, dgettext(section.doc_domain,
                                        to_unicode(section.__doc__)))
                        for name, section in registry.iteritems()
                        if name.startswith(section_filter))

        registry = Option.get_registry(self.compmgr)
        options = {}
        for (section, key), option in registry.iteritems():
            if section.startswith(section_filter):
                options.setdefault(section, {})[key] = option
                sections.setdefault(section, '')

        def default_cell(option):
            default = option.default
            if default is True:
                default = 'true'
            elif default is False:
                default = 'false'
            elif default == 0:
                default = '0.0' if isinstance(default, float) else '0'
            elif default:
                default = ', '.join(to_unicode(val) for val in default) \
                          if isinstance(default, (list, tuple)) \
                          else to_unicode(default)
            else:
                return tag.td(_("(no default)"), class_='nodefault')
            return tag.td(tag.code(default), class_='default')

        return tag.div(class_='tracini')(
            (tag.h3(tag.code('[%s]' % section), id='%s-section' % section),
             format_to_html(self.env, formatter.context, section_doc),
             tag.table(class_='wiki')(tag.tbody(
                 tag.tr(tag.td(tag.tt(option.name)),
                        tag.td(format_to_oneliner(
                            self.env, formatter.context,
                            dgettext(option.doc_domain,
                                     to_unicode(option.__doc__)))),
                        default_cell(option))
                 for option in sorted(options.get(section, {}).itervalues(),
                                      key=lambda o: o.name)
                 if option.name.startswith(key_filter))))
            for section, section_doc in sorted(sections.iteritems()))
 def __getattribute__(self, name):
     if name == '__class__':
         return Option
     value = Option.__getattribute__(self, name)
     if name == '__doc__':
         value = dgettext(doc_domain, value)
     return value
Example #5
0
    def _gather_option_data(self, req, section_name, option_name,
                            section_default_values):
        option = None
        if (section_name, option_name) in Option.registry:
            # Allow wiki formatting in descriptions
            option = Option.registry[(section_name, option_name)]
            doc = option.__doc__
            if doc:
                doc = dgettext(option.doc_domain, doc)
            else:
                doc = None
            option_desc = doc
            option_type = option.__class__.__name__.lower()[:-6] or N_('text')
        else:
            option_desc = None
            option_type = N_('text')

        # See "IniEditorBasicSecurityManager" for why we use a pipe char here.
        if ('%s|%s' %
            (section_name, option_name)) in self.password_options_set:
            option_type = N_('password')

        if section_default_values:
            default_value = (self._convert_value(
                section_default_values.get(option_name), option) or '')
        else:
            default_value = ''

        return {
            'default_value': default_value,
            'desc': option_desc,
            'type': option_type,
            'option_info': option,
            'access': self._check_option_access(section_name, option_name)
        }
 def __getattribute__(self, name):
     if name == '__class__':
         return Base
     val = Base.__getattribute__(self, name)
     if name == '__doc__':
         val = dgettext('tracworkflowadmin', val)
     return val
Example #7
0
 def get_macro_descr():
     for macro_provider in formatter.wiki.macro_providers:
         names = list(macro_provider.get_macros() or [])
         if name_filter and not any(name.startswith(name_filter)
                                    for name in names):
             continue
         try:
             name_descriptions = [
                 (name, macro_provider.get_macro_description(name))
                 for name in names]
         except Exception as e:
             yield system_message(
                 _("Error: Can't get description for macro %(name)s",
                   name=names[0]), e), names
         else:
             for descr, pairs in groupby(name_descriptions,
                                         key=lambda p: p[1]):
                 if descr:
                     if isinstance(descr, (tuple, list)):
                         descr = dgettext(descr[0],
                                          to_unicode(descr[1])) \
                                 if descr[1] else ''
                     else:
                         descr = to_unicode(descr) or ''
                     if content == '*':
                         descr = format_to_oneliner(
                             self.env, formatter.context, descr,
                             shorten=True)
                     else:
                         descr = format_to_html(
                             self.env, formatter.context, descr)
                 yield descr, [name for name, descr in pairs]
Example #8
0
 def get_macro_descr():
     for macro_provider in formatter.wiki.macro_providers:
         names = list(macro_provider.get_macros() or [])
         if name_filter and not any(name.startswith(name_filter)
                                    for name in names):
             continue
         try:
             name_descriptions = [
                 (name, macro_provider.get_macro_description(name))
                 for name in names]
         except Exception, e:
             yield system_message(
                 _("Error: Can't get description for macro %(name)s",
                   name=names[0]), e), names
         else:
             for descr, pairs in groupby(name_descriptions,
                                         key=lambda p: p[1]):
                 if descr:
                     if isinstance(descr, (tuple, list)):
                         descr = dgettext(descr[0],
                                          to_unicode(descr[1])) \
                                 if descr[1] else ''
                     else:
                         descr = to_unicode(descr) or ''
                     if content == '*':
                         descr = format_to_oneliner(
                             self.env, formatter.context, descr,
                             shorten=True)
                     else:
                         descr = format_to_html(
                             self.env, formatter.context, descr)
                 yield descr, [name for name, descr in pairs]
 def __getattribute__(self, name):
     if name == '__class__':
         return Option
     value = Option.__getattribute__(self, name)
     if name == '__doc__':
         value = dgettext(doc_domain, value)
     return value
Example #10
0
 def __getattribute__(self, name):
     if name == '__class__':
         return Base
     val = Base.__getattribute__(self, name)
     if name == '__doc__':
         val = dgettext('tracworkflowadmin', val)
     return val
Example #11
0
    def _gather_option_data(self, req, section_name, option_name, section_default_values):
        option = None
        if (section_name, option_name) in Option.registry:
            # Allow wiki formatting in descriptions
            option = Option.registry[(section_name, option_name)]
            doc = option.__doc__
            if doc:
                doc = dgettext(option.doc_domain, doc)
            else:
                doc = None
            option_desc = doc
            option_type = option.__class__.__name__.lower()[:-6] or N_("text")
        else:
            option_desc = None
            option_type = N_("text")

        # See "IniEditorBasicSecurityManager" for why we use a pipe char here.
        if ("%s|%s" % (section_name, option_name)) in self.password_options_set:
            option_type = N_("password")

        if section_default_values:
            default_value = self._convert_value(section_default_values.get(option_name), option) or ""
        else:
            default_value = ""

        return {
            "default_value": default_value,
            "desc": option_desc,
            "type": option_type,
            "option_info": option,
            "access": self._check_option_access(section_name, option_name),
        }
Example #12
0
 def _get_macros(self, term):
     macros = {}
     for name, descr in self._known_macros.iteritems():
         if name.startswith(term):
             if isinstance(descr, (tuple, list)):
                 descr = dgettext(descr[0], to_unicode(descr[1]))
             macros[name] = descr
     return macros
Example #13
0
 def _get_doc(self, obj):
     doc = to_unicode(inspect.getdoc(obj))
     if doc and hasattr(obj, 'doc_domain') and obj.doc_domain:
         doc = dgettext(obj.doc_domain, doc)
     return doc
Example #14
0
 def getdoc(option_or_section):
     doc = to_unicode(option_or_section.__doc__)
     if doc:
         doc = dgettext(option_or_section.doc_domain, doc)
     return doc
Example #15
0
 def _get_plural_forms(self):
     for line in dgettext('messages', "").splitlines():
         match = self._plural_forms_re.match(line)
         if match:
             return (int(match.group('nplurals')), match.group('plural'))
     return (2, 'n != 1')
Example #16
0
 def getdoc(option_or_section):
     doc = to_unicode(option_or_section.__doc__)
     if doc:
         doc = dgettext(option_or_section.doc_domain, doc)
     return doc
Example #17
0
 def __getattribute__(self, name):
     val = Base.__getattribute__(self, name)
     if name == '__doc__':
         val = dgettext(TEXTDOMAIN, val)
     return val
Example #18
0
 def get_admin_panels(self, req):
     if "TRAC_ADMIN" in req.perm:
         yield ("general", dgettext("messages", "General"), "trac_ini_editor", _("trac.ini Editor"))
Example #19
0
 def formats(singular, plural):
     msgid = (singular, 0)
     if dgettext('messages', msgid) == msgid:
         return (singular, plural) # without babel
     return [dgettext('messages', (singular, i)) for i in xrange(n)]
Example #20
0
    def render_admin_panel(self, req, cat, page, path_info):
        req.perm.require('TRAC_ADMIN')

        if path_info == None:
            ext = ""
        else:
            ext = '/' + path_info

        #
        # Gather section names for section drop down field
        #
        all_section_names = []
        for section_name in self.config.sections():
            if section_name == 'components':
                continue
            all_section_names.append(section_name)

        # Check whether section exists and if it's not existing then check whether
        # its name is a valid section name.
        if (path_info is not None) and (path_info not in ('', '/', '_all_sections')) \
           and (path_info not in all_section_names):
            if path_info == 'components':
                add_warning(
                    req,
                    _('The section "components" can\'t be edited with the ini editor.'
                      ))
                req.redirect(req.href.admin(cat, page))
                return None
            elif self.valid_section_name_chars_regexp.match(path_info) is None:
                add_warning(req,
                            _('The section name %s is invalid.') % path_info)
                req.redirect(req.href.admin(cat, page))
                return None

            # Add current section if it's not already in the list. This happens if
            # the section is essentially empty (i.e. newly created with no non-default
            # option values and no option from the option registry).
            all_section_names.append(path_info)

        registry = ConfigSection.get_registry(self.compmgr)
        descriptions = {}
        for section_name, section in registry.items():
            if section_name == 'components':
                continue
            doc = section.__doc__
            if not section_name in all_section_names:
                all_section_names.append(section_name)
            if doc:
                descriptions[section_name] = dgettext(section.doc_domain, doc)

        all_section_names.sort()

        sections = {}

        #
        # Check security manager
        #
        manager = None
        try:
            manager = self.security_manager
        except Exception, detail:  # "except ... as ..." is only available since Python 2.6
            if req.method != 'POST':
                # only add this warning once
                add_warning(
                    req,
                    _('Security manager could not be initated. %s') %
                    unicode(detail))
Example #21
0
 def __getattribute__(self, name):
     val = Base.__getattribute__(self, name)
     if name == '__doc__':
         val = dgettext(TEXTDOMAIN, val)
     return val
Example #22
0
 def _get_doc(self, obj):
     doc = to_unicode(inspect.getdoc(obj))
     if doc and hasattr(obj, 'doc_domain') and obj.doc_domain:
         doc = dgettext(obj.doc_domain, doc)
     return doc
Example #23
0
File: config.py Project: zxfly/trac
def _getdoc(option_or_section):
    doc = to_unicode(option_or_section.__doc__)
    if doc:
        doc = dgettext(option_or_section.doc_domain, doc,
                       **(option_or_section.doc_args or {}))
    return doc
Example #24
0
 def __verify_size(self, size, max_size):
     if max_size >= 0 and size > max_size:
         message = dgettext('messages',
                            'Maximum attachment size: %(num)s bytes',
                            num=max_size)
         raise TracError(message, dgettext('messages', 'Upload failed'))
Example #25
0
    def post_process_request(self, req, template, data, content_type):
        if not req or not template or not isinstance(data, dict):
            return template, data, content_type

        model = None
        resource = None
        attachments = None

        if template in ('wiki_view.html', 'wiki_edit.html'):
            model = data.get('page')
        elif template == 'ticket.html':
            model = data.get('ticket')
        elif template in ('milestone_view.html', 'milestone_edit.html'):
            model = data.get('milestone')
        elif template == 'attachment.html':
            attachments = data.get('attachments')
            if attachments:
                resource = attachments['parent']

        if not resource and model and model.exists:
            resource = model.resource
        if not resource:
            return template, data, content_type
        if not attachments:
            attachments = data.get('attachments')
        if not attachments and model and resource:
            context = web_context(req, resource)
            attachments = AttachmentModule(self.env).attachment_data(context)
            # mark appending list of attachments in filter_stream
            attachments['tracdragdrop'] = True
            data['attachments'] = attachments

        if template in ('wiki_edit.html', 'milestone_edit.html'):
            self._add_overlayview(req)
        add_stylesheet(req, 'tracdragdrop/tracdragdrop.css')
        locale = req.locale and str(req.locale)
        if locale in self.messages_files:
            add_script(req, 'tracdragdrop/messages/%s.js' % locale)
        add_script(req, 'common/js/folding.js')
        add_script(req, 'tracdragdrop/tracdragdrop.js')
        script_data = {
            '_tracdragdrop': {
                'base_url':
                req.href().rstrip('/') + '/',
                'new_url':
                req.href('tracdragdrop', 'new', resource.realm, resource.id),
                'raw_parent_url':
                get_resource_url(self.env,
                                 resource.child('attachment'),
                                 req.href,
                                 format='raw'),
                'parent_name':
                get_resource_name(self.env, resource),
                'no_image_msg':
                dgettext('messages',
                         'No image "%(id)s" attached to %(parent)s'),
                'can_create':
                attachments.get('can_create') or False,
                'max_size':
                AttachmentModule(self.env).max_size,
            },
            'form_token': req.form_token,
        }
        add_script_data(req, script_data)

        return template, data, content_type
Example #26
0
    def render_admin_panel(self, req, cat, page, path_info):
        req.perm.require("TRAC_ADMIN")

        if path_info == None:
            ext = ""
        else:
            ext = "/" + path_info

        #
        # Gather section names for section drop down field
        #
        all_section_names = []
        for section_name in self.config.sections():
            if section_name == "components":
                continue
            all_section_names.append(section_name)

        # Check whether section exists and if it's not existing then check whether
        # its name is a valid section name.
        if (
            (path_info is not None)
            and (path_info not in ("", "/", "_all_sections"))
            and (path_info not in all_section_names)
        ):
            if path_info == "components":
                add_warning(req, _('The section "components" can\'t be edited with the ini editor.'))
                req.redirect(req.href.admin(cat, page))
                return None
            elif self.valid_section_name_chars_regexp.match(path_info) is None:
                add_warning(req, _("The section name %s is invalid.") % path_info)
                req.redirect(req.href.admin(cat, page))
                return None

            # Add current section if it's not already in the list. This happens if
            # the section is essentially empty (i.e. newly created with no non-default
            # option values and no option from the option registry).
            all_section_names.append(path_info)

        registry = ConfigSection.get_registry(self.compmgr)
        descriptions = {}
        for section_name, section in registry.items():
            if section_name == "components":
                continue
            doc = section.__doc__
            if not section_name in all_section_names:
                all_section_names.append(section_name)
            if doc:
                descriptions[section_name] = dgettext(section.doc_domain, doc)

        all_section_names.sort()

        sections = {}

        #
        # Check security manager
        #
        manager = None
        try:
            manager = self.security_manager
        except Exception, detail:  # "except ... as ..." is only available since Python 2.6
            if req.method != "POST":
                # only add this warning once
                add_warning(req, _("Security manager could not be initated. %s") % unicode(detail))
Example #27
0
class TracIniAdminPanel(Component):
    """ An editor panel for trac.ini. """

    implements(IAdminPanelProvider, ITemplateProvider)

    valid_section_name_chars = Option(
        'ini-editor',
        'valid-section-name-chars',
        '^[a-zA-Z0-9\\-_\\:]+$',
        doc="""Defines the valid characters for a section name or option name in 
      `trac.ini`. Must be a valid regular expression. You only need to change 
      these if you have plugins that use some strange section or option names.
      """,
        doc_domain="inieditorpanel")

    valid_option_name_chars = Option(
        'ini-editor',
        'valid-option-name-chars',
        '^[a-zA-Z0-9\\-_\\:.]+$',
        doc="""Defines the valid characters for a section name or option name in 
      `trac.ini`. Must be a valid regular expression. You only need to change 
      these if you have plugins that use some strange section or option names.
      """,
        doc_domain="inieditorpanel")

    security_manager = ExtensionOption(
        'ini-editor',
        'security-manager',
        IOptionSecurityManager,
        'IniEditorEmptySecurityManager',
        doc="""Defines the security manager that specifies whether the user has 
      access to certain options.
      """,
        doc_domain="inieditorpanel")

    # See "IniEditorBasicSecurityManager" for why we use a pipe char here.
    password_options = ListOption(
        'ini-editor',
        'password-options',
        doc="""Defines option fields (as `section-name|option-name`) that 
      represent passwords. Password input fields are used for these fields.
      Note the fields specified here are taken additionally to some predefined 
      fields provided by the ini editor.
      """,
        doc_domain="inieditorpanel")

    ini_section = ConfigSection(
        'ini-editor',
        """This section is used to handle configurations used by
      TracIniAdminPanel plugin.""",
        doc_domain='inieditorpanel')

    DEFAULT_PASSWORD_OPTIONS = {'notification|smtp_password': True}

    def __init__(self):
        """Set up translation domain"""
        locale_dir = resource_filename(__name__, 'locale')
        add_domain(self.env.path, locale_dir)

        self.valid_section_name_chars_regexp = re.compile(
            self.valid_section_name_chars)
        self.valid_option_name_chars_regexp = re.compile(
            self.valid_option_name_chars)

        self.password_options_set = copy.deepcopy(
            self.DEFAULT_PASSWORD_OPTIONS)
        for option in self.password_options:
            self.password_options_set[option] = True

    #
    # IAdminPanelProvider methods
    #

    def get_admin_panels(self, req):
        if 'TRAC_ADMIN' in req.perm:
            yield ('general', dgettext('messages',
                                       'General'), 'trac_ini_editor',
                   _('trac.ini Editor'))

    def render_admin_panel(self, req, cat, page, path_info):
        req.perm.require('TRAC_ADMIN')

        if path_info == None:
            ext = ""
        else:
            ext = '/' + path_info

        #
        # Gather section names for section drop down field
        #
        all_section_names = []
        for section_name in self.config.sections():
            if section_name == 'components':
                continue
            all_section_names.append(section_name)

        # Check whether section exists and if it's not existing then check whether
        # its name is a valid section name.
        if (path_info is not None) and (path_info not in ('', '/', '_all_sections')) \
           and (path_info not in all_section_names):
            if path_info == 'components':
                add_warning(
                    req,
                    _('The section "components" can\'t be edited with the ini editor.'
                      ))
                req.redirect(req.href.admin(cat, page))
                return None
            elif self.valid_section_name_chars_regexp.match(path_info) is None:
                add_warning(req,
                            _('The section name %s is invalid.') % path_info)
                req.redirect(req.href.admin(cat, page))
                return None

            # Add current section if it's not already in the list. This happens if
            # the section is essentially empty (i.e. newly created with no non-default
            # option values and no option from the option registry).
            all_section_names.append(path_info)

        registry = ConfigSection.get_registry(self.compmgr)
        descriptions = {}
        for section_name, section in registry.items():
            if section_name == 'components':
                continue
            doc = section.__doc__
            if not section_name in all_section_names:
                all_section_names.append(section_name)
            if doc:
                descriptions[section_name] = dgettext(section.doc_domain, doc)

        all_section_names.sort()

        sections = {}

        #
        # Check security manager
        #
        manager = None
        try:
            manager = self.security_manager
        except Exception, detail:  # "except ... as ..." is only available since Python 2.6
            if req.method != 'POST':
                # only add this warning once
                add_warning(
                    req,
                    _('Security manager could not be initated. %s') %
                    unicode(detail))

        if manager is None:
            #
            # Security manager is not available
            #
            if req.method == 'POST':
                req.redirect(req.href.admin(cat, page) + ext)
                return None

        elif req.method == 'POST' and 'change-section' in req.args:
            #
            # Changing the section
            #
            req.redirect(
                req.href.admin(cat, page) + '/' + req.args['change-section'])
            return None

        elif req.method == 'POST' and 'new-section-name' in req.args:
            #
            # Create new section (essentially simply changing the section)
            #
            section_name = req.args['new-section-name'].strip()

            if section_name == '':
                add_warning(req, _('The section name was empty.'))
                req.redirect(req.href.admin(cat, page) + ext)
            elif section_name == 'components':
                add_warning(
                    req,
                    _('The section "components" can\'t be edited with the ini editor.'
                      ))
                req.redirect(req.href.admin(cat, page))
            elif self.valid_section_name_chars_regexp.match(
                    section_name) is None:
                add_warning(
                    req,
                    _('The section name %s is invalid.') % section_name)
                req.redirect(req.href.admin(cat, page) + ext)
            else:
                if section_name not in all_section_names:
                    add_notice(
                        req,
                        _('Section %s has been created. Note that you need to add at least one option to store it permanently.'
                          ) % section_name)
                else:
                    add_warning(req, _('The section already exists.'))
                req.redirect(req.href.admin(cat, page) + '/' + section_name)

            return None

        elif path_info is not None and path_info not in ('', '/'):
            #
            # Display and possibly modify section (if one is selected)
            #
            default_values = self.config.defaults()

            # Gather option values
            # NOTE: This needs to be done regardless whether we have POST data just to
            #   be on the safe site.
            if path_info == '_all_sections':
                # All sections
                custom_options = self._get_session_custom_options(req)
                # Only show sections with any data
                for section_name in all_section_names:
                    sections[section_name] = self._read_section_config(
                        req, section_name, default_values, custom_options)
            else:
                # Only a single section
                # Note: At this point path_info has already been verified to contain a
                #   valid section name (see check above).
                sections[path_info] = self._read_section_config(
                    req, path_info, default_values)

            #
            # Handle POST data
            #
            if req.method == 'POST':
                # Overwrite option values with POST values so that they don't get lost
                for key, value in req.args.items():
                    if not key.startswith(
                            'inieditor_value##'):  # skip unrelated args
                        continue

                    name = key[len('inieditor_value##'):].split('##')
                    section_name = name[0].strip()
                    option_name = name[1].strip()

                    if section_name == 'components':
                        continue

                    if option_name == 'dummy':
                        if section_name not in sections:
                            sections[section_name] = {}
                        continue

                    section = sections.get(section_name, None)
                    if section:
                        option = section.get(option_name, None)
                        if option:
                            self._set_option_value(req, section_name,
                                                   option_name, option, value)
                        else:
                            # option not available; was propably newly added
                            section[
                                option_name] = self._create_new_field_instance(
                                    req, section_name, option_name,
                                    default_values.get(section_name, None),
                                    value)
                    else:
                        # newly created section (not yet stored)
                        sections[section_name] = {
                            option_name:
                            self._create_new_field_instance(
                                req, section_name, option_name, None, value)
                        }

                # Check which options use their default values
                # NOTE: Must be done after assigning field value from the previous step
                #   to ensure that the default value has been initialized.
                if 'inieditor_default' in req.args:
                    default_using_options = req.args.get('inieditor_default')
                    if default_using_options is None or len(
                            default_using_options) == 0:
                        # if no checkbox was selected make this explicitly a list (just for safety)
                        default_using_options = []
                    elif type(default_using_options).__name__ != 'list':
                        # if there's only one checkbox it's just a string
                        default_using_options = [
                            unicode(default_using_options)
                        ]

                    for default_using_option in default_using_options:
                        name = default_using_option.split('##')
                        section_name = name[0].strip()
                        option_name = name[1].strip()
                        section = sections.get(section_name, None)
                        if section:
                            option = section.get(option_name, None)
                            if option:
                                if option['access'] == ACCESS_MODIFIABLE:
                                    option['value'] = option['default_value']
                            else:
                                # option not available; was propably newly added
                                section[
                                    option_name] = self._create_new_field_instance(
                                        req, section_name, option_name,
                                        default_values.get(section_name, None))
                        else:
                            # newly created section (not yet stored)
                            sections[section_name] = {
                                option_name:
                                self._create_new_field_instance(
                                    req, section_name, option_name, None)
                            }

                #
                # Identify submit type
                # NOTE: Using "cur_focused_field" is a hack to support hitting the
                #  return key even for the new-options field. Without this hitting
                #  return would always associated to the apply button.
                #
                submit_type = None
                cur_focused_field = req.args.get('inieditor_cur_focused_field',
                                                 '')
                if cur_focused_field.startswith('option-value-'):
                    submit_type = 'apply-' + cur_focused_field[
                        len('option-value-'):]
                elif cur_focused_field.startswith('new-options-'):
                    submit_type = 'addnewoptions-' + cur_focused_field[
                        len('new-options-'):]
                else:
                    for key in req.args:
                        if not key.startswith('inieditor-submit-'):
                            continue

                        submit_type = key[len('inieditor-submit-'):]
                        break

                if submit_type.startswith('apply'):  # apply changes
                    if submit_type.startswith('apply-'):
                        # apply only one section
                        section_name = submit_type[len('apply-'):].strip()
                        if self._apply_section_changes(req, section_name,
                                                       sections[section_name]):
                            add_notice(
                                req,
                                _('Changes for section %s have been applied.')
                                % section_name)
                            self.config.save()
                        else:
                            add_warning(req,
                                        _('No changes have been applied.'))
                    else:
                        # apply all sections
                        changes_applied = False
                        for section_name, options in sections.items():
                            if self._apply_section_changes(
                                    req, section_name, options):
                                changes_applied = True

                        if changes_applied:
                            add_notice(req, _('Changes have been applied.'))
                            self.config.save()
                        else:
                            add_warning(req,
                                        _('No changes have been applied.'))

                elif submit_type.startswith('discard'):
                    if submit_type.startswith('discard-'):
                        # discard only one section
                        section_name = submit_type[len('discard-'):].strip()
                        self._discard_section_changes(req, section_name,
                                                      sections[section_name])
                        add_notice(
                            req,
                            _('Your changes for section %s have been discarded.'
                              ) % section_name)
                    else:
                        # discard all sections
                        for section_name, options in sections.items():
                            self._discard_section_changes(
                                req, section_name, options)
                        add_notice(req, _('All changes have been discarded.'))

                elif submit_type.startswith('addnewoptions-'):
                    section_name = submit_type[len('addnewoptions-'):].strip()
                    section = sections[section_name]
                    new_option_names = req.args['new-options-' +
                                                section_name].split(',')
                    section_default_values = default_values.get(
                        section_name, None)

                    field_added = False
                    for new_option_name in new_option_names:
                        new_option_name = new_option_name.strip()
                        if new_option_name in section:
                            continue  # field already exists

                        if self.valid_option_name_chars_regexp.match(
                                new_option_name) is None:
                            add_warning(
                                req,
                                _('The option name %s is invalid.') %
                                new_option_name)
                            continue

                        new_option = self._create_new_field_instance(
                            req, section_name, new_option_name,
                            section_default_values)
                        if new_option['access'] != ACCESS_MODIFIABLE:
                            add_warning(
                                req,
                                _('The new option %s could not be added due to security restrictions.'
                                  ) % new_option_name)
                            continue

                        self._add_session_custom_option(
                            req, section_name, new_option_name)
                        field_added = True

                    if field_added:
                        add_notice(
                            req,
                            _('The new fields have been added to section %s.')
                            % section_name)
                    else:
                        add_warning(req, _('No new fields have been added.'))

                req.redirect(req.href.admin(cat, page) + ext)
                return None

        # Split sections dict for faster template rendering
        modifiable_options = {}
        readonly_options = {}
        hidden_options = {}
        for section_name, options in sections.items():
            sect_modifiable = {}
            sect_readonly = {}
            sect_hidden = {}
            for option_name, option in options.items():
                if option['access'] == ACCESS_MODIFIABLE:
                    sect_modifiable[option_name] = option
                elif option['access'] == ACCESS_READONLY:
                    sect_readonly[option_name] = option
                else:
                    sect_hidden[option_name] = option

            modifiable_options[section_name] = sect_modifiable
            readonly_options[section_name] = sect_readonly
            hidden_options[section_name] = sect_hidden

        registry = ConfigSection.get_registry(self.compmgr)
        descriptions = {}
        for name, section in registry.items():
            doc = section.__doc__
            if doc:
                descriptions[name] = dgettext(section.doc_domain, doc)

        data = {
            'all_section_names': all_section_names,
            'sections': sections,
            'descriptions': descriptions,
            'modifiable_options': modifiable_options,
            'readonly_options': readonly_options,
            'hidden_options': hidden_options
        }

        section_counters = {}
        settings_stored_values = {}
        for section_name, section in sections.iteritems():
            escaped = section_name.replace(':', '_')
            section_counters[escaped] = {'option_count': len(section)}
            settings_stored_values[escaped] = dict(
                (name, option['stored_value']) for name, option in
                modifiable_options[section_name].iteritems()
                if option['type'] != 'password')

        add_script_data(
            req, {
                'section_count':
                len(sections),
                'section_names':
                sorted(section_counters),
                'section_counters':
                section_counters,
                'settings_stored_values':
                settings_stored_values,
                'info_format':
                _("Modified: %(mod)d | Defaults: %(def)d | Options "
                  "count: %(opt)d"),
            })

        add_stylesheet(req, 'inieditorpanel/main.css')
        add_script(req, 'inieditorpanel/editor.js')
        return 'admin_tracini.html', data
Example #28
0
 def get_admin_panels(self, req):
     if 'TRAC_ADMIN' in req.perm:
         yield ('general', dgettext('messages',
                                    'General'), 'trac_ini_editor',
                _('trac.ini Editor'))
Example #29
0
 def get_admin_panels(self, req):
     if 'TRAC_ADMIN' in req.perm:
         yield ('ticket', dgettext("messages", ("Ticket System")),
                'workflowadmin', _("Workflow Admin"))
Example #30
0
    def process_request(self, req):
        strategy = req.args.get('strategy')
        term = req.args.get('q')

        if strategy == 'linkresolvers':
            wiki = WikiSystem(self.env)
            completions = []
            for provider in wiki.syntax_providers:
                for name, resolver in provider.get_link_resolvers():
                    if name.startswith(term):
                        completions.append(name)
            self._send_json(req, completions)

        elif strategy == 'ticket':
            with self.env.db_query as db:
                rows = db("""
                    SELECT id, summary
                    FROM ticket
                    WHERE %s %s
                    ORDER BY changetime DESC
                    LIMIT 10
                    """ % (db.cast('id', 'text'), db.prefix_match()),
                    (db.prefix_match_value(term), ))
            completions = [{
                'id': row[0],
                'summary': row[1],
                } for row in rows
                if 'TICKET_VIEW' in req.perm(Resource('ticket', row[0]))]
            self._send_json(req, completions)

        elif strategy == 'wikipage':
            with self.env.db_query as db:
                rows = db("""
                    SELECT name
                    FROM wiki
                    WHERE name %s
                    GROUP BY name
                    ORDER BY name
                    LIMIT 10
                    """ % db.prefix_match(),
                    (db.prefix_match_value(term), ))
            completions = [row[0] for row in rows
                           if 'WIKI_VIEW' in req.perm(Resource('wiki', row[0]))]
            self._send_json(req, completions)

        elif strategy == 'macro':
            resource = Resource()
            context = web_context(req, resource)
            wiki = WikiSystem(self.env)
            macros = []
            for provider in wiki.macro_providers:
                names = list(provider.get_macros() or [])
                for name in names:
                    if name.startswith(term):
                        macros.append((name, provider))
            completions = []
            if len(macros) == 1:
                name, provider = macros[0]
                descr = provider.get_macro_description(name)
                if isinstance(descr, (tuple, list)):
                    descr = dgettext(descr[0], to_unicode(descr[1]))
                descr = format_to_html(self.env, context, descr)
                completions.append({
                    'name': name,
                    'description': descr,
                })
            else:
                for name, provider in macros:
                    descr = provider.get_macro_description(name)
                    if isinstance(descr, (tuple, list)):
                        descr = dgettext(descr[0], to_unicode(descr[1]))
                    descr = format_to_oneliner(self.env, context, descr, shorten=True)
                    completions.append({
                        'name': name,
                        'description': descr,
                    })
            self._send_json(req, completions)

        elif strategy == 'source':
            rm = RepositoryManager(self.env)
            completions = []
            if term.find('/') == -1:
                for reponame, repoinfo in rm.get_all_repositories().iteritems():
                    if 'BROWSER_VIEW' in req.perm(Resource('repository', reponame)):
                        if len(term) == 0 or reponame.lower().startswith(term.lower()):
                            completions.append(reponame+'/')
            else:
                reponame, path = term.split('/', 1)
                repos = rm.get_repository(reponame)
                if repos is not None:
                    if path.find('@') != -1:
                        path, search_rev = path.rsplit('@', 1)
                        node = repos.get_node(path, repos.youngest_rev)
                        if node.can_view(req.perm):
                            for r in node.get_history(10):
                                if str(r[1]).startswith(search_rev):
                                    completions.append('%s/%s@%s' % (reponame, path, r[1]))
                    else:
                        if path.find('/') != -1:
                            dir, filename = path.rsplit('/', 1)
                        else:
                            dir, filename = '/', path
                        node = repos.get_node(dir, repos.youngest_rev)
                        completions = ['%s/%s%s' % (reponame, n.path, '/' if n.isdir else '')
                                       for n in node.get_entries()
                                       if n.can_view(req.perm) and n.name.startswith(filename)]
            self._send_json(req, completions)

        raise TracError()