Example #1
0
class IRule(form.Schema):

    source_path = TextLine(
        title=_(u'label_source_path', default=u'Source Path'))

    destination = TextLine(
        title=_(u'label_destination', default=u'Destination'))
Example #2
0
    def validate_source_path(self, rownum, value):
        if not value:
            raise Invalid(
                _(u'source_path_required',
                  default=u'Row ${rownum}: source path required.',
                  mapping={'rownum': rownum}))

        if value == '/':
            raise Invalid(
                _(u'source_path_invalid_root',
                  default=u'Row ${rownum}: invalid source path: cannot'
                  u' redirect from root.',
                  mapping={'rownum': rownum}))

        if value.startswith('/'):
            return

        raise Invalid(
            _(u'source_path_must_start_with_slash',
              default=u'Row ${rownum}: the source path "${value}"'
              u' must start with a slash.',
              mapping={
                  'rownum': rownum,
                  'value': value
              }))
Example #3
0
def create_rules_excel():
    portal = api.portal.get()
    request = portal.REQUEST

    rules = IRedirectConfig(portal).rules
    if not rules:
        rules = []

    book = Workbook()
    sheet = book.active

    title = translate(_(u'Redirect Configuration'), context=request)
    source_title = translate(_(u'label_source_path', default=u'Source Path'),
                             context=request)
    destination_title = translate(_(u'label_destination',
                                    default=u'Destination'),
                                  context=request)

    # HEADER
    sheet.title = title

    bold = Font(bold=True)
    cell = sheet.cell(column=1, row=1)
    cell.font = bold
    cell.value = source_title

    cell = sheet.cell(column=2, row=1)
    cell.font = bold
    cell.value = destination_title

    # DATA
    for rule_nr, rule in enumerate(rules):
        cell = sheet.cell(column=1, row=RULES_START_ROW + rule_nr)
        cell.value = rule['source_path']
        cell = sheet.cell(column=2, row=RULES_START_ROW + rule_nr)
        cell.value = rule['destination']

    # match the width to the longest entry
    for column in sheet.columns:
        maxwidth = 0
        for cell in column:
            if not cell.value:
                continue
            cwidth = len(cell.value)
            maxwidth = cwidth if cwidth > maxwidth else maxwidth
        # a bit more space for readability
        sheet.column_dimensions[cell.column].width = maxwidth + 5

    return save_virtual_workbook(book)
Example #4
0
def create_rules_excel():
    portal = api.portal.get()
    request = portal.REQUEST

    rules = IRedirectConfig(portal).rules
    if not rules:
        rules = []

    book = Workbook()
    sheet = book.active

    title = translate(_(u'Redirect Configuration'), context=request)
    source_title = translate(_(u'label_source_path',
                             default=u'Source Path'), context=request)
    destination_title = translate(_(u'label_destination',
                                  default=u'Destination'), context=request)

    # HEADER
    sheet.title = title

    bold = Font(bold=True)
    cell = sheet.cell(column=1, row=1)
    cell.font = bold
    cell.value = source_title

    cell = sheet.cell(column=2, row=1)
    cell.font = bold
    cell.value = destination_title

    # DATA
    for rule_nr, rule in enumerate(rules):
        cell = sheet.cell(column=1, row=RULES_START_ROW+rule_nr)
        cell.value = rule['source_path']
        cell = sheet.cell(column=2, row=RULES_START_ROW+rule_nr)
        cell.value = rule['destination']

    # match the width to the longest entry
    for column in sheet.columns:
        maxwidth = 0
        for cell in column:
            if not cell.value:
                continue
            cwidth = len(cell.value)
            maxwidth = cwidth if cwidth > maxwidth else maxwidth
        # a bit more space for readability
        sheet.column_dimensions[cell.column].width = maxwidth + 5

    return save_virtual_workbook(book)
Example #5
0
class ImportRedirectConfigView(form.SchemaForm):

    schema = IRulesUploadSchema
    ignoreContext = True

    label = _(u"Upload redirect config")

    def updateWidgets(self):
        # use the basic widget to disable "keep existing file"
        self.fields['rules_file'].widgetFactory = ForceFileUploadFieldWidget
        super(ImportRedirectConfigView, self).updateWidgets()

    @button.buttonAndHandler(u'Upload')
    def handleApply(self, action):
        data, errors = self.extractData()

        if errors:
            # since we have only one field we can copy the error message
            # to make it more visible
            self.status = errors[0].message
            return

        excel_file = StringIO(data['rules_file'].data)
        rules = load_rules_from_excel(excel_file)

        rconfig = IRedirectConfig(self.context)
        rconfig.rules = rules

        messages = IStatusMessage(self.request)
        messages.add(_("The redirect config has been replaced."), type=u'info')

        self.request.RESPONSE.redirect(self.context.absolute_url())
Example #6
0
 def validate(self, value):
     if not value:
         raise Invalid(_(u'missing_input_data',
                         default=u'Please upload a rules excel file.'))
     excel_file = StringIO(value.data)
     rules = load_rules_from_excel(excel_file)
     map(self.validate_row, enumerate(rules, RULES_START_ROW))
Example #7
0
    def validate_destination(self, rownum, value):
        if not value:
            raise Invalid(
                _(u'destination_required',
                  default=u'Row ${rownum}: destination required.',
                  mapping={'rownum': rownum}))

        if value.startswith('/'):
            return

        if re.match(r'^https?://', value):
            return

        raise Invalid(
            _(u'destination_must_be_path_or_url',
              default=u'Row ${rownum}: the destination "${value}"'
              u' must be a path (start with slash)'
              u' or a full qualified URL.',
              mapping={'rownum': rownum, 'value': value}))
Example #8
0
    def validate_destination(self, rownum, value):
        if not value:
            raise Invalid(
                _(u'destination_required',
                  default=u'Row ${rownum}: destination required.',
                  mapping={'rownum': rownum}))

        if value.startswith('/'):
            return

        if re.match(r'^https?://', value):
            return

        raise Invalid(
            _(u'destination_must_be_path_or_url',
              default=u'Row ${rownum}: the destination "${value}"'
              u' must be a path (start with slash)'
              u' or a full qualified URL.',
              mapping={
                  'rownum': rownum,
                  'value': value
              }))
Example #9
0
    def validate_source_path(self, rownum, value):
        if not value:
            raise Invalid(
                _(u'source_path_required',
                  default=u'Row ${rownum}: source path required.',
                  mapping={'rownum': rownum}))

        if value == '/':
            raise Invalid(
                _(u'source_path_invalid_root',
                  default=u'Row ${rownum}: invalid source path: cannot'
                  u' redirect from root.',
                  mapping={'rownum': rownum}))

        if value.startswith('/'):
            return

        raise Invalid(
            _(u'source_path_must_start_with_slash',
              default=u'Row ${rownum}: the source path "${value}"'
              u' must start with a slash.',
              mapping={'rownum': rownum, 'value': value}))
Example #10
0
    def handleApply(self, action):
        data, errors = self.extractData()

        if errors:
            # since we have only one field we can copy the error message
            # to make it more visible
            self.status = errors[0].message
            return

        excel_file = StringIO(data['rules_file'].data)
        rules = load_rules_from_excel(excel_file)

        rconfig = IRedirectConfig(self.context)
        rconfig.rules = rules

        messages = IStatusMessage(self.request)
        messages.add(_("The redirect config has been replaced."), type=u'info')

        self.request.RESPONSE.redirect(self.context.absolute_url())
Example #11
0
class IRulesUploadSchema(form.Schema):
    form.primary('rules_file')
    rules_file = NamedBlobFile(
        title=_(u'redirect_config_file',
                default=u'Excel redirect config'),
        required=True)
Example #12
0
class IRedirectConfigSchema(form.Schema):

    form.widget('rules', DataGridFieldFactory, allow_reorder=True)
    rules = List(title=_(u'label_redirect_rules', default=u'Redirect rules'),
                 value_type=DictRow(schema=IRule),
                 description=RULES_DESCRIPTION)
Example #13
0
 def Title(self):
     return _(u'Redirect Configuration')
Example #14
0
from z3c.form.validator import SimpleFieldValidator
from z3c.form.validator import WidgetValidatorDiscriminators
from zope.component import adapter
from zope.i18nmessageid import Message
from zope.interface import alsoProvides
from zope.interface import implementer
from zope.interface import implements
from zope.interface import Invalid
from zope.schema import List
from zope.schema import TextLine
import re

REDIRECT_CONFIG_ID = 'redirect-config'

RULES = dict((u'm{}'.format(idx), msg) for (idx, msg) in enumerate((
    _(u'Redirects are only applied if no content is found (404).'),
    _(u'Redirect rules are applied top-down: top roles have higher'
      u' priority. The first matching rule is applied, later rules are'
      u' not considered.'),
    _(u'Redirects match when the request path starts with the'
      u' source path.'),
    _(u'Each rule requires a source path and a destination.'),
    _(u'The source path must start with a slash and should not'
      u' be the site root.'),
    _(u'The destination may be a path (starting with a slash)'
      u' or an URL to an external site.'),
)))

RULES_DESCRIPTION = Message(
    u'<ul>' + ''.join('<li>${%s}</li>' % key
                      for key in sorted(RULES.keys())) + u'</ul>',
Example #15
0
 def Title(self):
     return _(u'Redirect Configuration')
Example #16
0
from zope.interface import implementer
from zope.interface import implements
from zope.interface import Invalid
from zope.schema import List
from zope.schema import TextLine
import re


REDIRECT_CONFIG_ID = 'redirect-config'

RULES = dict(
    (u'm{}'.format(idx), msg)
    for (idx, msg)
    in enumerate((

        _(u'Redirects are only applied if no content is found (404).'),
        _(u'Redirect rules are applied top-down: top roles have higher'
          u' priority. The first matching rule is applied, later rules are'
          u' not considered.'),
        _(u'Redirects match when the request path starts with the'
          u' source path.'),
        _(u'Each rule requires a source path and a destination.'),
        _(u'The source path must start with a slash and should not'
          u' be the site root.'),
        _(u'The destination may be a path (starting with a slash)'
          u' or an URL to an external site.'),

    )))

RULES_DESCRIPTION = Message(
    u'<ul>' +