Beispiel #1
0
def role_index():
    data = []
    classes = set()

    # Collect all models and roles in the default render registry
    for (cls, __) in html.registry:
        if not issubclass(cls, Model) or cls in classes:
            continue
        classes.add(cls)
        name = cls.__name__
        href = reverse("role-model", kwargs={"model": name.lower()})
        data.append((name, span([a(name, href=href), ": " + get_doc(cls)])))

    # Now we collect the queryset renderers
    classes = set()
    for (cls, __) in register_queryset.registry:
        classes.add(cls)
        name = cls.__name__
        href = reverse("role-model-queryset", kwargs={"model": name.lower()})
        data.append([
            name + " (queryset)",
            span([a(name, href=href), ": " + get_doc(cls)])
        ])

    return {"data": html_map(data)}
Beispiel #2
0
def role_index():
    data = []
    classes = set()

    # Collect all models and roles in the default render registry
    for (cls, __) in render.registry:
        if not issubclass(cls, Model) or cls in classes:
            continue
        classes.add(cls)
        name = cls.__name__
        href = reverse('role-model', kwargs={'model': name.lower()})
        data.append((name, span([a(name, href=href), ': ' + cls.__doc__])))

    # Now we collect the queryset renderers
    classes = set()
    for (cls, __) in register_queryset.registry:
        classes.add(cls)
        name = cls.__name__
        href = reverse('role-model-queryset', kwargs={'model': name.lower()})
        data.append([
            name + ' (queryset)',
            span([a(name, href=href), ': ' + cls.__doc__]),
        ])

    return {'data': html_map(data)}
 def _detail_links(request, conversation):
     if request.user.has_perm("ej.can_edit_conversation", conversation):
         return [
             a(_("Edit groups"), href=conversation.url("cluster:edit")),
             a(_("Manage personas"),
               href=conversation.url("cluster:stereotype-votes")),
         ]
     else:
         return []
Beispiel #4
0
def conversation_admin_menu_links(conversation, user):
    """
    Return administrative links to the conversation menu.
    """

    menu_links = []
    if user.has_perm("ej.can_edit_conversation", conversation):
        url = conversation.url("conversation:edit")
        menu_links.append(a(_("Edit"), href=url))
    if user.has_perm("ej.can_moderate_conversation", conversation):
        url = conversation.url("conversation:moderate")
        menu_links.append(a(_("Moderate"), href=url))
    return menu_links
Beispiel #5
0
def link(value,
         href='#',
         target='.Page-mainContainer',
         class_=(),
         action='target',
         instant=True,
         button=False,
         transition='cross-fade',
         preload=False,
         scroll=False,
         prefetch=False,
         primary=False,
         args=None):
    classes = [*class_]
    if button:
        classes.append('Button')

    kwargs = {
        'href': href,
        'class': classes,
        'primary': primary,
        'up-instant': instant,
        'up-restore-scroll': scroll,
        'up-preload': preload,
        'up-prefetch': prefetch,
    }
    if action:
        kwargs[f'up-{action}'] = target
    if transition:
        kwargs['up-transition'] = transition
    if args:
        for arg in args.split():
            kwargs[arg] = True
    return a(kwargs, value)
Beispiel #6
0
def conversation_comment_form(
    conversation, request=None, content=None, user=None, form=None, target=None
):
    """
    Render comment form for conversation.
    """
    # Check user credentials
    user = user or getattr(request, "user", None)
    if not user.is_authenticated:
        conversation_url = conversation.get_absolute_url()
        login = reverse("auth:login")
        return {
            "user": None,
            "login_anchor": a(_("login"), href=f"{login}?next={conversation_url}"),
        }

    # Check if user still have comments left
    n_comments = rules.compute("ej.remaining_comments", conversation, user)
    if conversation.author != user and n_comments <= 0:
        return {"comments_exceeded": True, "user": user}

    # Everything is ok, proceed ;)
    return {
        "user": user,
        "csrf_input": csrf_input(request),
        "n_comments": n_comments,
        "content": content,
        "target": target or "main",
        "form": form or forms.CommentForm(request=request, conversation=conversation),
    }
Beispiel #7
0
def index(request, conversation, slug, check=check_promoted):
    check(conversation, request)
    user = request.user
    clusterization = getattr(conversation, 'clusterization', None)

    if clusterization and clusterization.clusters.count() == 0:
        clusterization = None
    if clusterization is None:
        clusters = ()
        shapes_json = None
    else:
        clusters = (clusterization.clusters.annotate(
            size=Count(F.users)).annotate_attr(
                separated_comments=lambda c: c.separate_comments()).
                    prefetch_related("stereotypes"))
        shapes = cluster_shapes(clusterization, clusters, user)
        shapes_json = json.dumps({"shapes": list(shapes.values())})

    can_edit = user.has_perm("ej.can_edit_conversation", conversation)
    return {
        "conversation": conversation,
        "clusters": clusters,
        "groups":
        {cluster.name: f"#cluster-{cluster.id}"
         for cluster in clusters},
        "has_edit_perm": can_edit,
        "edit_link": a(_("here"), href=conversation.url("cluster:edit")),
        "json_data": shapes_json,
    }
Beispiel #8
0
def comment_card(
    comment: Comment, request=None, target=None, show_actions=None, **kwargs
):
    """
    Render comment information inside a comment card.
    """

    user = getattr(request, "user", None)
    is_authenticated = getattr(user, "is_authenticated", False)

    if is_authenticated:
        login_anchor = None
    else:
        login = reverse("auth:login")
        login_anchor = a(
            _("login"), href=f"{login}?next={comment.conversation.get_absolute_url()}"
        )

    buttons = {
        "disagree": ("fa-times", "text-negative", _("Disagree")),
        "skip": ("fa-arrow-right", "text-black", _("Skip")),
        "agree": ("fa-check", "text-positive", _("Agree")),
    }

    return {
        "author": comment.author.username,
        "comment": comment,
        "show_actions": is_authenticated,
        "csrf_input": csrf_input(request),
        "buttons": buttons,
        "login_anchor": login_anchor,
        "target": target,
        **kwargs,
    }
Beispiel #9
0
    def link_tag(self, classes=(), icon_classes=()):
        """
        Render an anchor tag with the link for the social network.

        >>> print(icon.link_tag(classes=['header-icon']))       # doctest: +SKIP
        <a href="url"><i class="fa fa-icon header-icon"></i></a>
        """
        return a(href=self.url, class_=classes)[self.icon_tag(icon_classes)]
Beispiel #10
0
    def anchor(self, name, **kwargs):
        """
        Return an Hyperpython anchor object using url as href.

        It must pass the anchor contents as the first argument. It also accepts
        a additional attributes as keyword arguments.
        """
        return a(name, href=self.url, **kwargs)
Beispiel #11
0
def role_model_list(request, model, role):
    cls = get_class(model)
    kwargs = query_to_kwargs(request)
    size = kwargs.pop("size", 10)
    data = []
    for idx, obj in enumerate(cls.objects.all()[:size], 1):
        link = reverse("role-model-instance", kwargs={"model": model, "role": role, "id": obj.id})
        key = span([f"{idx}) ", a(str(obj), href=link)])
        data.append((key, html(obj, role, **kwargs)))

    return {"data": html_map(data)}
Beispiel #12
0
def role_model(model):
    links = []
    cls = get_class(model)
    for role in get_roles(cls):
        href = reverse("role-model-list", kwargs={"model": model, "role": role})
        links.append(a(role, href=href))

    if not links:
        raise Http404
    else:
        return {"data": div([h1(_("List of roles")), html_list(links)])}
Beispiel #13
0
def role_model_list(request, model, role):
    cls = get_class(model)
    kwargs = query_to_kwargs(request)
    size = kwargs.pop('size', 10)
    data = []
    for idx, obj in enumerate(cls.objects.all()[:size], 1):
        link = reverse('role-model-instance',
                       kwargs={'model': model, 'role': role, 'id': obj.id})
        key = span([f'{idx}) ', a(str(obj), href=link)])
        data.append((key, html(obj, role, **kwargs)))

    return {'data': html_map(data)}
Beispiel #14
0
def stereotype_list(conversation):
    base_href = f'{conversation.get_absolute_url()}stereotypes/'
    return {
        'content_title':
        _('Stereotypes'),
        'conversation':
        conversation,
        'stereotypes':
        html_list(
            a(str(stereotype), href=f'{base_href}{stereotype.id}/')
            for stereotype in conversation.stereotypes.all()),
    }
Beispiel #15
0
def role_model(model):
    links = []
    cls = get_class(model)
    for role in get_roles(cls):
        href = reverse('role-model-list',
                       kwargs={'model': model, 'role': role})
        links.append(a(role, href=href))

    if not links:
        raise Http404
    else:
        return {'data': div([h1(_('List of roles')), html_list(links)])}
Beispiel #16
0
def index(request, conversation, slug, check=check_promoted):
    check(conversation, request)
    user = request.user
    clusterization = getattr(conversation, "clusterization", None)
    user_group = None

    if clusterization and clusterization.clusters.count() == 0:
        clusterization = None
    if clusterization is None:
        clusters = ()
        shapes_json = None
    else:
        try:
            clusters = (clusterization.clusters.annotate(
                size=Count(F.users)).annotate_attr(
                    separated_comments=lambda c: c.separate_comments()).
                        prefetch_related("stereotypes"))
            shapes = cluster_shapes(clusterization, clusters, user)
            shapes_json = json.dumps({"shapes": list(shapes.values())})
        except Exception as exc:
            exc_name = exc.__class__.__name__
            log.error(f"Error found during clusterization: {exc} ({exc_name})")
            clusters = ()
            shapes_json = {
                "shapes": [{
                    "name": _("Error"),
                    "size": 0,
                    "intersections": [[0.0]]
                }]
            }
        else:
            names = list(
                clusterization.clusters.filter(users=user).values_list(
                    "name", flat=True))
            print(names)
            if names:
                user_group = names[0]

    can_edit = user.has_perm("ej.can_edit_conversation", conversation)
    return {
        "conversation": conversation,
        "clusters": clusters,
        "groups":
        {cluster.name: f"#cluster-{cluster.id}"
         for cluster in clusters},
        "has_edit_perm": can_edit,
        "edit_link": a(_("here"), href=conversation.url("cluster:edit")),
        "json_data": shapes_json,
        "user_group": user_group,
    }
Beispiel #17
0
def button(
    text,
    *,
    href=None,
    submit=False,
    reset=False,
    form=False,
    outline=False,
    clear=False,
    **kwargs,
):
    """
    A styled button element.

    Args:
        text (str or HTML element):
            Text content of the button.
        href (str):
            Optional hyperlink target. If given, the button is create as an
            anchor tag.
        submit (bool):
            If True, renders element as an <input type='submit'> element.
        reset (bool):
            If True, renders element as an <input type='reset'> element.
        form (bool):
            If True, renders element as an <input type='button'> element.
        outline (bool):
            If True, paints only the outline.
        clear:
            If True, renders a plain-text button with no background color or
            outline.

        ``button`` also accepts additional HTML attributes as keyword arguments.
    """
    classes = ["button"]
    if clear:
        classes.append("button-clear")
    if outline:
        classes.append("button-outline")

    if href:
        return hp.a(text, href=href, **kwargs).add_class(classes)
    elif submit or reset or form:
        if not isinstance(text, (str, int, float)):
            raise ValueError("submit inputs do not accept rich element children.")
        kind = "submit" if submit else "reset" if reset else "button"
        return hp.input_(value=text, type=kind, **kwargs).add_class(classes)
    else:
        return hp.button(text, **kwargs).add_class(classes)
Beispiel #18
0
def tabs(items, select=0, js=True, **kwargs):
    """
    Return a tabbed interface.
    """
    items = items.items() if isinstance(items, Mapping) else items
    children = []
    if js:
        kwargs["is-component"] = True

    for idx, (k, v) in enumerate(items):
        args = {"href": v} if isinstance(v, str) else v
        anchor = a(args, k, is_selected=select == idx)
        children.append(anchor)

    return div(children, **kwargs).add_class("tabs", first=True)
Beispiel #19
0
def comment_form(conversation, request=None, comment_content=None, **kwargs):
    """
    Render comment form for one conversation.
    """
    user = getattr(request, 'user', None)
    n_comments = rules.compute('ej_conversations.remaining_comments', conversation, user)
    conversation_url = conversation.get_absolute_url()
    login = reverse('auth:login')
    login_anchor = a(_('login'), href=f'{login}?next={conversation_url}')
    return {
        'can_comment': user.is_authenticated,
        'comments_left': n_comments,
        'user_is_owner': conversation.author == user,
        'csrf_input': csrf_input(request),
        'comment_content': comment_content,
        'login_anchor': login_anchor,
    }
Beispiel #20
0
def link(value,
         href='#',
         target='.Page-mainContainer .Header-topIcon',
         action='target',
         instant=True,
         button=False,
         transition='cross-fade',
         preload=False,
         scroll=False,
         prefetch=False,
         primary=False,
         args=None,
         query=None,
         url_args=None,
         **kwargs):
    if href.startswith('/'):
        # raise ValueError(href)
        warnings.warn(
            'Do not use absolute urls in the link function (%s).'
            'Prefer using view function names such as auth:login instead of '
            '/login/' % href)
    else:
        href = reverse(href, kwargs=url_args)
    if query is not None:
        query = '&'.join(f'{k}={v}' for k, v in query.items())
        href = f'{href}?{query}'

    kwargs = {
        'href': href,
        'primary': primary,
        'up-instant': instant,
        'up-restore-scroll': scroll,
        'up-preload': preload,
        'up-prefetch': prefetch,
        **kwargs,
    }
    if action:
        kwargs[f'up-{action}'] = target
    if transition:
        kwargs['up-transition'] = transition
    if args:
        for arg in args.split():
            kwargs[arg] = True
    elem = a(kwargs, value)
    return elem.add_class('Button') if button else elem
Beispiel #21
0
def detail(request, conversation, owner=None):
    user = request.user
    comment = conversation.next_comment(user, None)
    n_comments = rules.compute('ej_conversations.remaining_comments',
                               conversation, user)
    favorites = FavoriteConversation.objects.filter(conversation=conversation)
    ctx = {
        'conversation':
        conversation,
        'comment':
        comment,
        'owner':
        owner,
        'edit_perm':
        user.has_perm('ej_conversations.can_edit_conversation', conversation),
        'can_comment':
        user.has_perm('ej_conversations.can_comment', conversation),
        'remaining_comments':
        n_comments,
        'login_link':
        a(_('login'), href=reverse('auth:login')),
        'favorites':
        favorites,
    }

    if comment and request.POST.get('action') == 'vote':
        vote = request.POST['vote']
        if vote not in {'agree', 'skip', 'disagree'}:
            return HttpResponseServerError('invalid parameter')
        comment.vote(user, vote)

    elif request.POST.get('action') == 'comment':
        comment = request.POST['comment'].strip()

        # FIXME: do not hardcode this and use a proper form!
        comment = comment[:210]
        try:
            ctx['comment'] = conversation.create_comment(user, comment)
        except (PermissionError, ValidationError) as ex:
            ctx['comment_error'] = str(ex)
    elif request.POST.get('action') == 'favorite':
        conversation.toggle_favorite(user)
    return ctx
Beispiel #22
0
def cluster_info(cluster):
    stereotypes = cluster.stereotypes.all()
    user_data = [(user.username, user.name) for user in cluster.users.all()]
    return {
        'size':
        cluster.users.count(),
        'stereotypes':
        stereotypes,
        'stereotype_links': [
            a(str(stereotype),
              href=reverse('cluster:stereotype-vote',
                           kwargs={
                               'conversation': cluster.conversation,
                               'stereotype': stereotype,
                           })) for stereotype in stereotypes
        ],
        'users':
        html_table(user_data, columns=[_('Username'), _('Name')])
    }
Beispiel #23
0
def categories(items, select=0, js=True, **kwargs):
    """
    Similar to tabs, but display several categories for the user to select.
    """
    items = items.items() if isinstance(items, Mapping) else items
    children = [
        icon("chevron-left", class_="categories__left", is_element="leftArrow:click")
    ]
    if js:
        kwargs["is-component"] = True

    for idx, (k, v) in enumerate(items):
        args = {"href": v} if isinstance(v, str) else v
        if select == idx or select == v:
            args["is-selected"] = True
        children.append(a(args, k))
    children.append(
        icon("chevron-right", class_="categories_right", is_element="rightArrow:click")
    )

    return div(children, **kwargs).add_class("categories", first=True)
Beispiel #24
0
def link(value, href='#', target='.Page-mainContainer .Header-topIcon',
         action='target', instant=True, button=False, transition='cross-fade',
         preload=False, scroll=False, prefetch=False, primary=False, args=None,
         **kwargs):
    kwargs = {
        'href': href,
        'primary': primary,
        'up-instant': instant,
        'up-restore-scroll': scroll,
        'up-preload': preload,
        'up-prefetch': prefetch,
        **kwargs,
    }
    if action:
        kwargs[f'up-{action}'] = target
    if transition:
        kwargs['up-transition'] = transition
    if args:
        for arg in args.split():
            kwargs[arg] = True
    elem = a(kwargs, value)
    return elem.add_class('Button') if button else elem
Beispiel #25
0
def comment_card(comment, request=None, **kwargs):
    """
    Render comment information inside a comment card.
    """

    user = getattr(request, 'user', None)
    is_authenticated = getattr(user, 'is_authenticated', False)
    total = comment.conversation.approved_comments.count()
    remaining = total - comment.conversation.user_votes(user).count()
    voted = total - remaining + 1

    login = reverse('auth:login')
    comment_url = comment.conversation.get_absolute_url()
    login_anchor = a(_('login'), href=f'{login}?next={comment_url}')
    return {
        'comment': comment,
        'total': total,
        'voted': voted,
        'show_user_actions': is_authenticated,
        'csrf_input': csrf_input(request),
        'login_anchor': login_anchor,
        **kwargs,
    }
Beispiel #26
0
def login_link(content, obj):
    path = obj.get_absolute_url()
    return a(content, href=reverse('auth:login') + f'?next={path}')
Beispiel #27
0
def _tab_anchors(items, select):
    items = items.items() if isinstance(items, Mapping) else items
    for idx, (k, v) in enumerate(items):
        args = {"href": v} if isinstance(v, str) else v
        args.update(role="tab", tabindex=0, is_selected=select == idx)
        yield a(k, **args)
Beispiel #28
0
    (which can be None) pertaining to that section. Ex.: in a route that
    configures the user profile, that object can be the profile object for the
    request user.
    """
    return lambda f: MENU_FUNCTIONS[section].append(f) or f


# Storage
MENU_FUNCTIONS = defaultdict(list)

#: Accessibility menu
page_menu.ACCESSIBILITY = thunk(lambda: menu_section(
    _("Accessibility"),
    [
        a([fa_icon("text-height"),
           _("Toggle Font Size")],
          href="#",
          is_element="toggleFontSize"),
        a([fa_icon("adjust"), _("Toggle Contrast")],
          href="#",
          is_element="toggleContrast"),
    ],
))

#: About menu
page_menu._ABOUT = thunk(lambda: menu_section(
    _("About"),
    [
        link(_("About"), href="about-us"),
        link(_("Frequently Asked Questions"), href="faq"),
        link(_("Usage terms"), href="usage"),
    ],
Beispiel #29
0
 def a(self):
     return a(class_='cls', href='url')['click me']
Beispiel #30
0
 def a(self):
     return a(class_='cls1 cls2', id='id', href='url')['click me']