示例#1
0
    def detailed_author(cls, contributor):
        """Turn a Contributor into a detailed <author> tag."""
        children = []
        children.append(AtomFeed.name(contributor.display_name or ""))
        sort_name = AtomFeed.makeelement("{%s}sort_name" % AtomFeed.SIMPLIFIED_NS)
        sort_name.text = contributor.sort_name

        children.append(sort_name)

        if contributor.family_name:
            family_name = AtomFeed.makeelement(AtomFeed.schema_("family_name"))
            family_name.text = contributor.family_name
            children.append(family_name)

        if contributor.wikipedia_name:
            wikipedia_name = AtomFeed.makeelement(
                "{%s}wikipedia_name" % AtomFeed.SIMPLIFIED_NS)
            wikipedia_name.text = contributor.wikipedia_name
            children.append(wikipedia_name)

        if contributor.viaf:
            viaf_tag = AtomFeed.makeelement(AtomFeed.schema_("sameas"))
            viaf_tag.text = "http://viaf.org/viaf/%s" % contributor.viaf
            children.append(viaf_tag)

        if contributor.lc:
            lc_tag = AtomFeed.makeelement(AtomFeed.schema_("sameas"))
            lc_tag.text = "http://id.loc.gov/authorities/names/%s" % contributor.lc
            children.append(lc_tag)


        return AtomFeed.author(*children)
示例#2
0
 def rating_tag(cls, type_uri, value):
     """Generate a schema:Rating tag for the given type and value."""
     rating_tag = AtomFeed.makeelement(AtomFeed.schema_("Rating"))
     value_key = AtomFeed.schema_('ratingValue')
     rating_tag.set(value_key, "%.4f" % value)
     if type_uri:
         type_key = AtomFeed.schema_('additionalType')
         rating_tag.set(type_key, type_uri)
     return rating_tag
示例#3
0
 def series(cls, series_name, series_position):
     """Generate a schema:Series tag for the given name and position."""
     if not series_name:
         return None
     series_details = dict()
     series_details['name'] = series_name
     if series_position:
         series_details[AtomFeed.schema_('position')] = unicode(series_position)
     series_tag = AtomFeed.makeelement(AtomFeed.schema_("Series"), **series_details)
     return series_tag
示例#4
0
    def categories(cls, work):
        """Send out _all_ categories for the work.

        (So long as the category type has a URI associated with it in
        Subject.uri_lookup.)
        """
        _db = Session.object_session(work)
        by_scheme_and_term = dict()
        identifier_ids = work.all_identifier_ids()
        classifications = Identifier.classifications_for_identifier_ids(
            _db, identifier_ids)
        for c in classifications:
            subject = c.subject
            if subject.type in Subject.uri_lookup:
                scheme = Subject.uri_lookup[subject.type]
                term = subject.identifier
                weight_field = AtomFeed.schema_("ratingValue")
                key = (scheme, term)
                if not key in by_scheme_and_term:
                    value = dict(term=subject.identifier)
                    if subject.name:
                        value['label'] = subject.name
                    value[weight_field] = 0
                    by_scheme_and_term[key] = value
                by_scheme_and_term[key][weight_field] += c.weight

        # Collapse by_scheme_and_term to by_scheme
        by_scheme = defaultdict(list)
        for (scheme, term), value in by_scheme_and_term.items():
            by_scheme[scheme].append(value)
        by_scheme.update(super(VerboseAnnotator, cls).categories(work))
        return by_scheme
示例#5
0
    def _make_entry_xml(self, work, license_pool, edition, identifier,
                        lane_link):

        # Find the .epub link
        epub_href = None
        p = None

        links = []
        cover_quality = 0
        qualities = []
        if work:
            qualities.append(("Work quality", work.quality))
        full_url = None

        thumbnail_urls, full_urls = self.annotator.cover_links(work)
        for rel, urls in (
                (Hyperlink.IMAGE, full_urls),
                (Hyperlink.THUMBNAIL_IMAGE, thumbnail_urls)):
            for url in urls:
                image_type = "image/png"
                if url.endswith(".jpeg") or url.endswith(".jpg"):
                    image_type = "image/jpeg"
                elif url.endswith(".gif"):
                    image_type = "image/gif"
                links.append(AtomFeed.link(rel=rel, href=url, type=image_type))
           

        permalink = self.annotator.permalink_for(work, license_pool, identifier)
        content = self.annotator.content(work)
        if isinstance(content, str):
            content = content.decode("utf8")

        content_type = 'html'

        kw = {}
        if edition.medium:
            additional_type = Edition.medium_to_additional_type.get(
                edition.medium)
            if not additional_type:
                logging.warn("No additionalType for medium %s",
                             edition.medium)
            additional_type_field = AtomFeed.schema_("additionalType")
            kw[additional_type_field] = additional_type

        entry = AtomFeed.entry(
            AtomFeed.id(permalink),
            AtomFeed.title(edition.title or OPDSFeed.NO_TITLE),
            **kw
        )
        if edition.subtitle:
            subtitle_tag = AtomFeed.makeelement(AtomFeed.schema_("alternativeHeadline"))
            subtitle_tag.text = edition.subtitle
            entry.append(subtitle_tag)

        if license_pool:
            provider_name_attr = "{%s}ProviderName" % AtomFeed.BIBFRAME_NS
            kwargs = {provider_name_attr : license_pool.data_source.name}
            data_source_tag = AtomFeed.makeelement(
                "{%s}distribution" % AtomFeed.BIBFRAME_NS,
                **kwargs
            )
            entry.extend([data_source_tag])

        author_tags = self.annotator.authors(work, license_pool, edition, identifier)
        entry.extend(author_tags)

        if edition.series:
            entry.extend([self.annotator.series(edition.series, edition.series_position)])

        if content:
            entry.extend([AtomFeed.summary(content, type=content_type)])

        entry.extend([
            AtomFeed.updated(AtomFeed._strftime(datetime.datetime.utcnow())),
        ])

        permanent_work_id_tag = AtomFeed.makeelement("{%s}pwid" % AtomFeed.SIMPLIFIED_NS)
        permanent_work_id_tag.text = edition.permanent_work_id
        entry.append(permanent_work_id_tag)

        entry.extend(links)

        categories_by_scheme = self.annotator.categories(work)
        category_tags = []
        for scheme, categories in categories_by_scheme.items():
            for category in categories:
                if isinstance(category, basestring):
                    category = dict(term=category)
                category = dict(map(unicode, (k, v)) for k, v in category.items())
                category_tag = AtomFeed.category(scheme=scheme, **category)
                category_tags.append(category_tag)
        entry.extend(category_tags)

        # print " ID %s TITLE %s AUTHORS %s" % (tag, work.title, work.authors)
        language = edition.language_code
        if language:
            language_tag = AtomFeed.makeelement("{%s}language" % AtomFeed.DCTERMS_NS)
            language_tag.text = language
            entry.append(language_tag)

        if edition.publisher:
            publisher_tag = AtomFeed.makeelement("{%s}publisher" % AtomFeed.DCTERMS_NS)
            publisher_tag.text = edition.publisher
            entry.extend([publisher_tag])

        # We use Atom 'published' for the date the book first became
        # available to people using this application.
        now = datetime.datetime.utcnow()
        today = datetime.date.today()
        if license_pool and license_pool.availability_time:
            avail = license_pool.availability_time
            if isinstance(avail, datetime.datetime):
                avail = avail.date()
            if avail <= today:
                availability_tag = AtomFeed.makeelement("published")
                # TODO: convert to local timezone.
                availability_tag.text = AtomFeed._strftime(license_pool.availability_time)
                entry.extend([availability_tag])

        # Entry.issued is the date the ebook came out, as distinct
        # from Entry.published (which may refer to the print edition
        # or some original edition way back when).
        #
        # For Dublin Core 'created' we use Entry.issued if we have it
        # and Entry.published if not. In general this means we use
        # issued date for Gutenberg and published date for other
        # sources.
        #
        # We use dc:created instead of dc:issued because dc:issued is
        # commonly conflated with atom:published.
        #
        # For the date the book was added to our collection we use
        # atom:published.
        issued = edition.issued or edition.published
        if (isinstance(issued, datetime.datetime) 
            or isinstance(issued, datetime.date)):
            issued_already = False
            if isinstance(issued, datetime.datetime):
                issued_already = (issued <= now)
            elif isinstance(issued, datetime.date):
                issued_already = (issued <= today)
            if issued_already:
                issued_tag = AtomFeed.makeelement("{%s}created" % AtomFeed.DCTERMS_NS)
                # TODO: convert to local timezone, not that it matters much.
                issued_tag.text = issued.strftime("%Y-%m-%d")
                entry.extend([issued_tag])

        return entry
示例#6
0
    def categories(cls, work):
        """Return all relevant classifications of this work.

        :return: A dictionary mapping 'scheme' URLs to dictionaries of
        attribute-value pairs.

        Notable attributes: 'term', 'label', 'http://schema.org/ratingValue'
        """
        if not work:
            return {}

        categories = {}

        fiction_term = None
        if work.fiction == True:
            fiction_term = 'Fiction'
        elif work.fiction == False:
            fiction_term = 'Nonfiction'
        if fiction_term:
            fiction_scheme = Subject.SIMPLIFIED_FICTION_STATUS
            categories[fiction_scheme] = [
                dict(term=fiction_scheme + fiction_term,
                     label=fiction_term)
            ]

        simplified_genres = []
        for wg in work.work_genres:
            simplified_genres.append(wg.genre.name)

        if simplified_genres:
            categories[Subject.SIMPLIFIED_GENRE] = [
                dict(term=Subject.SIMPLIFIED_GENRE + urllib.quote(x),
                     label=x)
                for x in simplified_genres
            ]

        # Add the appeals as a category of schema
        # http://librarysimplified.org/terms/appeal
        schema_url = AtomFeed.SIMPLIFIED_NS + "appeals/"
        appeals = []
        categories[schema_url] = appeals
        for name, value in (
                (Work.CHARACTER_APPEAL, work.appeal_character),
                (Work.LANGUAGE_APPEAL, work.appeal_language),
                (Work.SETTING_APPEAL, work.appeal_setting),
                (Work.STORY_APPEAL, work.appeal_story),
        ):
            if value:
                appeal = dict(term=schema_url + name, label=name)
                weight_field = AtomFeed.schema_("ratingValue")
                appeal[weight_field] = value
                appeals.append(appeal)

        # Add the audience as a category of schema
        # http://schema.org/audience
        if work.audience:
            audience_uri = AtomFeed.SCHEMA_NS + "audience"
            categories[audience_uri] = [
                dict(term=work.audience, label=work.audience)
            ]

        if work.target_age:
            uri = Subject.uri_lookup[Subject.AGE_RANGE]
            target_age = work.target_age_string
            if target_age:
                categories[uri] = [dict(term=target_age, label=target_age)]

        return categories