Example #1
0
def feed_from_annotations(
        annotations, atom_url, annotation_url, annotation_api_url=None,
        html_url=None, title=None, subtitle=None):
    """Return an Atom feed for the given list of annotations.

    :returns: A logical representation of an Atom feed as a Python dict
        containing all of the data that a template would need to render the
        feed to XML (including a list of dicts for the feed's entries).
    :rtype: dict

    """
    annotations = [presenters.AnnotationHTMLPresenter(a) for a in annotations]

    links = [{"rel": "self", "type": "application/atom+xml", "href": atom_url}]

    if html_url:
        links.append(
            {"rel": "alternate", "type": "text/html", "href": html_url})

    entries = [
        _feed_entry_from_annotation(a, annotation_url, annotation_api_url)
        for a in annotations]

    feed = {
        "id": atom_url,
        "title": title or _("Hypothesis Stream"),
        "subtitle": subtitle or _("The Web. Annotated"),
        "entries": entries,
        "links": links
    }

    if annotations:
        feed["updated"] = annotations[0]["updated"]

    return feed
Example #2
0
def feed_from_annotations(  # pylint: disable=too-many-arguments
    annotations, annotation_url, rss_url, html_url, title, description
):
    """
    Return an RSS feed for the given list of annotations.

    :returns: A logical representation of an RSS feed as a Python dict
        containing all of the data that a template would need to render the
        feed to XML (including a list of dicts for the feed's items).
    :rtype: dict

    """
    annotations = [presenters.AnnotationHTMLPresenter(a) for a in annotations]

    feed = {
        "title": title,
        "rss_url": rss_url,
        "html_url": html_url,
        "description": description,
        # This is called entries not items so as not to clash with the dict's
        # standard .items() method.
        "entries": [
            _feed_item_from_annotation(annotation, annotation_url)
            for annotation in annotations
        ],
    }

    if annotations:
        feed["pubDate"] = _pubdate_string(annotations[0].updated)

    return feed
Example #3
0
def feed_from_annotations(annotations, annotation_url, rss_url, html_url,
                          title, description):
    """Return an RSS feed for the given list of annotations.

    :returns: A logical representation of an RSS feed as a Python dict
        containing all of the data that a template would need to render the
        feed to XML (including a list of dicts for the feed's items).
    :rtype: dict

    """
    annotations = [presenters.AnnotationHTMLPresenter(a) for a in annotations]

    feed = {
        'title': title,
        'rss_url': rss_url,
        'html_url': html_url,
        'description': description,
        # This is called entries not items so as not to clash with the dict's
        # standard .items() method.
        'entries': [
            _feed_item_from_annotation(annotation, annotation_url)
            for annotation in annotations]
    }

    if annotations:
        feed['pubDate'] = parser.parse(annotations[0]['updated']).strftime(
            '%a, %d %b %Y %H:%M:%S %Z')

    return feed
Example #4
0
def execute(request, query, page_size):
    search_result = _execute_search(request, query, page_size)

    result = ActivityResults(total=search_result.total,
                             aggregations=search_result.aggregations,
                             timeframes=[])

    if result.total == 0:
        return result

    # Load all referenced annotations from the database, bucket them, and add
    # the buckets to result.timeframes.
    anns = _fetch_annotations(request.db, search_result.annotation_ids)
    result.timeframes.extend(bucketing.bucket(anns.all()))

    # Fetch all groups
    group_pubids = set([a.groupid
                        for t in result.timeframes
                        for b in t.document_buckets.values()
                        for a in b.annotations])
    groups = {g.pubid: g for g in _fetch_groups(request.db, group_pubids)}

    # Add group information to buckets and present annotations
    for timeframe in result.timeframes:
        for bucket in timeframe.document_buckets.values():
            for index, annotation in enumerate(bucket.annotations):
                bucket.annotations[index] = {
                    'annotation': presenters.AnnotationHTMLPresenter(annotation),
                    'group': groups.get(annotation.groupid)
                }

    return result
Example #5
0
    def _annotation(self, annotation=None, **kwargs):
        """Return an AnnotationHTMLPresenter for the given annotation.

        If no annotation is given a mock will be used, and any keyword
        arguments will be forwarded to the mock.Mock() constructor.

        """
        return presenters.AnnotationHTMLPresenter(annotation
                                                  or mock.Mock(**kwargs))
Example #6
0
    def test_it_does_not_crash_when_annotation_has_no_document(self):
        annotation = mock.Mock(document=None)
        presenter = presenters.AnnotationHTMLPresenter(annotation)

        # Some AnnotationHTMLPresenter properties rely on the annotation's
        # document. Call them all to make sure that none of them crash when
        # the document is None.
        # pylint: disable=pointless-statement
        presenter.document_link
        presenter.hostname_or_filename
        presenter.href
        presenter.link_text
        presenter.title
Example #7
0
def _read_group(request, group):
    """Return the rendered "Share this group" page.

    This is the page that's shown when a user who is already a member of a
    group visits the group's URL.

    """
    url = request.route_url('group_read', pubid=group.pubid, slug=group.slug)

    result = search.search(request,
                           private=False,
                           params={
                               "group": group.pubid,
                               "limit": 1000
                           })
    annotations = [
        presenters.AnnotationHTMLPresenter(storage.annotation_from_dict(a))
        for a in result['rows']
    ]

    # Group the annotations by URI.
    # Create a dict mapping the (normalized) URIs of the annotated documents
    # to the most recent annotation of each document.
    annotations_by_uri = collections.OrderedDict()
    for annotation in annotations:
        normalized_uri = uri.normalize(annotation.uri)
        if normalized_uri not in annotations_by_uri:
            annotations_by_uri[normalized_uri] = annotation
            if len(annotations_by_uri) >= 25:
                break

    document_links = [
        annotation.document_link for annotation in annotations_by_uri.values()
    ]

    template_data = {
        'group': group,
        'group_url': url,
        'document_links': document_links
    }

    return renderers.render_to_response(
        renderer_name='h:templates/groups/share.html.jinja2',
        value=template_data,
        request=request)
Example #8
0
def execute(request, query, page_size):
    search_result = _execute_search(request, query, page_size)

    result = ActivityResults(
        total=search_result.total,
        aggregations=search_result.aggregations,
        timeframes=[],
    )

    if result.total == 0:
        return result

    # Load all referenced annotations from the database, bucket them, and add
    # the buckets to result.timeframes.
    anns = fetch_annotations(request.db, search_result.annotation_ids)
    result.timeframes.extend(bucketing.bucket(anns))

    # Fetch all groups
    group_pubids = {
        a.groupid
        for t in result.timeframes for b in t.document_buckets.values()
        for a in b.annotations
    }
    groups = {g.pubid: g for g in _fetch_groups(request.db, group_pubids)}

    # Add group information to buckets and present annotations
    for timeframe in result.timeframes:
        for bucket in timeframe.document_buckets.values():
            bucket.presented_annotations = []
            for annotation in bucket.annotations:
                bucket.presented_annotations.append({
                    "annotation":
                    presenters.AnnotationHTMLPresenter(annotation),
                    "group":
                    groups.get(annotation.groupid),
                    "html_link":
                    links.html_link(request, annotation),
                    "incontext_link":
                    links.incontext_link(request, annotation),
                })

    return result
Example #9
0
    def test_it_does_not_init_DocumentHTMLPresenter_if_no_document(
            self, DocumentHTMLPresenter):
        """
        It shouldn't init DocumentHTMLPresenter if document is None.

        We don't want DocumentHTMLPresenter to be initialized with None for
        a document, so make sure that AnnotationHTMLPresenter doesn't do so.

        """
        annotation = mock.Mock(document=None)
        presenter = presenters.AnnotationHTMLPresenter(annotation)

        # Call all these as well to make sure that none of them cause a
        # DocumentHTMLPresenter to be initialized.
        # pylint: disable=pointless-statement
        presenter.document_link
        presenter.hostname_or_filename
        presenter.href
        presenter.link_text
        presenter.title

        assert not DocumentHTMLPresenter.called
Example #10
0
def execute(request, query, page_size):
    search_result = _execute_search(request, query, page_size)

    result = ActivityResults(total=search_result.total,
                             aggregations=search_result.aggregations,
                             timeframes=[])

    if result.total == 0:
        return result

    # Load all referenced annotations from the database, bucket them, and add
    # the buckets to result.timeframes.
    anns = fetch_annotations(request.db, search_result.annotation_ids)
    result.timeframes.extend(bucketing.bucket(anns))

    # Fetch all groups
    group_pubids = set([a.groupid
                        for t in result.timeframes
                        for b in t.document_buckets.values()
                        for a in b.annotations])
    groups = {g.pubid: g for g in _fetch_groups(request.db, group_pubids)}

    # Add group information to buckets and present annotations
    result.docs = dict()
    for timeframe in result.timeframes:
        for bucket in timeframe.document_buckets.values():
            bucket.presented_annotations = []
            for annotation in bucket.annotations:
                bucket.presented_annotations.append({
                    'annotation': presenters.AnnotationHTMLPresenter(annotation),
                    'group': groups.get(annotation.groupid),
                    'html_link': links.html_link(request, annotation),
                    'incontext_link': links.incontext_link(request, annotation)
                })
                # XXX: redo the bucketing, fake a bucket
                if annotation.document.title not in result.docs:
                    result.docs[annotation.document.title] = doc = lambda: None
                    doc.title = annotation.document.title
                    doc.annotations = []
                    doc.tags = set()
                    doc.users = set()
                    doc.annotations_count = 0
                    doc.incontext_link = types.MethodType(_incontext_link, doc)

                    presented_document = presenters.DocumentHTMLPresenter(annotation.document)

                    if presented_document.web_uri:
                        parsed = urlparse.urlparse(presented_document.web_uri)
                        doc.uri = parsed.geturl()
                        doc.domain = parsed.netloc
                    else:
                        doc.domain = _('Local file')

                doc = result.docs[annotation.document.title]
                doc.annotations.append(annotation)
                doc.tags.update(set(annotation.tags))
                doc.users.add(annotation.userid)
                doc.annotations_count += 1
    for key in result.docs:
        doc = result.docs[key]
        doc.annotations = sorted(doc.annotations, cmp=_sort_by_position)
        doc.presented_annotations = []
        for annotation in doc.annotations:
            doc.presented_annotations.append({
                'annotation': presenters.AnnotationHTMLPresenter(annotation),
                'group': groups.get(annotation.groupid),
                'html_link': links.html_link(request, annotation),
                'incontext_link': links.incontext_link(request, annotation)
            })

    return result
Example #11
0
def read_group(request, group, language=None, search_url=None, user=None, render=True):
    """
    Return the rendered "Share this group" page.

    This is the page that's shown when a user who is already a member of a group visits the group's URL.
    :param request: a request object
    :param group: a group object
    :param language: a language object to search or None
    :param search_url: the URL to search or None
    :param user: the user object to search or None
    :param render: whether or not to return a context object
    :return: if render, a context object for a template. If render is false, a list of annotations
    """

    if group is None:
        public_group_id = "__world__"
        slug = "Public"
    else:
        public_group_id = group.pubid
        slug = group.slug

    url = request.route_url('group_read', pubid=public_group_id, slug=slug)

    parameters = {"group": public_group_id, "limit": 1000}

    if language:
        parameters['language'] = language.pubid

    if search_url:
        parameters['uri'] = search_url

    if user:
        parameters['user'] = user

    result = search.search(request,
                           private=False,
                           params=parameters)

    annotations = [presenters.AnnotationHTMLPresenter(h.models.Annotation(a))
                   for a in result['rows']]

    if render:
        # Group the annotations by URI.
        # Create a dict mapping the (normalized) URIs of the annotated documents
        # to the most recent annotation of each document.
        annotations_by_uri = collections.OrderedDict()
        for annotation in annotations:
            normalized_uri = uri.normalize(annotation.uri)
            if normalized_uri not in annotations_by_uri:
                annotations_by_uri[normalized_uri] = annotation
                if len(annotations_by_uri) >= 25:
                    break

        document_links = [annotation.document_link
                          for annotation in annotations_by_uri.values()]

        template_data = {
            'group': group, 'group_url': url, 'document_links': document_links}

        return renderers.render_to_response(
            renderer_name='h:templates/groups/share.html.jinja2',
            value=template_data, request=request)
    else:
        return annotations