Пример #1
0
    def show_details(self, index):
        f = rating_font()
        book = self.model().data(index, Qt.UserRole)
        parts = [
            '<center>',
            '<h2>%s</h2>'%book.title,
            '<div><i>%s</i></div>'%authors_to_string(book.authors),
        ]
        if not book.is_null('series'):
            series = book.format_field('series')
            if series[1]:
                parts.append('<div>%s: %s</div>'%series)
        if not book.is_null('rating'):
            style = 'style=\'font-family:"%s"\''%f
            parts.append('<div %s>%s</div>'%(style, rating_to_stars(int(2 * book.rating))))
        parts.append('</center>')
        if book.identifiers:
            urls = urls_from_identifiers(book.identifiers)
            ids = ['<a href="%s">%s</a>'%(url, name) for name, ign, ign, url in urls]
            if ids:
                parts.append('<div><b>%s:</b> %s</div><br>'%(_('See at'), ', '.join(ids)))
        if book.tags:
            parts.append('<div>%s</div><div>\u00a0</div>'%', '.join(book.tags))
        if book.comments:
            parts.append(comments_to_html(book.comments))

        self.show_details_signal.emit(''.join(parts))
Пример #2
0
 def data(self, index, role=Qt.DisplayRole):
     if role == Qt.DisplayRole:
         val = index.row() * (1 if self.is_half_star else 2)
         return rating_to_stars(val, self.is_half_star) or self.null_text
     if role == Qt.FontRole:
         return QApplication.instance().font() if index.row(
         ) == 0 else self.rating_font
Пример #3
0
    def show_details(self, index):
        f = rating_font()
        book = self.model().data(index, Qt.UserRole)
        parts = [
            '<center>',
            '<h2>%s</h2>' % book.title,
            '<div><i>%s</i></div>' % authors_to_string(book.authors),
        ]
        if not book.is_null('series'):
            series = book.format_field('series')
            if series[1]:
                parts.append('<div>%s: %s</div>' % series)
        if not book.is_null('rating'):
            style = 'style=\'font-family:"%s"\'' % f
            parts.append('<div %s>%s</div>' %
                         (style, rating_to_stars(int(2 * book.rating))))
        parts.append('</center>')
        if book.identifiers:
            urls = urls_from_identifiers(book.identifiers)
            ids = [
                '<a href="%s">%s</a>' % (url, name)
                for name, ign, ign, url in urls
            ]
            if ids:
                parts.append('<div><b>%s:</b> %s</div><br>' %
                             (_('See at'), ', '.join(ids)))
        if book.tags:
            parts.append('<div>%s</div><div>\u00a0</div>' %
                         ', '.join(book.tags))
        if book.comments:
            parts.append(comments_to_html(book.comments))

        self.show_details_signal.emit(''.join(parts))
Пример #4
0
 def subtitle(self, index):
     if gprefs['show_rating_in_cover_browser']:
         try:
             return rating_to_stars(self.model.rating(index) * 2)
         except:
             pass
     return ''
Пример #5
0
 def subtitle(self, index):
     try:
         db = self.model.db.new_api
         if not self.template_inited:
             self.init_template(db)
         field = db.pref('cover_browser_subtitle_field', 'rating')
         if field and field != 'none':
             book_id = self.model.id(index)
             fm = db.field_metadata[field]
             if fm['datatype'] == 'rating':
                 val = db.field_for(field, book_id, default_value=0)
                 if val:
                     return rating_to_stars(
                         val,
                         allow_half_stars=db.field_metadata[field]
                         ['display'].get('allow_half_stars'))
             else:
                 return self.render_template('{%s}' % field, index,
                                             db).replace('&', '&&')
     except Exception:
         if not self.subtitle_error_reported:
             self.subtitle_error_reported = True
             import traceback
             traceback.print_exc()
     return ''
Пример #6
0
def ACQUISITION_ENTRY(book_id, updated, request_context):
    field_metadata = request_context.db.field_metadata
    mi = request_context.db.get_metadata(book_id)
    extra = []
    if (mi.rating or 0) > 0:
        rating = rating_to_stars(mi.rating)
        extra.append(_('RATING: %s<br />')%rating)
    if mi.tags:
        extra.append(_('TAGS: %s<br />')%xml(format_tag_string(mi.tags, None)))
    if mi.series:
        extra.append(_('SERIES: %(series)s [%(sidx)s]<br />')%
                dict(series=xml(mi.series),
                sidx=fmt_sidx(float(mi.series_index))))
    for key in filter(request_context.ctx.is_field_displayable, field_metadata.ignorable_field_keys()):
        name, val = mi.format_field(key)
        if val:
            fm = field_metadata[key]
            datatype = fm['datatype']
            if datatype == 'text' and fm['is_multiple']:
                extra.append('%s: %s<br />'%
                             (xml(name),
                              xml(format_tag_string(val,
                                    fm['is_multiple']['ui_to_list'],
                                    joinval=fm['is_multiple']['list_to_ui']))))
            elif datatype == 'comments' or (fm['datatype'] == 'composite' and fm['display'].get('contains_html', False)):
                extra.append('%s: %s<br />'%(xml(name), comments_to_html(str(val))))
            else:
                extra.append('%s: %s<br />'%(xml(name), xml(str(val))))
    if mi.comments:
        comments = comments_to_html(mi.comments)
        extra.append(comments)
    if extra:
        extra = html_to_lxml('\n'.join(extra))
    ans = E.entry(TITLE(mi.title), E.author(E.name(authors_to_string(mi.authors))), ID('urn:uuid:' + mi.uuid), UPDATED(mi.last_modified),
                  E.published(mi.timestamp.isoformat()))
    if mi.pubdate and not is_date_undefined(mi.pubdate):
        ans.append(ans.makeelement('{%s}date' % DC_NS))
        ans[-1].text = mi.pubdate.isoformat()
    if len(extra):
        ans.append(E.content(extra, type='xhtml'))
    get = partial(request_context.ctx.url_for, '/get', book_id=book_id, library_id=request_context.library_id)
    if mi.formats:
        fm = mi.format_metadata
        for fmt in mi.formats:
            fmt = fmt.lower()
            mt = guess_type('a.'+fmt)[0]
            if mt:
                link = E.link(type=mt, href=get(what=fmt), rel="http://opds-spec.org/acquisition")
                ffm = fm.get(fmt.upper())
                if ffm:
                    link.set('length', str(ffm['size']))
                    link.set('mtime', ffm['mtime'].isoformat())
                ans.append(link)
    ans.append(E.link(type='image/jpeg', href=get(what='cover'), rel="http://opds-spec.org/cover"))
    ans.append(E.link(type='image/jpeg', href=get(what='thumb'), rel="http://opds-spec.org/thumbnail"))
    ans.append(E.link(type='image/jpeg', href=get(what='cover'), rel="http://opds-spec.org/image"))
    ans.append(E.link(type='image/jpeg', href=get(what='thumb'), rel="http://opds-spec.org/image/thumbnail"))

    return ans
Пример #7
0
def ACQUISITION_ENTRY(book_id, updated, request_context):
    field_metadata = request_context.db.field_metadata
    mi = request_context.db.get_metadata(book_id)
    extra = []
    if mi.rating > 0:
        rating = rating_to_stars(mi.rating)
        extra.append(_('RATING: %s<br />')%rating)
    if mi.tags:
        extra.append(_('TAGS: %s<br />')%xml(format_tag_string(mi.tags, None)))
    if mi.series:
        extra.append(_('SERIES: %(series)s [%(sidx)s]<br />')%
                dict(series=xml(mi.series),
                sidx=fmt_sidx(float(mi.series_index))))
    for key in filter(request_context.ctx.is_field_displayable, field_metadata.ignorable_field_keys()):
        name, val = mi.format_field(key)
        if val:
            fm = field_metadata[key]
            datatype = fm['datatype']
            if datatype == 'text' and fm['is_multiple']:
                extra.append('%s: %s<br />'%
                             (xml(name),
                              xml(format_tag_string(val,
                                    fm['is_multiple']['ui_to_list'],
                                    joinval=fm['is_multiple']['list_to_ui']))))
            elif datatype == 'comments' or (fm['datatype'] == 'composite' and
                            fm['display'].get('contains_html', False)):
                extra.append('%s: %s<br />'%(xml(name), comments_to_html(unicode(val))))
            else:
                extra.append('%s: %s<br />'%(xml(name), xml(unicode(val))))
    if mi.comments:
        comments = comments_to_html(mi.comments)
        extra.append(comments)
    if extra:
        extra = html_to_lxml('\n'.join(extra))
    ans = E.entry(TITLE(mi.title), E.author(E.name(authors_to_string(mi.authors))), ID('urn:uuid:' + mi.uuid), UPDATED(mi.last_modified),
                  E.published(mi.timestamp.isoformat()))
    if mi.pubdate and not is_date_undefined(mi.pubdate):
        ans.append(ans.makeelement('{%s}date' % DC_NS))
        ans[-1].text = mi.pubdate.isoformat()
    if len(extra):
        ans.append(E.content(extra, type='xhtml'))
    get = partial(request_context.ctx.url_for, '/get', book_id=book_id, library_id=request_context.library_id)
    if mi.formats:
        fm = mi.format_metadata
        for fmt in mi.formats:
            fmt = fmt.lower()
            mt = guess_type('a.'+fmt)[0]
            if mt:
                link = E.link(type=mt, href=get(what=fmt), rel="http://opds-spec.org/acquisition")
                ffm = fm.get(fmt.upper())
                if ffm:
                    link.set('length', str(ffm['size']))
                    link.set('mtime', ffm['mtime'].isoformat())
                ans.append(link)
    ans.append(E.link(type='image/jpeg', href=get(what='cover'), rel="http://opds-spec.org/cover"))
    ans.append(E.link(type='image/jpeg', href=get(what='thumb'), rel="http://opds-spec.org/thumbnail"))

    return ans
Пример #8
0
    def __init__(self, name, table, bools_are_tristate,
                 get_template_functions):
        self.name, self.table = name, table
        dt = self.metadata['datatype']
        self.has_text_data = dt in {
            'text', 'comments', 'series', 'enumeration'
        }
        self.table_type = self.table.table_type
        self._sort_key = (sort_key if dt in ('text', 'series',
                                             'enumeration') else IDENTITY)

        # This will be compared to the output of sort_key() which is a
        # bytestring, therefore it is safer to have it be a bytestring.
        # Coercing an empty bytestring to unicode will never fail, but the
        # output of sort_key cannot be coerced to unicode
        self._default_sort_key = b''

        if dt in {'int', 'float', 'rating'}:
            self._default_sort_key = 0
            self._sort_key = numeric_sort_key
        elif dt == 'bool':
            self._default_sort_key = None
            self._sort_key = bool_sort_key(bools_are_tristate)
        elif dt == 'datetime':
            self._default_sort_key = UNDEFINED_DATE
            if tweaks['sort_dates_using_visible_fields']:
                fmt = None
                if name in {'timestamp', 'pubdate', 'last_modified'}:
                    fmt = tweaks['gui_%s_display_format' % name]
                elif self.metadata['is_custom']:
                    fmt = self.metadata.get('display',
                                            {}).get('date_format', None)
                self._sort_key = partial(clean_date_for_sort, fmt=fmt)
        elif dt == 'comments' or name == 'identifiers':
            self._default_sort_key = ''

        if self.name == 'languages':
            self._sort_key = lambda x: sort_key(calibre_langcode_to_name(x))
        self.is_multiple = (bool(self.metadata['is_multiple'])
                            or self.name == 'formats')
        self.sort_sort_key = True
        if self.is_multiple and '&' in self.metadata['is_multiple'][
                'list_to_ui']:
            self._sort_key = lambda x: sort_key(author_to_author_sort(x))
            self.sort_sort_key = False
        self.default_value = {} if name == 'identifiers' else (
        ) if self.is_multiple else None
        self.category_formatter = unicode_type
        if dt == 'rating':
            if self.metadata['display'].get('allow_half_stars', False):
                self.category_formatter = lambda x: rating_to_stars(x, True)
            else:
                self.category_formatter = rating_to_stars
        elif name == 'languages':
            self.category_formatter = calibre_langcode_to_name
        self.writer = Writer(self)
        self.series_field = None
        self.get_template_functions = get_template_functions
Пример #9
0
    def __init__(self, name, table, bools_are_tristate, get_template_functions):
        self.name, self.table = name, table
        dt = self.metadata['datatype']
        self.has_text_data = dt in {'text', 'comments', 'series', 'enumeration'}
        self.table_type = self.table.table_type
        self._sort_key = (sort_key if dt in ('text', 'series', 'enumeration') else IDENTITY)

        # This will be compared to the output of sort_key() which is a
        # bytestring, therefore it is safer to have it be a bytestring.
        # Coercing an empty bytestring to unicode will never fail, but the
        # output of sort_key cannot be coerced to unicode
        self._default_sort_key = b''

        if dt in {'int', 'float', 'rating'}:
            self._default_sort_key = 0
        elif dt == 'bool':
            self._default_sort_key = None
            self._sort_key = bool_sort_key(bools_are_tristate)
        elif dt == 'datetime':
            self._default_sort_key = UNDEFINED_DATE
            if tweaks['sort_dates_using_visible_fields']:
                fmt = None
                if name in {'timestamp', 'pubdate', 'last_modified'}:
                    fmt = tweaks['gui_%s_display_format' % name]
                elif self.metadata['is_custom']:
                    fmt = self.metadata.get('display', {}).get('date_format', None)
                self._sort_key = partial(clean_date_for_sort, fmt=fmt)
        elif dt == 'comments' or name == 'identifiers':
            self._default_sort_key = ''

        if self.name == 'languages':
            self._sort_key = lambda x:sort_key(calibre_langcode_to_name(x))
        self.is_multiple = (bool(self.metadata['is_multiple']) or self.name ==
                'formats')
        self.sort_sort_key = True
        if self.is_multiple and '&' in self.metadata['is_multiple']['list_to_ui']:
            self._sort_key = lambda x: sort_key(author_to_author_sort(x))
            self.sort_sort_key = False
        self.default_value = {} if name == 'identifiers' else () if self.is_multiple else None
        self.category_formatter = unicode_type
        if dt == 'rating':
            if self.metadata['display'].get('allow_half_stars', False):
                self.category_formatter = lambda x: rating_to_stars(x, True)
            else:
                self.category_formatter = rating_to_stars
        elif name == 'languages':
            self.category_formatter = calibre_langcode_to_name
        self.writer = Writer(self)
        self.series_field = None
        self.get_template_functions = get_template_functions
Пример #10
0
 def render_field(self, db, book_id):
     is_stars = False
     try:
         field = db.pref('field_under_covers_in_grid', 'title')
         if field == 'size':
             ans = human_readable(db.field_for(field, book_id, default_value=0))
         else:
             mi = db.get_proxy_metadata(book_id)
             display_name, ans, val, fm = mi.format_field_extended(field)
             if fm and fm['datatype'] == 'rating':
                 ans = rating_to_stars(val, fm['display'].get('allow_half_stars', False))
                 is_stars = True
         return ('' if ans is None else unicode_type(ans)), is_stars
     except Exception:
         if DEBUG:
             import traceback
             traceback.print_exc()
     return '', is_stars
Пример #11
0
 def render_field(self, db, book_id):
     is_stars = False
     try:
         field = db.pref('field_under_covers_in_grid', 'title')
         if field == 'size':
             ans = human_readable(db.field_for(field, book_id, default_value=0))
         else:
             mi = db.get_proxy_metadata(book_id)
             display_name, ans, val, fm = mi.format_field_extended(field)
             if fm and fm['datatype'] == 'rating':
                 ans = rating_to_stars(val, fm['display'].get('allow_half_stars', False))
                 is_stars = True
         return ('' if ans is None else unicode_type(ans)), is_stars
     except Exception:
         if DEBUG:
             import traceback
             traceback.print_exc()
     return '', is_stars
Пример #12
0
 def subtitle(self, index):
     try:
         db = self.model.db.new_api
         field = db.pref('cover_browser_subtitle_field', 'rating')
         if field and field != 'none':
             book_id = self.model.id(index)
             fm = db.field_metadata[field]
             if fm['datatype'] == 'rating':
                 val = db.field_for(field, book_id, default_value=0)
                 if val:
                     return rating_to_stars(val, allow_half_stars=db.field_metadata[field]['display'].get('allow_half_stars'))
             else:
                 return self.render_template('{%s}' % field, index, db).replace('&', '&&')
     except Exception:
         if not self.subtitle_error_reported:
             self.subtitle_error_reported = True
             import traceback
             traceback.print_exc()
     return ''
Пример #13
0
 def __init__(self, *args, **kwargs):
     QStyledItemDelegate.__init__(self, *args, **kwargs)
     self.old_look = False
     self.rating_pat = re.compile(r'[%s]' % rating_to_stars(3, True))
     self.rating_font = QFont(rating_font())
     self.completion_data = None
Пример #14
0
    def generate_html(comments):
        args = dict(xmlns=XHTML_NS,
                    title_str=title_str,
                    css=css,
                    title=title,
                    author=author,
                    publisher=publisher,
                    pubdate_label=_('Published'), pubdate=pubdate,
                    series_label=_('Series'), series=series,
                    rating_label=_('Rating'), rating=rating,
                    tags_label=_('Tags'), tags=tags,
                    comments=comments,
                    footer='',
                    searchable_tags=' '.join(escape(t)+'ttt' for t in tags.tags_list),
                    )
        for key in mi.custom_field_keys():
            m = mi.get_user_metadata(key, False) or {}
            try:
                display_name, val = mi.format_field_extended(key)[:2]
                dkey = key.replace('#', '_')
                dt = m.get('datatype')
                if dt == 'series':
                    args[dkey] = Series(mi.get(key), mi.get(key + '_index'))
                elif dt == 'rating':
                    args[dkey] = rating_to_stars(mi.get(key), m.get('display', {}).get('allow_half_stars', False))
                elif dt == 'comments':
                    val = val or ''
                    display = m.get('display', {})
                    ctype = display.get('interpret_as') or 'html'
                    if ctype == 'long-text':
                        val = '<pre style="white-space:pre-wrap">%s</pre>' % escape(val)
                    elif ctype == 'short-text':
                        val = '<span>%s</span>' % escape(val)
                    elif ctype == 'markdown':
                        val = markdown(val)
                    else:
                        val = comments_to_html(val)
                    args[dkey] = val
                else:
                    args[dkey] = escape(val)
                args[dkey+'_label'] = escape(display_name)
            except Exception:
                # if the val (custom column contents) is None, don't add to args
                pass

        if False:
            print("Custom column values available in jacket template:")
            for key in args.keys():
                if key.startswith('_') and not key.endswith('_label'):
                    print(" %s: %s" % ('#' + key[1:], args[key]))

        # Used in the comment describing use of custom columns in templates
        # Don't change this unless you also change it in template.xhtml
        args['_genre_label'] = args.get('_genre_label', '{_genre_label}')
        args['_genre'] = args.get('_genre', '{_genre}')

        formatter = SafeFormatter()
        generated_html = formatter.format(template, **args)

        # Post-process the generated html to strip out empty header items

        soup = BeautifulSoup(generated_html)
        if not series:
            series_tag = soup.find(attrs={'class':'cbj_series'})
            if series_tag is not None:
                series_tag.extract()
        if not rating:
            rating_tag = soup.find(attrs={'class':'cbj_rating'})
            if rating_tag is not None:
                rating_tag.extract()
        if not tags:
            tags_tag = soup.find(attrs={'class':'cbj_tags'})
            if tags_tag is not None:
                tags_tag.extract()
        if not pubdate:
            pubdate_tag = soup.find(attrs={'class':'cbj_pubdata'})
            if pubdate_tag is not None:
                pubdate_tag.extract()
        if output_profile.short_name != 'kindle':
            hr_tag = soup.find('hr', attrs={'class':'cbj_kindle_banner_hr'})
            if hr_tag is not None:
                hr_tag.extract()

        return strip_encoding_declarations(
                soup.renderContents('utf-8').decode('utf-8'))
Пример #15
0
 def __init__(self, *args, **kwargs):
     QStyledItemDelegate.__init__(self, *args, **kwargs)
     self.old_look = gprefs['tag_browser_old_look']
     self.rating_pat = re.compile(r'[%s]' % rating_to_stars(3, True))
     self.rating_font = QFont(rating_font())
Пример #16
0
def mi_to_html(mi,
               field_list=None,
               default_author_link=None,
               use_roman_numbers=True,
               rating_font='Liberation Serif',
               rtl=False):
    if field_list is None:
        field_list = get_field_list(mi)
    ans = []
    comment_fields = []
    isdevice = not hasattr(mi, 'id')
    row = u'<td class="title">%s</td><td class="value">%s</td>'
    p = prepare_string_for_xml
    a = partial(prepare_string_for_xml, attribute=True)
    book_id = getattr(mi, 'id', 0)

    for field in (field for field, display in field_list if display):
        try:
            metadata = mi.metadata_for_field(field)
        except:
            continue
        if not metadata:
            continue
        if field == 'sort':
            field = 'title_sort'
        if metadata['is_custom'] and metadata['datatype'] in {
                'bool', 'int', 'float'
        }:
            isnull = mi.get(field) is None
        else:
            isnull = mi.is_null(field)
        if isnull:
            continue
        name = metadata['name']
        if not name:
            name = field
        name += ':'
        disp = metadata['display']
        if metadata['datatype'] == 'comments' or field == 'comments':
            val = getattr(mi, field)
            if val:
                ctype = disp.get('interpret_as') or 'html'
                val = force_unicode(val)
                if ctype == 'long-text':
                    val = '<pre style="white-space:pre-wrap">%s</pre>' % p(val)
                elif ctype == 'short-text':
                    val = '<span>%s</span>' % p(val)
                elif ctype == 'markdown':
                    val = markdown(val)
                else:
                    val = comments_to_html(val)
                if disp.get('heading_position', 'hide') == 'side':
                    ans.append((field, row % (name, val)))
                else:
                    if disp.get('heading_position', 'hide') == 'above':
                        val = '<h3 class="comments-heading">%s</h3>%s' % (
                            p(name), val)
                    comment_fields.append(
                        '<div id="%s" class="comments">%s</div>' %
                        (field.replace('#', '_'), val))
        elif metadata['datatype'] == 'rating':
            val = getattr(mi, field)
            if val:
                star_string = rating_to_stars(
                    val, disp.get('allow_half_stars', False))
                ans.append(
                    (field,
                     u'<td class="title">%s</td><td class="rating value" '
                     'style=\'font-family:"%s"\'>%s</td>' %
                     (name, rating_font, star_string)))
        elif metadata['datatype'] == 'composite':
            val = getattr(mi, field)
            if val:
                val = force_unicode(val)
                if disp.get('contains_html', False):
                    ans.append((field, row % (name, comments_to_html(val))))
                else:
                    if not metadata['is_multiple']:
                        val = '<a href="%s" title="%s">%s</a>' % (search_href(
                            field,
                            val), _('Click to see books with {0}: {1}').format(
                                metadata['name'], a(val)), p(val))
                    else:
                        all_vals = [
                            v.strip() for v in val.split(
                                metadata['is_multiple']['list_to_ui'])
                            if v.strip()
                        ]
                        links = [
                            '<a href="%s" title="%s">%s</a>' %
                            (search_href(field, x),
                             _('Click to see books with {0}: {1}').format(
                                 metadata['name'], a(x)), p(x))
                            for x in all_vals
                        ]
                        val = metadata['is_multiple']['list_to_ui'].join(links)
                    ans.append((field, row % (name, val)))
        elif field == 'path':
            if mi.path:
                path = force_unicode(mi.path, filesystem_encoding)
                scheme = u'devpath' if isdevice else u'path'
                url = prepare_string_for_xml(
                    path if isdevice else unicode(book_id), True)
                pathstr = _('Click to open')
                extra = ''
                if isdevice:
                    durl = url
                    if durl.startswith('mtp:::'):
                        durl = ':::'.join((durl.split(':::'))[2:])
                    extra = '<br><span style="font-size:smaller">%s</span>' % (
                        prepare_string_for_xml(durl))
                link = u'<a href="%s:%s" title="%s">%s</a>%s' % (
                    scheme, url, prepare_string_for_xml(path,
                                                        True), pathstr, extra)
                ans.append((field, row % (name, link)))
        elif field == 'formats':
            if isdevice:
                continue
            path = mi.path or ''
            bpath = ''
            if path:
                h, t = os.path.split(path)
                bpath = os.sep.join((os.path.basename(h), t))
            data = ({
                'fmt': x,
                'path': a(path or ''),
                'fname': a(mi.format_files.get(x, '')),
                'ext': x.lower(),
                'id': book_id,
                'bpath': bpath,
                'sep': os.sep
            } for x in mi.formats)
            fmts = [
                u'<a data-full-path="{path}{sep}{fname}.{ext}" title="{bpath}{sep}{fname}.{ext}" href="format:{id}:{fmt}">{fmt}</a>'
                .format(**x) for x in data
            ]
            ans.append((field, row % (name, u', '.join(fmts))))
        elif field == 'identifiers':
            urls = urls_from_identifiers(mi.identifiers)
            links = [
                u'<a href="%s" title="%s:%s" data-item="%s">%s</a>' %
                (a(url), a(id_typ), a(id_val),
                 a(item_data(field, id_typ, book_id)), p(namel))
                for namel, id_typ, id_val, url in urls
            ]
            links = u', '.join(links)
            if links:
                ans.append((field, row % (_('Ids') + ':', links)))
        elif field == 'authors':
            authors = []
            formatter = EvalFormatter()
            for aut in mi.authors:
                link = ''
                if mi.author_link_map.get(aut):
                    link = lt = mi.author_link_map[aut]
                elif default_author_link:
                    if isdevice and default_author_link == 'search-calibre':
                        default_author_link = DEFAULT_AUTHOR_LINK
                    if default_author_link.startswith('search-'):
                        which_src = default_author_link.partition('-')[2]
                        link, lt = author_search_href(which_src,
                                                      title=mi.title,
                                                      author=aut)
                    else:
                        vals = {
                            'author': qquote(aut),
                            'title': qquote(mi.title)
                        }
                        try:
                            vals['author_sort'] = qquote(
                                mi.author_sort_map[aut])
                        except KeyError:
                            vals['author_sort'] = qquote(aut)
                        link = lt = formatter.safe_format(
                            default_author_link, vals, '', vals)
                aut = p(aut)
                if link:
                    authors.append(
                        u'<a calibre-data="authors" title="%s" href="%s">%s</a>'
                        % (a(lt), a(link), aut))
                else:
                    authors.append(aut)
            ans.append((field, row % (name, u' & '.join(authors))))
        elif field == 'languages':
            if not mi.languages:
                continue
            names = filter(None, map(calibre_langcode_to_name, mi.languages))
            names = [
                '<a href="%s" title="%s">%s</a>' %
                (search_href('languages', n),
                 _('Search calibre for books with the language: {}').format(n),
                 n) for n in names
            ]
            ans.append((field, row % (name, u', '.join(names))))
        elif field == 'publisher':
            if not mi.publisher:
                continue
            val = '<a href="%s" title="%s" data-item="%s">%s</a>' % (
                search_href('publisher', mi.publisher),
                _('Click to see books with {0}: {1}').format(
                    metadata['name'], a(mi.publisher)),
                a(item_data('publisher', mi.publisher,
                            book_id)), p(mi.publisher))
            ans.append((field, row % (name, val)))
        elif field == 'title':
            # otherwise title gets metadata['datatype'] == 'text'
            # treatment below with a click to search link (which isn't
            # too bad), and a right-click 'Delete' option to delete
            # the title (which is bad).
            val = mi.format_field(field)[-1]
            ans.append((field, row % (name, val)))
        else:
            val = mi.format_field(field)[-1]
            if val is None:
                continue
            val = p(val)
            if metadata['datatype'] == 'series':
                sidx = mi.get(field + '_index')
                if sidx is None:
                    sidx = 1.0
                try:
                    st = metadata['search_terms'][0]
                except Exception:
                    st = field
                series = getattr(mi, field)
                val = _(
                    '%(sidx)s of <a href="%(href)s" title="%(tt)s" data-item="%(data)s">'
                    '<span class="%(cls)s">%(series)s</span></a>') % dict(
                        sidx=fmt_sidx(sidx, use_roman=use_roman_numbers),
                        cls="series_name",
                        series=p(series),
                        href=search_href(st, series),
                        data=a(item_data(field, series, book_id)),
                        tt=p(_('Click to see books in this series')))
            elif metadata['datatype'] == 'datetime':
                aval = getattr(mi, field)
                if is_date_undefined(aval):
                    continue
            elif metadata['datatype'] == 'text' and metadata['is_multiple']:
                try:
                    st = metadata['search_terms'][0]
                except Exception:
                    st = field
                all_vals = mi.get(field)
                if not metadata.get('display', {}).get('is_names', False):
                    all_vals = sorted(all_vals, key=sort_key)
                links = [
                    '<a href="%s" title="%s" data-item="%s">%s</a>' %
                    (search_href(
                        st, x), _('Click to see books with {0}: {1}').format(
                            metadata['name'],
                            a(x)), a(item_data(field, x, book_id)), p(x))
                    for x in all_vals
                ]
                val = metadata['is_multiple']['list_to_ui'].join(links)
            elif metadata['datatype'] == 'text' or metadata[
                    'datatype'] == 'enumeration':
                # text/is_multiple handled above so no need to add the test to the if
                try:
                    st = metadata['search_terms'][0]
                except Exception:
                    st = field
                val = '<a href="%s" title="%s" data-item="%s">%s</a>' % (
                    search_href(st, val),
                    a(
                        _('Click to see books with {0}: {1}').format(
                            metadata['name'],
                            val)), a(item_data(field, val, book_id)), p(val))

            ans.append((field, row % (name, val)))

    dc = getattr(mi, 'device_collections', [])
    if dc:
        dc = u', '.join(sorted(dc, key=sort_key))
        ans.append(('device_collections', row % (_('Collections') + ':', dc)))

    def classname(field):
        try:
            dt = mi.metadata_for_field(field)['datatype']
        except:
            dt = 'text'
        return 'datatype_%s' % dt

    ans = [
        u'<tr id="%s" class="%s">%s</tr>' %
        (fieldl.replace('#', '_'), classname(fieldl), html)
        for fieldl, html in ans
    ]
    # print '\n'.join(ans)
    direction = 'rtl' if rtl else 'ltr'
    margin = 'left' if rtl else 'right'
    return u'<style>table.fields td { vertical-align:top}</style>' + \
           u'<table class="fields" style="direction: %s; margin-%s:auto">%s</table>'%(
               direction, margin, u'\n'.join(ans)), comment_fields
Пример #17
0
 def __init__(self, *args, **kwargs):
     QStyledItemDelegate.__init__(self, *args, **kwargs)
     self.old_look = False
     self.rating_pat = re.compile(r'[%s]' % rating_to_stars(3, True))
     self.rating_font = QFont(rating_font())
Пример #18
0
def stars(num, is_half_star=False):
    return rating_to_stars(num, is_half_star)
Пример #19
0
def mi_to_html(mi, field_list=None, default_author_link=None, use_roman_numbers=True, rating_font='Liberation Serif', rtl=False):
    if field_list is None:
        field_list = get_field_list(mi)
    ans = []
    comment_fields = []
    isdevice = not hasattr(mi, 'id')
    row = u'<td class="title">%s</td><td class="value">%s</td>'
    p = prepare_string_for_xml
    a = partial(prepare_string_for_xml, attribute=True)
    book_id = getattr(mi, 'id', 0)

    for field in (field for field, display in field_list if display):
        try:
            metadata = mi.metadata_for_field(field)
        except:
            continue
        if not metadata:
            continue
        if field == 'sort':
            field = 'title_sort'
        if metadata['is_custom'] and metadata['datatype'] in {'bool', 'int', 'float'}:
            isnull = mi.get(field) is None
        else:
            isnull = mi.is_null(field)
        if isnull:
            continue
        name = metadata['name']
        if not name:
            name = field
        name += ':'
        disp = metadata['display']
        if metadata['datatype'] == 'comments' or field == 'comments':
            val = getattr(mi, field)
            if val:
                ctype = disp.get('interpret_as') or 'html'
                val = force_unicode(val)
                if ctype == 'long-text':
                    val = '<pre style="white-space:pre-wrap">%s</pre>' % p(val)
                elif ctype == 'short-text':
                    val = '<span>%s</span>' % p(val)
                elif ctype == 'markdown':
                    val = markdown(val)
                else:
                    val = comments_to_html(val)
                if disp.get('heading_position', 'hide') == 'side':
                    ans.append((field, row % (name, val)))
                else:
                    if disp.get('heading_position', 'hide') == 'above':
                        val = '<h3 class="comments-heading">%s</h3>%s' % (p(name), val)
                    comment_fields.append('<div id="%s" class="comments">%s</div>' % (field.replace('#', '_'), val))
        elif metadata['datatype'] == 'rating':
            val = getattr(mi, field)
            if val:
                star_string = rating_to_stars(val, disp.get('allow_half_stars', False))
                ans.append((field,
                    u'<td class="title">%s</td><td class="rating value" '
                    'style=\'font-family:"%s"\'>%s</td>'%(
                        name, rating_font, star_string)))
        elif metadata['datatype'] == 'composite':
            val = getattr(mi, field)
            if val:
                val = force_unicode(val)
                if disp.get('contains_html', False):
                    ans.append((field, row % (name, comments_to_html(val))))
                else:
                    if not metadata['is_multiple']:
                        val = '<a href="%s" title="%s">%s</a>' % (
                              search_href(field, val),
                              _('Click to see books with {0}: {1}').format(metadata['name'], a(val)), p(val))
                    else:
                        all_vals = [v.strip()
                            for v in val.split(metadata['is_multiple']['list_to_ui']) if v.strip()]
                        links = ['<a href="%s" title="%s">%s</a>' % (
                            search_href(field, x), _('Click to see books with {0}: {1}').format(
                                     metadata['name'], a(x)), p(x)) for x in all_vals]
                        val = metadata['is_multiple']['list_to_ui'].join(links)
                    ans.append((field, row % (name, val)))
        elif field == 'path':
            if mi.path:
                path = force_unicode(mi.path, filesystem_encoding)
                scheme = u'devpath' if isdevice else u'path'
                url = prepare_string_for_xml(path if isdevice else
                        unicode(book_id), True)
                pathstr = _('Click to open')
                extra = ''
                if isdevice:
                    durl = url
                    if durl.startswith('mtp:::'):
                        durl = ':::'.join((durl.split(':::'))[2:])
                    extra = '<br><span style="font-size:smaller">%s</span>'%(
                            prepare_string_for_xml(durl))
                link = u'<a href="%s:%s" title="%s">%s</a>%s' % (scheme, url,
                        prepare_string_for_xml(path, True), pathstr, extra)
                ans.append((field, row % (name, link)))
        elif field == 'formats':
            if isdevice:
                continue
            path = mi.path or ''
            bpath = ''
            if path:
                h, t = os.path.split(path)
                bpath = os.sep.join((os.path.basename(h), t))
            data = ({
                'fmt':x, 'path':a(path or ''), 'fname':a(mi.format_files.get(x, '')),
                'ext':x.lower(), 'id':book_id, 'bpath':bpath, 'sep':os.sep
            } for x in mi.formats)
            fmts = [u'<a data-full-path="{path}{sep}{fname}.{ext}" title="{bpath}{sep}{fname}.{ext}" href="format:{id}:{fmt}">{fmt}</a>'.format(**x)
                    for x in data]
            ans.append((field, row % (name, u', '.join(fmts))))
        elif field == 'identifiers':
            urls = urls_from_identifiers(mi.identifiers)
            links = [u'<a href="%s" title="%s:%s" data-item="%s">%s</a>' % (a(url), a(id_typ), a(id_val), a(item_data(field, id_typ, book_id)), p(namel))
                    for namel, id_typ, id_val, url in urls]
            links = u', '.join(links)
            if links:
                ans.append((field, row % (_('Ids')+':', links)))
        elif field == 'authors' and not isdevice:
            authors = []
            formatter = EvalFormatter()
            for aut in mi.authors:
                link = ''
                if mi.author_link_map[aut]:
                    link = lt = mi.author_link_map[aut]
                elif default_author_link:
                    if default_author_link == 'search-calibre':
                        link = search_href('authors', aut)
                        lt = a(_('Search the calibre library for books by %s') % aut)
                    else:
                        vals = {'author': aut.replace(' ', '+')}
                        try:
                            vals['author_sort'] =  mi.author_sort_map[aut].replace(' ', '+')
                        except:
                            vals['author_sort'] = aut.replace(' ', '+')
                        link = lt = a(formatter.safe_format(default_author_link, vals, '', vals))
                aut = p(aut)
                if link:
                    authors.append(u'<a calibre-data="authors" title="%s" href="%s">%s</a>'%(lt, link, aut))
                else:
                    authors.append(aut)
            ans.append((field, row % (name, u' & '.join(authors))))
        elif field == 'languages':
            if not mi.languages:
                continue
            names = filter(None, map(calibre_langcode_to_name, mi.languages))
            ans.append((field, row % (name, u', '.join(names))))
        elif field == 'publisher':
            if not mi.publisher:
                continue
            val = '<a href="%s" title="%s" data-item="%s">%s</a>' % (
                search_href('publisher', mi.publisher), _('Click to see books with {0}: {1}').format(metadata['name'], a(mi.publisher)),
                a(item_data('publisher', mi.publisher, book_id)), p(mi.publisher))
            ans.append((field, row % (name, val)))
        elif field == 'title':
            # otherwise title gets metadata['datatype'] == 'text'
            # treatment below with a click to search link (which isn't
            # too bad), and a right-click 'Delete' option to delete
            # the title (which is bad).
            val = mi.format_field(field)[-1]
            ans.append((field, row % (name, val)))
        else:
            val = mi.format_field(field)[-1]
            if val is None:
                continue
            val = p(val)
            if metadata['datatype'] == 'series':
                sidx = mi.get(field+'_index')
                if sidx is None:
                    sidx = 1.0
                try:
                    st = metadata['search_terms'][0]
                except Exception:
                    st = field
                series = getattr(mi, field)
                val = _(
                    '%(sidx)s of <a href="%(href)s" title="%(tt)s" data-item="%(data)s">'
                    '<span class="%(cls)s">%(series)s</span></a>') % dict(
                        sidx=fmt_sidx(sidx, use_roman=use_roman_numbers), cls="series_name",
                        series=p(series), href=search_href(st, series),
                        data=a(item_data(field, series, book_id)),
                        tt=p(_('Click to see books in this series')))
            elif metadata['datatype'] == 'datetime':
                aval = getattr(mi, field)
                if is_date_undefined(aval):
                    continue
            elif metadata['datatype'] == 'text' and metadata['is_multiple']:
                try:
                    st = metadata['search_terms'][0]
                except Exception:
                    st = field
                all_vals = mi.get(field)
                if not metadata.get('display', {}).get('is_names', False):
                    all_vals = sorted(all_vals, key=sort_key)
                links = ['<a href="%s" title="%s" data-item="%s">%s</a>' % (
                    search_href(st, x), _('Click to see books with {0}: {1}').format(
                        metadata['name'], a(x)), a(item_data(field, x, book_id)), p(x))
                         for x in all_vals]
                val = metadata['is_multiple']['list_to_ui'].join(links)
            elif metadata['datatype'] == 'text' or metadata['datatype'] == 'enumeration':
                # text/is_multiple handled above so no need to add the test to the if
                try:
                    st = metadata['search_terms'][0]
                except Exception:
                    st = field
                val = '<a href="%s" title="%s" data-item="%s">%s</a>' % (
                    search_href(st, val), a(_('Click to see books with {0}: {1}').format(metadata['name'], val)),
                    a(item_data(field, val, book_id)), p(val))

            ans.append((field, row % (name, val)))

    dc = getattr(mi, 'device_collections', [])
    if dc:
        dc = u', '.join(sorted(dc, key=sort_key))
        ans.append(('device_collections',
            row % (_('Collections')+':', dc)))

    def classname(field):
        try:
            dt = mi.metadata_for_field(field)['datatype']
        except:
            dt = 'text'
        return 'datatype_%s'%dt

    ans = [u'<tr id="%s" class="%s">%s</tr>'%(fieldl.replace('#', '_'),
        classname(fieldl), html) for fieldl, html in ans]
    # print '\n'.join(ans)
    direction = 'rtl' if rtl else 'ltr'
    margin = 'left' if rtl else 'right'
    return u'<table class="fields" style="direction: %s; margin-%s:auto">%s</table>'%(direction, margin, u'\n'.join(ans)), comment_fields
Пример #20
0
    def generate_html(comments):
        args = dict(xmlns=XHTML_NS,
                    title_str=title_str,
                    css=css,
                    title=title,
                    author=author,
                    publisher=publisher,
                    pubdate_label=_('Published'), pubdate=pubdate,
                    series_label=_('Series'), series=series,
                    rating_label=_('Rating'), rating=rating,
                    tags_label=_('Tags'), tags=tags,
                    comments=comments,
                    footer='',
                    searchable_tags=' '.join(escape(t)+'ttt' for t in tags.tags_list),
                    )
        for key in mi.custom_field_keys():
            m = mi.get_user_metadata(key, False) or {}
            try:
                display_name, val = mi.format_field_extended(key)[:2]
                dkey = key.replace('#', '_')
                dt = m.get('datatype')
                if dt == 'series':
                    args[dkey] = Series(mi.get(key), mi.get(key + '_index'))
                elif dt == 'rating':
                    args[dkey] = rating_to_stars(mi.get(key), m.get('display', {}).get('allow_half_stars', False))
                elif dt == 'comments':
                    val = val or ''
                    display = m.get('display', {})
                    ctype = display.get('interpret_as') or 'html'
                    if ctype == 'long-text':
                        val = '<pre style="white-space:pre-wrap">%s</pre>' % escape(val)
                    elif ctype == 'short-text':
                        val = '<span>%s</span>' % escape(val)
                    elif ctype == 'markdown':
                        val = markdown(val)
                    else:
                        val = comments_to_html(val)
                    args[dkey] = val
                else:
                    args[dkey] = escape(val)
                args[dkey+'_label'] = escape(display_name)
            except Exception:
                # if the val (custom column contents) is None, don't add to args
                pass

        if False:
            print("Custom column values available in jacket template:")
            for key in args.keys():
                if key.startswith('_') and not key.endswith('_label'):
                    print(" %s: %s" % ('#' + key[1:], args[key]))

        # Used in the comment describing use of custom columns in templates
        # Don't change this unless you also change it in template.xhtml
        args['_genre_label'] = args.get('_genre_label', '{_genre_label}')
        args['_genre'] = args.get('_genre', '{_genre}')

        formatter = SafeFormatter()
        generated_html = formatter.format(template, **args)
        has_data['series'] = bool(series)
        has_data['tags'] = bool(tags)
        has_data['rating'] = bool(rating)
        has_data['pubdate'] = bool(pubdate)

        return strip_encoding_declarations(generated_html)
Пример #21
0
 def data(self, index, role=Qt.DisplayRole):
     if role == Qt.DisplayRole:
         val = index.row() * (1 if self.is_half_star else 2)
         return rating_to_stars(val, self.is_half_star) or self.null_text
     if role == Qt.FontRole:
         return QApplication.instance().font() if index.row() == 0 else self.rating_font
Пример #22
0
 def displayText(self, value, locale):
     return rating_to_stars(value, self.is_half_star)
Пример #23
0
    def generate_html(comments):
        display = Attributes()
        args = dict(
            xmlns=XHTML_NS,
            title_str=title_str,
            identifiers=Identifiers(mi.identifiers),
            css=css,
            title=title,
            author=author,
            publisher=publisher,
            pubdate_label=_('Published'),
            pubdate=pubdate,
            series_label=ngettext('Series', 'Series', 1),
            series=series,
            rating_label=_('Rating'),
            rating=rating,
            tags_label=_('Tags'),
            tags=tags,
            comments=comments,
            footer='',
            display=display,
            searchable_tags=' '.join(
                escape(t) + 'ttt' for t in tags.tags_list),
        )
        for key in mi.custom_field_keys():
            m = mi.get_user_metadata(key, False) or {}
            try:
                display_name, val = mi.format_field_extended(key)[:2]
                dkey = key.replace('#', '_')
                dt = m.get('datatype')
                if dt == 'series':
                    args[dkey] = Series(mi.get(key), mi.get(key + '_index'))
                elif dt == 'rating':
                    args[dkey] = rating_to_stars(
                        mi.get(key),
                        m.get('display', {}).get('allow_half_stars', False))
                elif dt == 'comments':
                    val = val or ''
                    ctype = m.get('display', {}).get('interpret_as') or 'html'
                    if ctype == 'long-text':
                        val = '<pre style="white-space:pre-wrap">%s</pre>' % escape(
                            val)
                    elif ctype == 'short-text':
                        val = '<span>%s</span>' % escape(val)
                    elif ctype == 'markdown':
                        val = markdown(val)
                    else:
                        val = comments_to_html(val)
                    args[dkey] = val
                else:
                    args[dkey] = escape(val)
                args[dkey + '_label'] = escape(display_name)
                setattr(display, dkey,
                        'none' if mi.is_null(key) else 'initial')
            except Exception:
                # if the val (custom column contents) is None, don't add to args
                pass

        if False:
            print("Custom column values available in jacket template:")
            for key in args.keys():
                if key.startswith('_') and not key.endswith('_label'):
                    print(" {}: {}".format('#' + key[1:], args[key]))

        # Used in the comment describing use of custom columns in templates
        # Don't change this unless you also change it in template.xhtml
        args['_genre_label'] = args.get('_genre_label', '{_genre_label}')
        args['_genre'] = args.get('_genre', '{_genre}')
        has_data['series'] = bool(series)
        has_data['tags'] = bool(tags)
        has_data['rating'] = bool(rating)
        has_data['pubdate'] = bool(pubdate)
        for k, v in has_data.items():
            setattr(display, k, 'initial' if v else 'none')
        display.title = 'initial'
        if mi.identifiers:
            display.identifiers = 'initial'

        formatter = SafeFormatter()
        generated_html = formatter.format(template, **args)

        return strip_encoding_declarations(generated_html)
Пример #24
0
    def generate_html(comments):
        args = dict(
            xmlns=XHTML_NS,
            title_str=title_str,
            css=css,
            title=title,
            author=author,
            publisher=publisher,
            pubdate_label=_('Published'),
            pubdate=pubdate,
            series_label=_('Series'),
            series=series,
            rating_label=_('Rating'),
            rating=rating,
            tags_label=_('Tags'),
            tags=tags,
            comments=comments,
            footer='',
            searchable_tags=' '.join(
                escape(t) + 'ttt' for t in tags.tags_list),
        )
        for key in mi.custom_field_keys():
            m = mi.get_user_metadata(key, False) or {}
            try:
                display_name, val = mi.format_field_extended(key)[:2]
                dkey = key.replace('#', '_')
                dt = m.get('datatype')
                if dt == 'series':
                    args[dkey] = Series(mi.get(key), mi.get(key + '_index'))
                elif dt == 'rating':
                    args[dkey] = rating_to_stars(
                        mi.get(key),
                        m.get('display', {}).get('allow_half_stars', False))
                else:
                    args[dkey] = escape(val)
                args[dkey + '_label'] = escape(display_name)
            except Exception:
                # if the val (custom column contents) is None, don't add to args
                pass

        if False:
            print("Custom column values available in jacket template:")
            for key in args.keys():
                if key.startswith('_') and not key.endswith('_label'):
                    print(" %s: %s" % ('#' + key[1:], args[key]))

        # Used in the comment describing use of custom columns in templates
        # Don't change this unless you also change it in template.xhtml
        args['_genre_label'] = args.get('_genre_label', '{_genre_label}')
        args['_genre'] = args.get('_genre', '{_genre}')

        formatter = SafeFormatter()
        generated_html = formatter.format(template, **args)

        # Post-process the generated html to strip out empty header items

        soup = BeautifulSoup(generated_html)
        if not series:
            series_tag = soup.find(attrs={'class': 'cbj_series'})
            if series_tag is not None:
                series_tag.extract()
        if not rating:
            rating_tag = soup.find(attrs={'class': 'cbj_rating'})
            if rating_tag is not None:
                rating_tag.extract()
        if not tags:
            tags_tag = soup.find(attrs={'class': 'cbj_tags'})
            if tags_tag is not None:
                tags_tag.extract()
        if not pubdate:
            pubdate_tag = soup.find(attrs={'class': 'cbj_pubdata'})
            if pubdate_tag is not None:
                pubdate_tag.extract()
        if output_profile.short_name != 'kindle':
            hr_tag = soup.find('hr', attrs={'class': 'cbj_kindle_banner_hr'})
            if hr_tag is not None:
                hr_tag.extract()

        return strip_encoding_declarations(
            soup.renderContents('utf-8').decode('utf-8'))
Пример #25
0
def ACQUISITION_ENTRY(item, version, db, updated, CFM, CKEYS, prefix):
    FM = db.FIELD_MAP
    title = item[FM['title']]
    if not title:
        title = _('Unknown')
    authors = item[FM['authors']]
    if not authors:
        authors = _('Unknown')
    authors = ' & '.join([i.replace('|', ',') for i in authors.split(',')])
    extra = []
    rating = item[FM['rating']]
    if rating > 0:
        rating = rating_to_stars(rating)
        extra.append(_('RATING: %s<br />') % rating)
    tags = item[FM['tags']]
    if tags:
        extra.append(
            _('TAGS: %s<br />') % xml(
                format_tag_string(
                    tags, ',', ignore_max=True, no_tag_count=True)))
    series = item[FM['series']]
    if series:
        extra.append(
            _('SERIES: %(series)s [%(sidx)s]<br />') %
            dict(series=xml(series),
                 sidx=fmt_sidx(float(item[FM['series_index']]))))
    mi = db.get_metadata(item[CFM['id']['rec_index']], index_is_id=True)
    for key in CKEYS:
        name, val = mi.format_field(key)
        if val:
            datatype = CFM[key]['datatype']
            if datatype == 'text' and CFM[key]['is_multiple']:
                extra.append(
                    '%s: %s<br />' %
                    (xml(name),
                     xml(
                         format_tag_string(
                             val,
                             CFM[key]['is_multiple']['ui_to_list'],
                             ignore_max=True,
                             no_tag_count=True,
                             joinval=CFM[key]['is_multiple']['list_to_ui']))))
            elif datatype == 'comments' or (CFM[key]['datatype'] == 'composite'
                                            and CFM[key]['display'].get(
                                                'contains_html', False)):
                extra.append('%s: %s<br />' %
                             (xml(name), comments_to_html(unicode(val))))
            else:
                extra.append('%s: %s<br />' % (xml(name), xml(unicode(val))))
    comments = item[FM['comments']]
    if comments:
        comments = comments_to_html(comments)
        extra.append(comments)
    if extra:
        extra = html_to_lxml('\n'.join(extra))
    idm = 'calibre' if version == 0 else 'uuid'
    id_ = 'urn:%s:%s' % (idm, item[FM['uuid']])
    ans = E.entry(TITLE(title), E.author(E.name(authors)), ID(id_),
                  UPDATED(item[FM['last_modified']]),
                  E.published(item[FM['timestamp']].isoformat()))
    if mi.pubdate and not is_date_undefined(mi.pubdate):
        ans.append(ans.makeelement('{%s}date' % DC_NS))
        ans[-1].text = mi.pubdate.isoformat()
    if len(extra):
        ans.append(E.content(extra, type='xhtml'))
    formats = item[FM['formats']]
    if formats:
        book_id = item[FM['id']]
        for fmt in formats.split(','):
            fmt = fmt.lower()
            mt = guess_type('a.' + fmt)[0]
            href = prefix + '/get/%s/%s' % (fmt, book_id)
            if mt:
                link = E.link(type=mt, href=href)
                if version > 0:
                    link.set('rel', "http://opds-spec.org/acquisition")
                    fm = db.format_metadata(book_id, fmt)
                    if fm:
                        link.set('length', str(fm['size']))
                        link.set('mtime', fm['mtime'].isoformat())
                ans.append(link)
    ans.append(
        E.link(type='image/jpeg',
               href=prefix + '/get/cover/%s' % item[FM['id']],
               rel="x-stanza-cover-image"
               if version == 0 else "http://opds-spec.org/cover"))
    ans.append(
        E.link(type='image/jpeg',
               href=prefix + '/get/thumb/%s' % item[FM['id']],
               rel="x-stanza-cover-image-thumbnail"
               if version == 0 else "http://opds-spec.org/thumbnail"))

    return ans
Пример #26
0
 def __init__(self, *args, **kwargs):
     QStyledItemDelegate.__init__(self, *args, **kwargs)
     self.old_look = gprefs['tag_browser_old_look']
     self.rating_pat = re.compile(r'[%s]' % rating_to_stars(3, True))
     self.rating_font = QFont(rating_font())
Пример #27
0
 def displayText(self, value, locale):
     return rating_to_stars(value, self.is_half_star)
Пример #28
0
def ACQUISITION_ENTRY(item, version, db, updated, CFM, CKEYS, prefix):
    FM = db.FIELD_MAP
    title = item[FM['title']]
    if not title:
        title = _('Unknown')
    authors = item[FM['authors']]
    if not authors:
        authors = _('Unknown')
    authors = ' & '.join([i.replace('|', ',') for i in
                                    authors.split(',')])
    extra = []
    rating = item[FM['rating']]
    if rating > 0:
        rating = rating_to_stars(rating)
        extra.append(_('RATING: %s<br />')%rating)
    tags = item[FM['tags']]
    if tags:
        extra.append(_('TAGS: %s<br />')%xml(format_tag_string(tags, ',',
                                                           ignore_max=True,
                                                           no_tag_count=True)))
    series = item[FM['series']]
    if series:
        extra.append(_('SERIES: %(series)s [%(sidx)s]<br />')%
                dict(series=xml(series),
                sidx=fmt_sidx(float(item[FM['series_index']]))))
    mi = db.get_metadata(item[CFM['id']['rec_index']], index_is_id=True)
    for key in CKEYS:
        name, val = mi.format_field(key)
        if val:
            datatype = CFM[key]['datatype']
            if datatype == 'text' and CFM[key]['is_multiple']:
                extra.append('%s: %s<br />'%
                             (xml(name),
                              xml(format_tag_string(val,
                                    CFM[key]['is_multiple']['ui_to_list'],
                                    ignore_max=True, no_tag_count=True,
                                    joinval=CFM[key]['is_multiple']['list_to_ui']))))
            elif datatype == 'comments' or (CFM[key]['datatype'] == 'composite' and
                            CFM[key]['display'].get('contains_html', False)):
                extra.append('%s: %s<br />'%(xml(name), comments_to_html(unicode(val))))
            else:
                extra.append('%s: %s<br />'%(xml(name), xml(unicode(val))))
    comments = item[FM['comments']]
    if comments:
        comments = comments_to_html(comments)
        extra.append(comments)
    if extra:
        extra = html_to_lxml('\n'.join(extra))
    idm = 'calibre' if version == 0 else 'uuid'
    id_ = 'urn:%s:%s'%(idm, item[FM['uuid']])
    ans = E.entry(TITLE(title), E.author(E.name(authors)), ID(id_),
            UPDATED(item[FM['last_modified']]), E.published(item[FM['timestamp']].isoformat()))
    if mi.pubdate and not is_date_undefined(mi.pubdate):
        ans.append(ans.makeelement('{%s}date' % DC_NS))
        ans[-1].text = mi.pubdate.isoformat()
    if len(extra):
        ans.append(E.content(extra, type='xhtml'))
    formats = item[FM['formats']]
    if formats:
        book_id = item[FM['id']]
        for fmt in formats.split(','):
            fmt = fmt.lower()
            mt = guess_type('a.'+fmt)[0]
            href = prefix + '/get/%s/%s'%(fmt, book_id)
            if mt:
                link = E.link(type=mt, href=href)
                if version > 0:
                    link.set('rel', "http://opds-spec.org/acquisition")
                    fm = db.format_metadata(book_id, fmt)
                    if fm:
                        link.set('length', str(fm['size']))
                        link.set('mtime', fm['mtime'].isoformat())
                ans.append(link)
    ans.append(E.link(type='image/jpeg', href=prefix+'/get/cover/%s'%item[FM['id']],
        rel="x-stanza-cover-image" if version == 0 else
        "http://opds-spec.org/cover"))
    ans.append(E.link(type='image/jpeg', href=prefix+'/get/thumb/%s'%item[FM['id']],
        rel="x-stanza-cover-image-thumbnail" if version == 0 else
        "http://opds-spec.org/thumbnail"))

    return ans