예제 #1
0
파일: lists.py 프로젝트: mjsorribas/ringo
    def __init__(self, listing, tablename=None):
        self.listing = listing
        self.config = get_table_config(self.listing.clazz, tablename)
        self.template = template_lookup.get_template("internal/dtlist.mako")

        # Template for JS datatable configuration
        self.js_template = template_lookup.get_template("internal/dtlist.js.mako")
예제 #2
0
    def __init__(self, listing, tablename=None):
        self.listing = listing
        self.config = get_table_config(self.listing.clazz, tablename)
        self.template = template_lookup.get_template("internal/dtlist.mako")

        # Template for JS datatable configuration
        self.js_template = template_lookup.get_template(
            "internal/dtlist.js.mako")
예제 #3
0
파일: form.py 프로젝트: reiterl/ringo
    def render(self):
        """Initialize renderer"""
        html = []
        active = 'active' if self._active else 'inactive'
        config = self._field._config.renderer
        has_errors = len(self._field.get_errors())
        has_warnings = len(self._field.get_warnings())
        class_options = "form-group %s %s %s" % ((has_errors and 'has-error'),
                                                 (has_warnings and 'has-warning'), (active))
        html.append(HTML.tag("div", _closed=False,
                             rules=u"{}".format(";".join(rules_to_string(self._field))),
                             formgroup="{}".format(self._field.name),
                             desired="{}".format(self._field.desired),
                             required="{}".format(self._field.required),
                             class_=class_options))
        html.append(self._render_label())

        # All items which can potentially be linked. However this list
        # of items may be already filtered be defining a default filter
        # in the overview configuration which is used for this renderer.
        items = self.itemlist.items
        selected_items = self._get_selected_items(items)

        if self._field.readonly or self.onlylinked == "true":
            items = selected_items

        # Filter options based on the configured filter expression of
        # the renderer. Please note the this method return a list of
        # tuples.
        item_tuples = self._field.filter_options(items)

        # Get filtered options and only use the items which are
        # in the origin items list and has passed filtering.
        item_tuples = self._field.filter_options(items)
        # Filter the items again based on the permissions. This means
        # resetting the third value in the tuple.
        if self.showall != "true" and not self._field.readonly:
            item_tuples = filter_options_on_permissions(self._field._form._request,
                                                        item_tuples)

        values = {'items': item_tuples,
                  'selected_item_ids': [i.id for i in selected_items],
                  'field': self._field,
                  'clazz': self.get_class(),
                  'pclazz': self._field._form._item.__class__,
                  'request': self._field._form._request,
                  '_': self._field._form._translate,
                  's': security,
                  'h': helpers,
                  'url_getter': get_link_url,
                  'tableconfig': get_table_config(self.itemlist.clazz,
                                                  config.table)}
        html.append(literal(self.template.render(**values)))
        html.append(self._render_errors())
        html.append(self._render_help())
        html.append(HTML.tag("/div", _closed=False))
        return literal("").join(html)
예제 #4
0
def handle_sorting(clazz, request):
    """Return a tuple of *fieldname* and *sortorder* (asc, desc). The
    sorting is determined in the follwoing order: First try to get the
    sorting from the current request (GET-Param). If there are no
    sorting params try to get the params saved in the session or if
    requested from a saved search. As last
    fallback use the default sorting for the table.
    """
    name = clazz.__tablename__

    # Default sorting options
    default_field = get_table_config(clazz).get_default_sort_column()
    default_order = get_table_config(clazz).get_default_sort_order()

    # Get sorting from the session. If there is no saved sorting use the
    # default value.
    field = request.session.get('%s.list.sort_field' % name, default_field)
    order = request.session.get('%s.list.sort_order' % name, default_order)

    # Get saved sorting from the the saved search.
    saved_search_id = request.params.get('saved')
    if saved_search_id:
        searches_dic = request.user.settings.get('searches', {})
        if searches_dic:
            search = searches_dic.get(name)
            if search:
                field, order = search.get(saved_search_id, [[], [], None])[1]

    # Get sorting from the request. If there is no sorting option in
    # the request then use the saved sorting options.
    field = request.GET.get('sort_field', field)
    order = request.GET.get('sort_order', order)

    # Save current sorting in the session
    if 'reset' in request.params:
        request.session['%s.list.sort_field' % name] = default_field
        request.session['%s.list.sort_order' % name] = default_order
    else:
        request.session['%s.list.sort_field' % name] = field
        request.session['%s.list.sort_order' % name] = order
    request.session.save()

    return field, order
예제 #5
0
파일: list_.py 프로젝트: mjsorribas/ringo
def handle_sorting(clazz, request):
    """Return a tuple of *fieldname* and *sortorder* (asc, desc). The
    sorting is determined in the follwoing order: First try to get the
    sorting from the current request (GET-Param). If there are no
    sorting params try to get the params saved in the session or if
    requested from a saved search. As last
    fallback use the default sorting for the table.
    """
    name = clazz.__tablename__

    # Default sorting options
    default_field = get_table_config(clazz).get_default_sort_column()
    default_order = get_table_config(clazz).get_default_sort_order()

    # Get sorting from the session. If there is no saved sorting use the
    # default value.
    field = request.session.get('%s.list.sort_field' % name, default_field)
    order = request.session.get('%s.list.sort_order' % name, default_order)

    # Get saved sorting from the the saved search.
    saved_search_id = request.params.get('saved')
    if saved_search_id:
        searches_dic = request.user.settings.get('searches', {})
        if searches_dic:
            search = searches_dic.get(name)
            if search:
                field, order = search.get(saved_search_id, [[], [], None])[1]

    # Get sorting from the request. If there is no sorting option in
    # the request then use the saved sorting options.
    field = request.GET.get('sort_field', field)
    order = request.GET.get('sort_order', order)

    # Save current sorting in the session
    if 'reset' in request.params:
        request.session['%s.list.sort_field' % name] = default_field
        request.session['%s.list.sort_order' % name] = default_order
    else:
        request.session['%s.list.sort_field' % name] = field
        request.session['%s.list.sort_order' % name] = order
    request.session.save()

    return field, order
예제 #6
0
파일: list_.py 프로젝트: mjsorribas/ringo
def get_list_renderer(listing, request):
    """Returns the renderer for an listing.
    Allow to use DTListRenderer if the renderer configuration is set."""
    tableconfig = get_table_config(listing.clazz)
    settings = request.registry.settings
    default = settings.get("layout.advanced_overviews") == "true"
    if tableconfig.is_advancedsearch(default):
        return ListRenderer(listing)
    else:
        return DTListRenderer(listing)
예제 #7
0
def get_list_renderer(listing, request, table=None):
    """Returns the renderer for an listing.
    Allow to use DTListRenderer if the renderer configuration is set."""
    tableconfig = get_table_config(listing.clazz, table)
    settings = request.registry.settings
    default = settings.get("layout.advanced_overviews") == "true"
    if tableconfig.is_advancedsearch(default):
        return ListRenderer(listing, table)
    else:
        return DTListRenderer(listing, table)
예제 #8
0
    def itemlist(self):
        clazz = self.get_class()
        itemlist = get_item_list(self._field._form._request, clazz)
        config = get_table_config(itemlist.clazz,
                                  self._field._config.renderer.table)
        sort_field = config.get_default_sort_column()
        sort_order = config.get_default_sort_order()
        itemlist.sort(sort_field, sort_order)

        # Warning filtering items here can cause loosing relations to
        # the filtered items. This is esspecially true if the item which
        # was related to the item before now gets filtered because of a
        # changes value in an attribute e.g. In this case the filtered
        # item is not in the list at all and will not be sent on a POST
        # request. This will result in removing the relation!
        search  = config.get_default_search()
        itemlist.filter(search)
        return itemlist
예제 #9
0
    def render(self):
        """Initialize renderer"""
        html = []
        active = 'active' if self._active else 'inactive'
        config = self._field._config.renderer
        has_errors = len(self._field.get_errors())
        has_warnings = len(self._field.get_warnings())
        class_options = "form-group %s %s %s" % ((has_errors and 'has-error'),
                                              (has_warnings and 'has-warning'),(active))
        html.append(HTML.tag("div", _closed=False,
                             rules=u"{}".format(";".join(self._field.rules_to_string)),
                             formgroup="{}".format(self._field.name),
                             desired="{}".format(self._field.desired),
                             required="{}".format(self._field.required),
                             class_=class_options))
        html.append(self._render_label())
        if self._field.is_readonly() or self.onlylinked == "true":
            items = self._get_selected_items(self.itemlist.items)
        else:
            items = self.itemlist.items

        # Get filtered options and only use the items which are
        # in the origin items list and has passed filtering.
        items = self._field.filter_options(items)
        # Now filter the items based on the user permissions
        if self.showall != "true": 
            items = filter_options_on_permissions(self._field._form._request,
                                                  items)

        values = {'items': items,
                  'field': self._field,
                  'clazz': self.get_class(),
                  'pclazz': self._field._form._item.__class__,
                  'request': self._field._form._request,
                  '_': self._field._form._translate,
                  's': security,
                  'h': helpers,
                  'tableconfig': get_table_config(self.itemlist.clazz,
                                                  config.table)}
        html.append(literal(self.template.render(**values)))
        html.append(self._render_errors())
        html.append(self._render_help())
        html.append(HTML.tag("/div", _closed=False))
        return literal("").join(html)
예제 #10
0
파일: list_.py 프로젝트: mjsorribas/ringo
def handle_paginating(clazz, request):
    """Returns a tupe of current page and pagesize. The default page and
    size is page on and all items on one page. This is also the default
    if pagination is not enabled for the table."""

    name = clazz.__tablename__
    # Default pagination options
    table_config = get_table_config(clazz)
    settings = request.registry.settings
    default = settings.get("layout.advanced_overviews") == "true"
    # Only set paginated if the table is the advancedsearch as the
    # simple search provides its own client sided pagination.
    if table_config.is_paginated() and table_config.is_advancedsearch(default):
        default_page = 0 # First page
        default_size = 50
    else:
        return (0, None)

    # Get pagination from session
    page = request.session.get('%s.list.pagination_page' % name, default_page)
    size = request.session.get('%s.list.pagination_size' % name, default_size)

    # Overwrite options with options from get request
    page = int(request.GET.get('pagination_page', page))
    size = request.GET.get('pagination_size', size)
    if size:
        size = int(size)
    else:
        size = None

    if 'reset' in request.params:
        request.session['%s.list.pagination_page' % name] = default_page
        request.session['%s.list.pagination_size' % name] = default_size
    else:
        request.session['%s.list.pagination_page' % name] = page
        request.session['%s.list.pagination_size' % name] = size
    request.session.save()

    return (page, size)
예제 #11
0
def handle_paginating(clazz, request):
    """Returns a tupe of current page and pagesize. The default page and
    size is page on and all items on one page. This is also the default
    if pagination is not enabled for the table."""

    name = clazz.__tablename__
    # Default pagination options
    table_config = get_table_config(clazz)
    settings = request.registry.settings
    default = settings.get("layout.advanced_overviews") == "true"
    # Only set paginated if the table is the advancedsearch as the
    # simple search provides its own client sided pagination.
    if table_config.is_paginated() and table_config.is_advancedsearch(default):
        default_page = 0  # First page
        default_size = 50
    else:
        return (0, None)

    # Get pagination from session
    page = request.session.get('%s.list.pagination_page' % name, default_page)
    size = request.session.get('%s.list.pagination_size' % name, default_size)

    # Overwrite options with options from get request
    page = int(request.GET.get('pagination_page', page))
    size = request.GET.get('pagination_size', size)
    if size:
        size = int(size)
    else:
        size = None

    if 'reset' in request.params:
        request.session['%s.list.pagination_page' % name] = default_page
        request.session['%s.list.pagination_size' % name] = default_size
    else:
        request.session['%s.list.pagination_page' % name] = page
        request.session['%s.list.pagination_size' % name] = size
    request.session.save()

    return (page, size)
예제 #12
0
    def itemlist(self):
        clazz = self.get_class()
        if self.showall == 'true':
            itemlist = get_item_list(self._field._form._request, clazz)
        else:
            itemlist = get_item_list(self._field._form._request,
                                     clazz,
                                     user=self._field._form._request.user)
        config = get_table_config(itemlist.clazz,
                                  self._field._config.renderer.table)
        sort_field = config.get_default_sort_column()
        sort_order = config.get_default_sort_order()
        itemlist.sort(sort_field, sort_order)

        # Warning filtering items here can cause loosing relations to
        # the filtered items. This is esspecially true if the item which
        # was related to the item before now gets filtered because of a
        # changes value in an attribute e.g. In this case the filtered
        # item is not in the list at all and will not be sent on a POST
        # request. This will result in removing the relation!
        search = config.get_default_search()
        itemlist.filter(search)
        return itemlist
예제 #13
0
 def __init__(self, listing, tablename=None):
     self.listing = listing
     self.config = get_table_config(self.listing.clazz, tablename)
     self.template = template_lookup.get_template("internal/staticlist.mako")
예제 #14
0
파일: list_.py 프로젝트: mjsorribas/ringo
def get_search(clazz, request):
    """Returns a list of tuples with the search word and the fieldname.
    The function will first look if there is already a saved search in
    the session for the overview of the given clazz. If there is no
    previous search the start with an empty search stack.  The following
    behavior differs depending if it is a POST or GET request:

    1. GET
    Return either an empty search stack or return the saved stack in the
    session.

    2. POST
    Get the new submitted search. If the search is not already on the
    stack, then push it.  If the search word is empty, then pop the last
    search from the stack.  Finally return the modified stack.

    Please note the this function will not save the modified search
    stack in the session! This should be done elsewhere. E.g Depending
    if the search was successfull.
    """
    name = clazz.__tablename__
    # Default search fielter
    default_search = get_table_config(clazz).get_default_search()
    # Check if there is already a saved search in the session, If not
    # use the default search.
    saved_search = (request.session.get('%s.list.search' % name, [])
                    or default_search)

    regexpr = request.session.get('%s.list.search.regexpr' % name, False)
    if "enableregexpr" in request.params:
        request.session['%s.list.search.regexpr' % name] = True
        return saved_search
    elif "disableregexpr" in request.params:
        request.session['%s.list.search.regexpr' % name] = False
        return saved_search

    if 'reset' in request.params:
        return default_search

    # If the request is not a equest from the search form then
    # abort here and return the saved search params if there are any.
    form_name = request.params.get('form')
    if form_name != "search":
        return saved_search

    saved_search_id = request.params.get('saved')
    if saved_search_id:
        searches_dic = request.user.settings.get('searches', {})
        if searches_dic:
            searches_dic_search = searches_dic.get(name)
            if searches_dic_search:
                return searches_dic_search.get(saved_search_id, [[],
                                               [], None])[0]
    elif "save" in request.params:
        return saved_search
    elif "delete" in request.params:
        return saved_search
    else:
        search = request.params.get('search')
        search_field = request.params.get('field')

    # If search is empty try to pop the last filter in the saved search
    if search == "" and len(saved_search) > 0:
        popped = saved_search.pop()
        log.debug('Popping %s from search stack' % repr(popped))

    # Iterate over the saved search. If the search is not already in the
    # stack push it.
    if search != "":
        found = False
        for x in saved_search:
            if search == x[0] and search_field == x[1]:
                found = True
                break
        if not found:
            log.debug('Adding search for "%s" in field "%s"' % (search,
                                                                search_field))
            saved_search.append((search, search_field, regexpr))
    return saved_search
예제 #15
0
파일: base.py 프로젝트: toirl/ringo
    def filter(self, filter_stack):
        """This function will filter the items by only leaving
        those items in the list which match all search criteria in the
        filter stack. The number of items will get reduced with every
        iteration on the filter stack. The search is case sensitive.

        The filter stack is a list of tuples which describe the filter
        expression. Each tuple consists of three values:

        1. The search expression
        2. Optionally the name of the column on which the search will be
           applied.
        3. Boolean flag to indicate that the given search expression
           should be handled as a regular expression.

        The search support three modes. On default the search will look
        for the presence of the given search string within the values of
        the item. It will also match on parts of the string. So
        searching for 'Foo' will also match 'Foobar'. Another mode is
        using the search expression as a regular expression. The last
        mode makes use of special operators. The search supports the
        following operators: "<", "<=", "!=", ">" ">=" and "~" The
        operator can be provided with the search string.  It mus be the
        first word of the search expression. If a operator is present it
        will be used.

        The "~" operator will trigger a fuzzy search using the Double
        Metaphone algorithm for determining equal phonetics. If the
        phonetics do not match the Levenshtein distance will be
        calculated. 

        The search will iterate over all items in the list. For each
        item the function will try to match the value of either all, or
        from the configured search field with the regular expression or
        configured operator. If the value matches, then the item is kept
        in the list.

        :filter_stack: Filter stack
        :returns: Filtered list of items
        """
        self.search_filter = filter_stack
        log.debug('Length filterstack: %s' % len(filter_stack))
        table_config = get_table_config(self.clazz)
        table_columns = {}

        # Save cols in the tableconfig for later access while getting values.
        for col in table_config.get_columns():
            table_columns[col.get('name')] = col

        for search, search_field, regexpr in filter_stack:
            search_op = None
            # Get soperator
            x = search.split(" ")
            if x[0] in opmapping:
                search_op = x[0]
                search = " ".join(x[1:])
            # Build a regular expression
            if regexpr:
                re_expr = re.compile(search, re.IGNORECASE)
            else:
                re_expr = re.compile(re.escape(search), re.IGNORECASE)
            filtered_items = []
            log.debug('Filtering "%s" in "%s" with operator "%s" on %s items'
                      % (search, search_field, search_op, len(self.items)))
            if search_field != "":
                fields = [search_field]
            else:
                fields = table_columns.keys()
            for item in self.items:
                for field in fields:
                    expand = table_columns[field].get('expand')
                    value = item.get_value(field, expand=expand)
                    if isinstance(value, list):
                        value = ", ".join([unicode(x) for x in value])
                    else:
                        value = unicode(value)
                    if search_op:
                        if opmapping[search_op](value, search):
                            filtered_items.append(item)
                            break
                    else:
                        if re_expr.search(value):
                            filtered_items.append(item)
                            break
            self.items = filtered_items
예제 #16
0
파일: base.py 프로젝트: Intevation/ringo
    def filter(self, filter_stack, request=None, table="overview"):
        """This function will filter the items by only leaving
        those items in the list which match all search criteria in the
        filter stack. The number of items will get reduced with every
        iteration on the filter stack. The search is case sensitive.

        The filter stack is a list of tuples which describe the filter
        expression. Each tuple consists of three values:

        1. The search expression
        2. Optionally the name of the column on which the search will be
           applied.
        3. Boolean flag to indicate that the given search expression
           should be handled as a regular expression.

        The search support three modes. On default the search will look
        for the presence of the given search string within the values of
        the item. It will also match on parts of the string. So
        searching for 'Foo' will also match 'Foobar'. Another mode is
        using the search expression as a regular expression. The last
        mode makes use of special operators. The search supports the
        following operators: "<", "<=", "!=", ">" ">=" and "~" The
        operator can be provided with the search string.  It mus be the
        first word of the search expression. If a operator is present it
        will be used.

        The "~" operator will trigger a fuzzy search using the Double
        Metaphone algorithm for determining equal phonetics. If the
        phonetics do not match the Levenshtein distance will be
        calculated.

        The search will iterate over all items in the list. For each
        item the function will try to match the value of either all, or
        from the configured search field with the regular expression or
        configured operator. If the value matches, then the item is kept
        in the list.

        :filter_stack: Filter stack
        :request: Current request.
        :table: Name of the table config which is used for the search
                defaults to "overview".
        :returns: Filtered list of items
        """
        self.search_filter = filter_stack
        log.debug('Length filterstack: %s' % len(filter_stack))
        table_config = get_table_config(self.clazz, table)
        table_columns = {}

        # Save cols in the tableconfig for later access while getting values.
        for col in [
                col for col in table_config.get_columns()
                if col.get("searchable", True)
        ]:
            table_columns[col.get('name')] = col

        for search, search_field, regexpr in filter_stack:
            search_op = None
            # Get soperator
            x = search.split(" ")
            if x[0] in opmapping:
                search_op = x[0]
                search = " ".join(x[1:])
            # Build a regular expression
            if regexpr:
                re_expr = re.compile(search, re.IGNORECASE)
            else:
                re_expr = re.compile(re.escape(search), re.IGNORECASE)
            filtered_items = []
            log.debug('Filtering "%s" in "%s" with operator "%s" on %s items' %
                      (search, search_field, search_op, len(self.items)))
            if search_field != "":
                fields = [search_field]
            else:
                fields = table_columns.keys()
            for item in self.items:
                for field in fields:
                    expand = table_columns[field].get('expand')
                    renderer = table_config.get_renderer(table_columns[field])
                    if renderer:
                        value = renderer(request, item, field, table_config)
                    else:
                        value = item.get_value(field, expand=expand)
                    if hasattr(value, 'render'):
                        pretty_value = value.render(request)
                    elif isinstance(value, list):
                        if request and expand:
                            value = ", ".join(
                                [request.translate(unicode(v)) for v in value])
                        else:
                            value = ", ".join([unicode(v) for v in value])
                        pretty_value = value
                    else:
                        pretty_value = unicode(prettify(request, value))
                        if request and expand:
                            pretty_value = request.translate(pretty_value)
                    if search_op:
                        if request:
                            value = request.translate(unicode(value))
                        else:
                            value = unicode(value)
                        if opmapping[search_op](value, search):
                            filtered_items.append(item)
                            break
                    else:
                        if re_expr.search(pretty_value):
                            filtered_items.append(item)
                            break
            self.items = filtered_items
예제 #17
0
 def __init__(self, listing, tablename=None):
     """@todo: to be defined """
     self.listing = listing
     self.config = get_table_config(self.listing.clazz, tablename)
     self.template = template_lookup.get_template("internal/list.mako")
예제 #18
0
 def __init__(self, listing, tablename=None):
     self.listing = listing
     self.config = get_table_config(self.listing.clazz, tablename)
     self.template = template_lookup.get_template(
         "internal/staticlist.mako")
예제 #19
0
파일: lists.py 프로젝트: mjsorribas/ringo
 def __init__(self, listing):
     """@todo: to be defined """
     self.listing = listing
     self.config = get_table_config(self.listing.clazz)
     self.template = template_lookup.get_template("internal/list.mako")
예제 #20
0
def get_search(clazz, request):
    """Returns a list of tuples with the search word and the fieldname.
    The function will first look if there is already a saved search in
    the session for the overview of the given clazz. If there is no
    previous search the start with an empty search stack.  The following
    behavior differs depending if it is a POST or GET request:

    1. GET
    Return either an empty search stack or return the saved stack in the
    session.

    2. POST
    Get the new submitted search. If the search is not already on the
    stack, then push it.  If the search word is empty, then pop the last
    search from the stack.  Finally return the modified stack.

    Please note the this function will not save the modified search
    stack in the session! This should be done elsewhere. E.g Depending
    if the search was successfull.
    """
    name = clazz.__tablename__
    # Default search fielter
    default_search = get_table_config(clazz).get_default_search()
    # Check if there is already a saved search in the session, If not
    # use the default search.
    saved_search = (request.session.get('%s.list.search' % name, [])
                    or default_search)

    regexpr = request.session.get('%s.list.search.regexpr' % name, False)
    if "enableregexpr" in request.params:
        request.session['%s.list.search.regexpr' % name] = True
        return saved_search
    elif "disableregexpr" in request.params:
        request.session['%s.list.search.regexpr' % name] = False
        return saved_search

    if 'reset' in request.params:
        saved_search = []

    # If the request is not a equest from the search form then
    # abort here and return the saved search params if there are any.
    form_name = request.params.get('form')
    if form_name != "search":
        return saved_search

    saved_search_id = request.params.get('saved')
    if saved_search_id:
        searches_dic = request.user.settings.get('searches', {})
        if searches_dic:
            searches_dic_search = searches_dic.get(name)
            if searches_dic_search:
                return searches_dic_search.get(saved_search_id,
                                               [[], [], None])[0]
    elif "save" in request.params:
        return saved_search
    elif "delete" in request.params:
        return saved_search
    else:
        search = request.params.get('search')
        search_field = request.params.get('field')

    # If search is empty try to pop the last filter in the saved search
    if search == "" and len(saved_search) > 0:
        popped = saved_search.pop()
        log.debug('Popping %s from search stack' % repr(popped))

    # Iterate over the saved search. If the search is not already in the
    # stack push it.
    if search != "":
        found = False
        for x in saved_search:
            if search == x[0] and search_field == x[1]:
                found = True
                break
        if not found:
            log.debug('Adding search for "%s" in field "%s"' %
                      (search, search_field))
            if search:
                saved_search.append((search, search_field, regexpr))
    return saved_search