mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-07 18:24:30 -04:00
Sync to pluginize
This commit is contained in:
commit
82faaff2cf
@ -26,12 +26,16 @@ mimetypes.add_type('text/x-sony-bbeb+xml', '.lrs')
|
||||
mimetypes.add_type('application/xhtml+xml', '.xhtml')
|
||||
mimetypes.add_type('image/svg+xml', '.svg')
|
||||
mimetypes.add_type('application/x-sony-bbeb', '.lrf')
|
||||
mimetypes.add_type('application/x-sony-bbeb', '.lrx')
|
||||
mimetypes.add_type('application/x-dtbncx+xml', '.ncx')
|
||||
mimetypes.add_type('application/adobe-page-template+xml', '.xpgt')
|
||||
mimetypes.add_type('application/x-font-opentype', '.otf')
|
||||
mimetypes.add_type('application/x-font-truetype', '.ttf')
|
||||
mimetypes.add_type('application/oebps-package+xml', '.opf')
|
||||
mimetypes.add_type('application/ereader', '.pdb')
|
||||
mimetypes.add_type('application/mobi', '.mobi')
|
||||
mimetypes.add_type('application/mobi', '.prc')
|
||||
mimetypes.add_type('application/mobi', '.azw')
|
||||
guess_type = mimetypes.guess_type
|
||||
import cssutils
|
||||
cssutils.log.setLevel(logging.WARN)
|
||||
|
@ -2,7 +2,7 @@ __license__ = 'GPL v3'
|
||||
__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
__appname__ = 'calibre'
|
||||
__version__ = '0.5.0'
|
||||
__version__ = '0.5.1'
|
||||
__author__ = "Kovid Goyal <kovid@kovidgoyal.net>"
|
||||
'''
|
||||
Various run time constants.
|
||||
|
@ -132,13 +132,24 @@ class HTMLMetadataReader(MetadataReaderPlugin):
|
||||
class MOBIMetadataReader(MetadataReaderPlugin):
|
||||
|
||||
name = 'Read MOBI metadata'
|
||||
file_types = set(['mobi', 'prc', '.azw'])
|
||||
file_types = set(['mobi', 'prc', 'azw'])
|
||||
description = _('Read metadata from %s files')%'MOBI'
|
||||
|
||||
def get_metadata(self, stream, ftype):
|
||||
from calibre.ebooks.mobi.reader import get_metadata
|
||||
return get_metadata(stream)
|
||||
|
||||
|
||||
class TOPAZMetadataReader(MetadataReaderPlugin):
|
||||
|
||||
name = 'Read Topaz metadata'
|
||||
file_types = set(['tpz', 'azw1'])
|
||||
description = _('Read metadata from %s files')%'MOBI'
|
||||
|
||||
def get_metadata(self, stream, ftype):
|
||||
from calibre.ebooks.metadata.topaz import get_metadata
|
||||
return get_metadata(stream)
|
||||
|
||||
class ODTMetadataReader(MetadataReaderPlugin):
|
||||
|
||||
name = 'Read ODT metadata'
|
||||
|
@ -4,9 +4,9 @@ __copyright__ = '2009, John Schember <john at nachtimwald.com>'
|
||||
Device driver for Amazon's Kindle
|
||||
'''
|
||||
|
||||
import os
|
||||
import os, re
|
||||
|
||||
from calibre.devices.usbms.driver import USBMS
|
||||
from calibre.devices.usbms.driver import USBMS, metadata_from_formats
|
||||
|
||||
class KINDLE(USBMS):
|
||||
# Ordered list of supported formats
|
||||
@ -30,6 +30,9 @@ class KINDLE(USBMS):
|
||||
EBOOK_DIR_CARD = "documents"
|
||||
SUPPORTS_SUB_DIRS = True
|
||||
|
||||
WIRELESS_FILE_NAME_PATTERN = re.compile(
|
||||
r'(?P<title>[^-]+)-asin_(?P<asin>[a-zA-Z\d]{10,})-type_(?P<type>\w{4})-v_(?P<index>\d+).*')
|
||||
|
||||
def delete_books(self, paths, end_session=True):
|
||||
for path in paths:
|
||||
if os.path.exists(path):
|
||||
@ -41,6 +44,16 @@ class KINDLE(USBMS):
|
||||
if os.path.exists(filepath + '.mbp'):
|
||||
os.unlink(filepath + '.mbp')
|
||||
|
||||
@classmethod
|
||||
def metadata_from_path(cls, path):
|
||||
mi = metadata_from_formats([path])
|
||||
if mi.title == _('Unknown') or ('-asin' in mi.title and '-type' in mi.title):
|
||||
match = cls.WIRELESS_FILE_NAME_PATTERN.match(os.path.basename(path))
|
||||
if match is not None:
|
||||
mi.title = match.group('title')
|
||||
return mi
|
||||
|
||||
|
||||
class KINDLE2(KINDLE):
|
||||
|
||||
PRODUCT_ID = [0x0002]
|
||||
|
@ -1,19 +1,20 @@
|
||||
__license__ = 'GPL v3'
|
||||
__copyright__ = '2009, John Schember <john at nachtimwald.com>'
|
||||
'''
|
||||
Global Mime mapping of ebook types.
|
||||
'''
|
||||
from __future__ import with_statement
|
||||
__license__ = 'GPL 3'
|
||||
__copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
MIME_MAP = {
|
||||
'azw' : 'application/azw',
|
||||
'epub' : 'application/epub+zip',
|
||||
'html' : 'text/html',
|
||||
'lrf' : 'application/x-sony-bbeb',
|
||||
'lrx' : 'application/x-sony-bbeb',
|
||||
'mobi' : 'application/mobi',
|
||||
'pdf' : 'application/pdf',
|
||||
'prc' : 'application/prc',
|
||||
'rtf' : 'application/rtf',
|
||||
'txt' : 'text/plain',
|
||||
}
|
||||
from calibre import guess_type
|
||||
|
||||
def _mt(path):
|
||||
mt = guess_type(path)[0]
|
||||
if not mt:
|
||||
mt = 'application/octet-stream'
|
||||
return mt
|
||||
|
||||
def mime_type_ext(ext):
|
||||
if not ext.startswith('.'):
|
||||
ext = '.'+ext
|
||||
return _mt('a'+ext)
|
||||
|
||||
def mime_type_path(path):
|
||||
return _mt(path)
|
@ -15,7 +15,7 @@ from calibre.ebooks.metadata import authors_to_string
|
||||
from calibre.devices.usbms.device import Device
|
||||
from calibre.devices.usbms.books import BookList, Book
|
||||
from calibre.devices.errors import FreeSpaceError, PathError
|
||||
from calibre.devices.mime import MIME_MAP
|
||||
from calibre.devices.mime import mime_type_ext
|
||||
|
||||
class File(object):
|
||||
def __init__(self, path):
|
||||
@ -226,14 +226,17 @@ class USBMS(Device):
|
||||
if not os.path.isdir(path):
|
||||
os.utime(path, None)
|
||||
|
||||
@classmethod
|
||||
def metadata_from_path(cls, path):
|
||||
return metadata_from_formats([path])
|
||||
|
||||
@classmethod
|
||||
def book_from_path(cls, path):
|
||||
fileext = path_to_ext(path)
|
||||
|
||||
mi = metadata_from_formats([path])
|
||||
mime = MIME_MAP[fileext] if fileext in MIME_MAP.keys() else 'Unknown'
|
||||
|
||||
mi = cls.metadata_from_path(path)
|
||||
mime = mime_type_ext(fileext)
|
||||
authors = authors_to_string(mi.authors)
|
||||
|
||||
return Book(path, mi.title, authors, mime)
|
||||
book = Book(path, mi.title, authors, mime)
|
||||
return book
|
||||
|
||||
|
@ -97,6 +97,8 @@ def xml_to_unicode(raw, verbose=False, strip_encoding_pats=False,
|
||||
if encoding is None:
|
||||
encoding = force_encoding(raw, verbose)
|
||||
try:
|
||||
if encoding.lower().strip() == 'macintosh':
|
||||
encoding = 'mac-roman'
|
||||
raw = raw.decode(encoding, 'replace')
|
||||
except LookupError:
|
||||
encoding = 'utf-8'
|
||||
|
@ -118,11 +118,17 @@ class EbookIterator(object):
|
||||
self.spine = [SpineItem(i.path) for i in self.opf.spine]
|
||||
|
||||
cover = self.opf.cover
|
||||
if os.path.splitext(self.pathtoebook)[1].lower() in ('.lit', '.mobi', '.prc') and cover:
|
||||
if os.path.splitext(self.pathtoebook)[1].lower() in \
|
||||
('.lit', '.mobi', '.prc') and cover:
|
||||
cfile = os.path.join(os.path.dirname(self.spine[0]), 'calibre_ei_cover.html')
|
||||
open(cfile, 'wb').write(TITLEPAGE%cover)
|
||||
self.spine[0:0] = [SpineItem(cfile)]
|
||||
|
||||
if self.opf.path_to_html_toc is not None and \
|
||||
self.opf.path_to_html_toc not in self.spine:
|
||||
self.spine.append(SpineItem(self.opf.path_to_html_toc))
|
||||
|
||||
|
||||
sizes = [i.character_count for i in self.spine]
|
||||
self.pages = [math.ceil(i/float(self.CHARACTERS_PER_PAGE)) for i in sizes]
|
||||
for p, s in zip(self.pages, self.spine):
|
||||
|
@ -15,7 +15,7 @@ _METADATA_PRIORITIES = [
|
||||
'html', 'htm', 'xhtml', 'xhtm',
|
||||
'rtf', 'fb2', 'pdf', 'prc', 'odt',
|
||||
'epub', 'lit', 'lrx', 'lrf', 'mobi',
|
||||
'rb', 'imp'
|
||||
'rb', 'imp', 'azw'
|
||||
]
|
||||
|
||||
# The priorities for loading metadata from different file types
|
||||
@ -41,7 +41,9 @@ def metadata_from_formats(formats):
|
||||
for path, ext in zip(formats, extensions):
|
||||
with open(path, 'rb') as stream:
|
||||
try:
|
||||
mi.smart_update(get_metadata(stream, stream_type=ext, use_libprs_metadata=True))
|
||||
newmi = get_metadata(stream, stream_type=ext,
|
||||
use_libprs_metadata=True)
|
||||
mi.smart_update(newmi)
|
||||
except:
|
||||
continue
|
||||
if getattr(mi, 'application_id', None) is not None:
|
||||
@ -58,7 +60,7 @@ def get_metadata(stream, stream_type='lrf', use_libprs_metadata=False):
|
||||
if stream_type: stream_type = stream_type.lower()
|
||||
if stream_type in ('html', 'html', 'xhtml', 'xhtm', 'xml'):
|
||||
stream_type = 'html'
|
||||
if stream_type in ('mobi', 'prc'):
|
||||
if stream_type in ('mobi', 'prc', 'azw'):
|
||||
stream_type = 'mobi'
|
||||
if stream_type in ('odt', 'ods', 'odp', 'odg', 'odf'):
|
||||
stream_type = 'odt'
|
||||
|
@ -444,6 +444,7 @@ class OPF(object):
|
||||
if not hasattr(stream, 'read'):
|
||||
stream = open(stream, 'rb')
|
||||
self.basedir = self.base_dir = basedir
|
||||
self.path_to_html_toc = None
|
||||
raw, self.encoding = xml_to_unicode(stream.read(), strip_encoding_pats=True, resolve_entities=True)
|
||||
raw = raw[raw.find('<'):]
|
||||
self.root = etree.fromstring(raw, self.PARSER)
|
||||
@ -495,6 +496,7 @@ class OPF(object):
|
||||
if f:
|
||||
self.toc.read_ncx_toc(f[0])
|
||||
else:
|
||||
self.path_to_html_toc = toc
|
||||
self.toc.read_html_toc(toc)
|
||||
except:
|
||||
pass
|
||||
|
40
src/calibre/ebooks/metadata/topaz.py
Normal file
40
src/calibre/ebooks/metadata/topaz.py
Normal file
@ -0,0 +1,40 @@
|
||||
from __future__ import with_statement
|
||||
__license__ = 'GPL 3'
|
||||
__copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
''' Read metadata from Amazon's topaz format '''
|
||||
|
||||
def read_record(raw, name):
|
||||
idx = raw.find(name)
|
||||
if idx > -1:
|
||||
length = ord(raw[idx+len(name)])
|
||||
return raw[idx+len(name)+1:idx+len(name)+1+length]
|
||||
|
||||
def get_metadata(stream):
|
||||
raw = stream.read(8*1024)
|
||||
if not raw.startswith('TPZ'):
|
||||
raise ValueError('Not a Topaz file')
|
||||
first = raw.find('metadata')
|
||||
if first < 0:
|
||||
raise ValueError('Invalid Topaz file')
|
||||
second = raw.find('metadata', first+10)
|
||||
if second < 0:
|
||||
raise ValueError('Invalid Topaz file')
|
||||
raw = raw[second:second+1000]
|
||||
authors = read_record(raw, 'Authors')
|
||||
if authors:
|
||||
authors = authors.decode('utf-8', 'replace').split(';')
|
||||
else:
|
||||
authors = [_('Unknown')]
|
||||
title = read_record(raw, 'Title')
|
||||
if title:
|
||||
title = title.decode('utf-8', 'replace')
|
||||
else:
|
||||
raise ValueError('No metadata in file')
|
||||
from calibre.ebooks.metadata import MetaInformation
|
||||
return MetaInformation(title, authors)
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
print get_metadata(open(sys.argv[1], 'rb'))
|
@ -92,6 +92,8 @@ class BookHeader(object):
|
||||
self.sublanguage = 'NEUTRAL'
|
||||
self.exth_flag, self.exth = 0, None
|
||||
self.ancient = True
|
||||
self.first_image_index = -1
|
||||
self.mobi_version = 1
|
||||
else:
|
||||
self.ancient = False
|
||||
self.doctype = raw[16:20]
|
||||
@ -537,7 +539,7 @@ class MobiReader(object):
|
||||
os.makedirs(output_dir)
|
||||
image_index = 0
|
||||
self.image_names = []
|
||||
start = self.book_header.first_image_index
|
||||
start = getattr(self.book_header, 'first_image_index', -1)
|
||||
if start > self.num_sections or start < 0:
|
||||
# BAEN PRC files have bad headers
|
||||
start=0
|
||||
|
@ -31,7 +31,7 @@ from calibre.ebooks.oeb.transforms.htmltoc import HTMLTOCAdder
|
||||
from calibre.ebooks.oeb.transforms.manglecase import CaseMangler
|
||||
from calibre.ebooks.mobi.palmdoc import compress_doc
|
||||
from calibre.ebooks.mobi.langcodes import iana2mobi
|
||||
from calibre.ebooks.mobi.mobiml import MBP_NS, MBP, MobiMLizer
|
||||
from calibre.ebooks.mobi.mobiml import MBP_NS, MobiMLizer
|
||||
from calibre.customize.ui import run_plugins_on_postprocess
|
||||
from calibre.utils.config import Config, StringConfig
|
||||
|
||||
@ -160,7 +160,7 @@ class Serializer(object):
|
||||
hrefs = self.oeb.manifest.hrefs
|
||||
buffer.write('<guide>')
|
||||
for ref in self.oeb.guide.values():
|
||||
path, frag = urldefrag(ref.href)
|
||||
path = urldefrag(ref.href)[0]
|
||||
if hrefs[path].media_type not in OEB_DOCS:
|
||||
continue
|
||||
buffer.write('<reference type="')
|
||||
@ -455,8 +455,6 @@ class MobiWriter(object):
|
||||
self._oeb.logger.info('Serializing images...')
|
||||
images = [(index, href) for href, index in self._images.items()]
|
||||
images.sort()
|
||||
metadata = self._oeb.metadata
|
||||
coverid = metadata.cover[0] if metadata.cover else None
|
||||
for _, href in images:
|
||||
item = self._oeb.manifest.hrefs[href]
|
||||
try:
|
||||
|
@ -159,7 +159,7 @@ class Stylizer(object):
|
||||
for _, _, cssdict, text, _ in rules:
|
||||
try:
|
||||
selector = CSSSelector(text)
|
||||
except ExpressionError:
|
||||
except (AssertionError, ExpressionError, etree.XPathSyntaxError):
|
||||
continue
|
||||
for elem in selector(tree):
|
||||
self.style(elem)._update_cssdict(cssdict)
|
||||
|
@ -63,6 +63,8 @@ class HTMLTOCAdder(object):
|
||||
def __call__(self, oeb, context):
|
||||
if 'toc' in oeb.guide:
|
||||
return
|
||||
if not getattr(getattr(oeb, 'toc', False), 'nodes', False):
|
||||
return
|
||||
oeb.logger.info('Generating in-line TOC...')
|
||||
title = self.title or oeb.translate(DEFAULT_TITLE)
|
||||
style = self.style
|
||||
|
@ -224,7 +224,10 @@ class AddRecursive(Add):
|
||||
files = _('<p>Books with the same title as the following already '
|
||||
'exist in the database. Add them anyway?<ul>')
|
||||
for mi in self.duplicates:
|
||||
files += '<li>'+mi[0].title+'</li>\n'
|
||||
title = mi[0].title
|
||||
if not isinstance(title, unicode):
|
||||
title = title.decode(preferred_encoding, 'replace')
|
||||
files += '<li>'+title+'</li>\n'
|
||||
d = WarningDialog (_('Duplicates found!'),
|
||||
_('Duplicates found!'),
|
||||
files+'</ul></p>', parent=self._parent)
|
||||
|
@ -1,7 +1,8 @@
|
||||
<ui version="4.0" >
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MetadataSingleDialog</class>
|
||||
<widget class="QDialog" name="MetadataSingleDialog" >
|
||||
<property name="geometry" >
|
||||
<widget class="QDialog" name="MetadataSingleDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
@ -9,36 +10,36 @@
|
||||
<height>750</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy vsizetype="MinimumExpanding" hsizetype="MinimumExpanding" >
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="windowTitle" >
|
||||
<property name="windowTitle">
|
||||
<string>Edit Meta Information</string>
|
||||
</property>
|
||||
<property name="windowIcon" >
|
||||
<iconset resource="../images.qrc" >
|
||||
<property name="windowIcon">
|
||||
<iconset resource="../images.qrc">
|
||||
<normaloff>:/images/edit_input.svg</normaloff>:/images/edit_input.svg</iconset>
|
||||
</property>
|
||||
<property name="sizeGripEnabled" >
|
||||
<property name="sizeGripEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="modal" >
|
||||
<property name="modal">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_6" >
|
||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||
<item>
|
||||
<widget class="QScrollArea" name="scrollArea" >
|
||||
<property name="frameShape" >
|
||||
<widget class="QScrollArea" name="scrollArea">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="widgetResizable" >
|
||||
<property name="widgetResizable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QWidget" name="scrollAreaWidgetContents" >
|
||||
<property name="geometry" >
|
||||
<widget class="QWidget" name="scrollAreaWidgetContents">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
@ -46,65 +47,65 @@
|
||||
<height>710</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5" >
|
||||
<property name="margin" >
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QWidget" native="1" name="central_widget" >
|
||||
<property name="minimumSize" >
|
||||
<widget class="QWidget" name="central_widget" native="true">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>800</width>
|
||||
<height>665</height>
|
||||
</size>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3" >
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QSplitter" name="splitter" >
|
||||
<property name="orientation" >
|
||||
<widget class="QSplitter" name="splitter">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<widget class="QWidget" name="layoutWidget" >
|
||||
<layout class="QVBoxLayout" >
|
||||
<widget class="QWidget" name="layoutWidget">
|
||||
<layout class="QVBoxLayout">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="meta_box" >
|
||||
<property name="title" >
|
||||
<widget class="QGroupBox" name="meta_box">
|
||||
<property name="title">
|
||||
<string>Meta information</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3" >
|
||||
<item row="0" column="0" >
|
||||
<widget class="QLabel" name="label" >
|
||||
<property name="text" >
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>&Title: </string>
|
||||
</property>
|
||||
<property name="alignment" >
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="buddy" >
|
||||
<property name="buddy">
|
||||
<cstring>title</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" >
|
||||
<widget class="QLineEdit" name="title" >
|
||||
<property name="toolTip" >
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="title">
|
||||
<property name="toolTip">
|
||||
<string>Change the title of this book</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item rowspan="2" row="0" column="2" >
|
||||
<widget class="QToolButton" name="swap_button" >
|
||||
<property name="toolTip" >
|
||||
<item row="0" column="2" rowspan="2">
|
||||
<widget class="QToolButton" name="swap_button">
|
||||
<property name="toolTip">
|
||||
<string>Swap the author and title</string>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon" >
|
||||
<iconset resource="../images.qrc" >
|
||||
<property name="icon">
|
||||
<iconset resource="../images.qrc">
|
||||
<normaloff>:/images/swap.svg</normaloff>:/images/swap.svg</iconset>
|
||||
</property>
|
||||
<property name="iconSize" >
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>16</width>
|
||||
<height>16</height>
|
||||
@ -112,305 +113,305 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" >
|
||||
<widget class="QLabel" name="label_2" >
|
||||
<property name="text" >
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>&Author(s): </string>
|
||||
</property>
|
||||
<property name="alignment" >
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="buddy" >
|
||||
<property name="buddy">
|
||||
<cstring>authors</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" >
|
||||
<widget class="QLabel" name="label_8" >
|
||||
<property name="text" >
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="text">
|
||||
<string>Author S&ort: </string>
|
||||
</property>
|
||||
<property name="alignment" >
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="buddy" >
|
||||
<property name="buddy">
|
||||
<cstring>author_sort</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1" colspan="2" >
|
||||
<layout class="QHBoxLayout" name="horizontalLayout" >
|
||||
<item row="2" column="1" colspan="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="author_sort" >
|
||||
<property name="toolTip" >
|
||||
<widget class="QLineEdit" name="author_sort">
|
||||
<property name="toolTip">
|
||||
<string>Specify how the author(s) of this book should be sorted. For example Charles Dickens should be sorted as Dickens, Charles.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="auto_author_sort" >
|
||||
<property name="toolTip" >
|
||||
<widget class="QToolButton" name="auto_author_sort">
|
||||
<property name="toolTip">
|
||||
<string>Automatically create the author sort entry based on the current author entry</string>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon" >
|
||||
<iconset resource="../images.qrc" >
|
||||
<property name="icon">
|
||||
<iconset resource="../images.qrc">
|
||||
<normaloff>:/images/auto_author_sort.svg</normaloff>:/images/auto_author_sort.svg</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="3" column="0" >
|
||||
<widget class="QLabel" name="label_6" >
|
||||
<property name="text" >
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>&Rating:</string>
|
||||
</property>
|
||||
<property name="alignment" >
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="buddy" >
|
||||
<property name="buddy">
|
||||
<cstring>rating</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1" colspan="2" >
|
||||
<widget class="QSpinBox" name="rating" >
|
||||
<property name="toolTip" >
|
||||
<item row="3" column="1" colspan="2">
|
||||
<widget class="QSpinBox" name="rating">
|
||||
<property name="toolTip">
|
||||
<string>Rating of this book. 0-5 stars</string>
|
||||
</property>
|
||||
<property name="whatsThis" >
|
||||
<property name="whatsThis">
|
||||
<string>Rating of this book. 0-5 stars</string>
|
||||
</property>
|
||||
<property name="buttonSymbols" >
|
||||
<property name="buttonSymbols">
|
||||
<enum>QAbstractSpinBox::PlusMinus</enum>
|
||||
</property>
|
||||
<property name="suffix" >
|
||||
<property name="suffix">
|
||||
<string> stars</string>
|
||||
</property>
|
||||
<property name="maximum" >
|
||||
<property name="maximum">
|
||||
<number>5</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0" >
|
||||
<widget class="QLabel" name="label_3" >
|
||||
<property name="text" >
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>&Publisher: </string>
|
||||
</property>
|
||||
<property name="alignment" >
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="buddy" >
|
||||
<property name="buddy">
|
||||
<cstring>publisher</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0" >
|
||||
<widget class="QLabel" name="label_4" >
|
||||
<property name="text" >
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Ta&gs: </string>
|
||||
</property>
|
||||
<property name="alignment" >
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="buddy" >
|
||||
<property name="buddy">
|
||||
<cstring>tags</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1" colspan="2" >
|
||||
<layout class="QHBoxLayout" name="_2" >
|
||||
<item row="5" column="1" colspan="2">
|
||||
<layout class="QHBoxLayout" name="_2">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="tags" >
|
||||
<property name="toolTip" >
|
||||
<string>Tags categorize the book. This is particularly useful while searching. <br><br>They can be any words or phrases, separated by commas.</string>
|
||||
<widget class="QLineEdit" name="tags">
|
||||
<property name="toolTip">
|
||||
<string>Tags categorize the book. This is particularly useful while searching. <br><br>They can be any words or phrases, separated by commas.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="tag_editor_button" >
|
||||
<property name="toolTip" >
|
||||
<widget class="QToolButton" name="tag_editor_button">
|
||||
<property name="toolTip">
|
||||
<string>Open Tag Editor</string>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<property name="text">
|
||||
<string>Open Tag Editor</string>
|
||||
</property>
|
||||
<property name="icon" >
|
||||
<iconset resource="../images.qrc" >
|
||||
<property name="icon">
|
||||
<iconset resource="../images.qrc">
|
||||
<normaloff>:/images/chapters.svg</normaloff>:/images/chapters.svg</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="6" column="0" >
|
||||
<widget class="QLabel" name="label_7" >
|
||||
<property name="text" >
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>&Series:</string>
|
||||
</property>
|
||||
<property name="textFormat" >
|
||||
<property name="textFormat">
|
||||
<enum>Qt::PlainText</enum>
|
||||
</property>
|
||||
<property name="alignment" >
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="buddy" >
|
||||
<property name="buddy">
|
||||
<cstring>series</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1" colspan="2" >
|
||||
<layout class="QHBoxLayout" name="_3" >
|
||||
<property name="spacing" >
|
||||
<item row="6" column="1" colspan="2">
|
||||
<layout class="QHBoxLayout" name="_3">
|
||||
<property name="spacing">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QComboBox" name="series" >
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy vsizetype="Fixed" hsizetype="MinimumExpanding" >
|
||||
<widget class="QComboBox" name="series">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip" >
|
||||
<property name="toolTip">
|
||||
<string>List of known series. You can add new series.</string>
|
||||
</property>
|
||||
<property name="whatsThis" >
|
||||
<property name="whatsThis">
|
||||
<string>List of known series. You can add new series.</string>
|
||||
</property>
|
||||
<property name="editable" >
|
||||
<property name="editable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="insertPolicy" >
|
||||
<property name="insertPolicy">
|
||||
<enum>QComboBox::InsertAlphabetically</enum>
|
||||
</property>
|
||||
<property name="sizeAdjustPolicy" >
|
||||
<property name="sizeAdjustPolicy">
|
||||
<enum>QComboBox::AdjustToContents</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="remove_series_button" >
|
||||
<property name="toolTip" >
|
||||
<widget class="QToolButton" name="remove_series_button">
|
||||
<property name="toolTip">
|
||||
<string>Remove unused series (Series that have no books)</string>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon" >
|
||||
<iconset resource="../images.qrc" >
|
||||
<property name="icon">
|
||||
<iconset resource="../images.qrc">
|
||||
<normaloff>:/images/trash.svg</normaloff>:/images/trash.svg</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="7" column="1" colspan="2" >
|
||||
<widget class="QSpinBox" name="series_index" >
|
||||
<property name="enabled" >
|
||||
<item row="7" column="1" colspan="2">
|
||||
<widget class="QSpinBox" name="series_index">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="toolTip" >
|
||||
<property name="toolTip">
|
||||
<string>Series index.</string>
|
||||
</property>
|
||||
<property name="whatsThis" >
|
||||
<property name="whatsThis">
|
||||
<string>Series index.</string>
|
||||
</property>
|
||||
<property name="prefix" >
|
||||
<property name="prefix">
|
||||
<string>Book </string>
|
||||
</property>
|
||||
<property name="minimum" >
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum" >
|
||||
<property name="maximum">
|
||||
<number>10000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0" >
|
||||
<widget class="QLabel" name="label_9" >
|
||||
<property name="text" >
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="text">
|
||||
<string>IS&BN:</string>
|
||||
</property>
|
||||
<property name="alignment" >
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="buddy" >
|
||||
<property name="buddy">
|
||||
<cstring>isbn</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1" colspan="2" >
|
||||
<widget class="QLineEdit" name="isbn" />
|
||||
<item row="8" column="1" colspan="2">
|
||||
<widget class="QLineEdit" name="isbn"/>
|
||||
</item>
|
||||
<item row="4" column="1" >
|
||||
<widget class="QComboBox" name="publisher" >
|
||||
<property name="editable" >
|
||||
<item row="4" column="1">
|
||||
<widget class="QComboBox" name="publisher">
|
||||
<property name="editable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1" >
|
||||
<widget class="QLineEdit" name="authors" />
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="authors"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_2" >
|
||||
<property name="title" >
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="title">
|
||||
<string>Comments</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_4" >
|
||||
<item row="0" column="0" >
|
||||
<widget class="QTextEdit" name="comments" />
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
<item row="0" column="0">
|
||||
<widget class="QTextEdit" name="comments"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="fetch_metadata_button" >
|
||||
<property name="text" >
|
||||
<string>Fetch metadata from server</string>
|
||||
<widget class="QPushButton" name="fetch_metadata_button">
|
||||
<property name="text">
|
||||
<string>&Fetch metadata from server</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="layoutWidget_2" >
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2" >
|
||||
<widget class="QWidget" name="layoutWidget_2">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="af_group_box" >
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy vsizetype="Minimum" hsizetype="Preferred" >
|
||||
<widget class="QGroupBox" name="af_group_box">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="title" >
|
||||
<property name="title">
|
||||
<string>Available Formats</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout" >
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout" >
|
||||
<item rowspan="3" row="0" column="0" >
|
||||
<widget class="QListWidget" name="formats" >
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy vsizetype="Minimum" hsizetype="Minimum" >
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0" rowspan="3">
|
||||
<widget class="QListWidget" name="formats">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize" >
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>130</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="iconSize" >
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>64</width>
|
||||
<height>64</height>
|
||||
@ -418,19 +419,19 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" >
|
||||
<widget class="QToolButton" name="add_format_button" >
|
||||
<property name="toolTip" >
|
||||
<item row="0" column="1">
|
||||
<widget class="QToolButton" name="add_format_button">
|
||||
<property name="toolTip">
|
||||
<string>Add a new format for this book to the database</string>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon" >
|
||||
<iconset resource="../images.qrc" >
|
||||
<property name="icon">
|
||||
<iconset resource="../images.qrc">
|
||||
<normaloff>:/images/add_book.svg</normaloff>:/images/add_book.svg</iconset>
|
||||
</property>
|
||||
<property name="iconSize" >
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>32</height>
|
||||
@ -438,19 +439,19 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1" >
|
||||
<widget class="QToolButton" name="remove_format_button" >
|
||||
<property name="toolTip" >
|
||||
<item row="2" column="1">
|
||||
<widget class="QToolButton" name="remove_format_button">
|
||||
<property name="toolTip">
|
||||
<string>Remove the selected formats for this book from the database.</string>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon" >
|
||||
<iconset resource="../images.qrc" >
|
||||
<property name="icon">
|
||||
<iconset resource="../images.qrc">
|
||||
<normaloff>:/images/trash.svg</normaloff>:/images/trash.svg</iconset>
|
||||
</property>
|
||||
<property name="iconSize" >
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>32</height>
|
||||
@ -458,19 +459,19 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1" >
|
||||
<widget class="QToolButton" name="button_set_cover" >
|
||||
<property name="toolTip" >
|
||||
<item row="1" column="1">
|
||||
<widget class="QToolButton" name="button_set_cover">
|
||||
<property name="toolTip">
|
||||
<string>Set the cover for the book from the selected format</string>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon" >
|
||||
<iconset resource="../images.qrc" >
|
||||
<property name="icon">
|
||||
<iconset resource="../images.qrc">
|
||||
<normaloff>:/images/book.svg</normaloff>:/images/book.svg</iconset>
|
||||
</property>
|
||||
<property name="iconSize" >
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>32</height>
|
||||
@ -485,96 +486,96 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="bc_box" >
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy vsizetype="Expanding" hsizetype="Preferred" >
|
||||
<widget class="QGroupBox" name="bc_box">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>10</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="title" >
|
||||
<property name="title">
|
||||
<string>Book Cover</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4" >
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<widget class="ImageView" name="cover" >
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
|
||||
<widget class="ImageView" name="cover">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap" >
|
||||
<pixmap resource="../images.qrc" >:/images/book.svg</pixmap>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="../images.qrc">:/images/book.svg</pixmap>
|
||||
</property>
|
||||
<property name="scaledContents" >
|
||||
<property name="scaledContents">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="_4" >
|
||||
<property name="spacing" >
|
||||
<layout class="QVBoxLayout" name="_4">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="sizeConstraint" >
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetMaximumSize</enum>
|
||||
</property>
|
||||
<property name="margin" >
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_5" >
|
||||
<property name="text" >
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Change &cover image:</string>
|
||||
</property>
|
||||
<property name="buddy" >
|
||||
<property name="buddy">
|
||||
<cstring>cover_path</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="_5" >
|
||||
<property name="spacing" >
|
||||
<layout class="QHBoxLayout" name="_5">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="margin" >
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="cover_path" >
|
||||
<property name="readOnly" >
|
||||
<widget class="QLineEdit" name="cover_path">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="cover_button" >
|
||||
<property name="toolTip" >
|
||||
<widget class="QToolButton" name="cover_button">
|
||||
<property name="toolTip">
|
||||
<string>Browse for an image to use as the cover of this book.</string>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon" >
|
||||
<iconset resource="../images.qrc" >
|
||||
<property name="icon">
|
||||
<iconset resource="../images.qrc">
|
||||
<normaloff>:/images/document_open.svg</normaloff>:/images/document_open.svg</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="reset_cover" >
|
||||
<property name="toolTip" >
|
||||
<widget class="QToolButton" name="reset_cover">
|
||||
<property name="toolTip">
|
||||
<string>Reset cover to default</string>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon" >
|
||||
<iconset resource="../images.qrc" >
|
||||
<property name="icon">
|
||||
<iconset resource="../images.qrc">
|
||||
<normaloff>:/images/trash.svg</normaloff>:/images/trash.svg</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
@ -584,21 +585,21 @@
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="_6" >
|
||||
<layout class="QHBoxLayout" name="_6">
|
||||
<item>
|
||||
<widget class="QPushButton" name="fetch_cover_button" >
|
||||
<property name="text" >
|
||||
<string>Fetch cover image from server</string>
|
||||
<widget class="QPushButton" name="fetch_cover_button">
|
||||
<property name="text">
|
||||
<string>Fetch &cover image from server</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="password_button" >
|
||||
<property name="toolTip" >
|
||||
<widget class="QPushButton" name="password_button">
|
||||
<property name="toolTip">
|
||||
<string>Change the username and/or password for your account at LibraryThing.com</string>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>Change password</string>
|
||||
<property name="text">
|
||||
<string>Change &password</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@ -619,11 +620,11 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="button_box" >
|
||||
<property name="orientation" >
|
||||
<widget class="QDialogButtonBox" name="button_box">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons" >
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
@ -666,7 +667,7 @@
|
||||
<tabstop>button_box</tabstop>
|
||||
</tabstops>
|
||||
<resources>
|
||||
<include location="../images.qrc" />
|
||||
<include location="../images.qrc"/>
|
||||
</resources>
|
||||
<connections>
|
||||
<connection>
|
||||
@ -675,11 +676,11 @@
|
||||
<receiver>MetadataSingleDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<hint type="sourcelabel">
|
||||
<x>261</x>
|
||||
<y>710</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
@ -691,11 +692,11 @@
|
||||
<receiver>MetadataSingleDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<hint type="sourcelabel">
|
||||
<x>329</x>
|
||||
<y>710</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
|
BIN
src/calibre/gui2/images/news/politico.png
Normal file
BIN
src/calibre/gui2/images/news/politico.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 572 B |
@ -94,6 +94,7 @@ class DateDelegate(QStyledItemDelegate):
|
||||
def createEditor(self, parent, option, index):
|
||||
qde = QStyledItemDelegate.createEditor(self, parent, option, index)
|
||||
qde.setDisplayFormat('MM/dd/yyyy')
|
||||
qde.setMinimumDate(QDate(100,1,1))
|
||||
return qde
|
||||
|
||||
class BooksModel(QAbstractTableModel):
|
||||
|
@ -238,6 +238,7 @@ class Main(MainWindow, Ui_MainWindow):
|
||||
|
||||
QObject.connect(self.config_button, SIGNAL('clicked(bool)'), self.do_config)
|
||||
self.connect(self.preferences_action, SIGNAL('triggered(bool)'), self.do_config)
|
||||
self.connect(self.action_preferences, SIGNAL('triggered(bool)'), self.do_config)
|
||||
QObject.connect(self.advanced_search_button, SIGNAL('clicked(bool)'), self.do_advanced_search)
|
||||
|
||||
####################### Library view ########################
|
||||
@ -1220,12 +1221,14 @@ class Main(MainWindow, Ui_MainWindow):
|
||||
if ext in config['internally_viewed_formats']:
|
||||
if ext == 'LRF':
|
||||
args = ['lrfviewer', name]
|
||||
self.job_manager.server.run_free_job('lrfviewer', kwdargs=dict(args=args))
|
||||
self.job_manager.server.run_free_job('lrfviewer',
|
||||
kwdargs=dict(args=args))
|
||||
else:
|
||||
args = ['ebook-viewer', name]
|
||||
if isosx:
|
||||
args.append('--raise-window')
|
||||
self.job_manager.server.run_free_job('ebook-viewer', kwdargs=dict(args=args))
|
||||
self.job_manager.server.run_free_job('ebook-viewer',
|
||||
kwdargs=dict(args=args))
|
||||
else:
|
||||
QDesktopServices.openUrl(QUrl('file:'+name))#launch(name)
|
||||
time.sleep(5) # User feedback
|
||||
@ -1320,7 +1323,7 @@ class Main(MainWindow, Ui_MainWindow):
|
||||
|
||||
############################### Do config ##################################
|
||||
|
||||
def do_config(self):
|
||||
def do_config(self, *args):
|
||||
if self.job_manager.has_jobs():
|
||||
d = error_dialog(self, _('Cannot configure'), _('Cannot configure while there are running jobs.'))
|
||||
d.exec_()
|
||||
|
@ -1,149 +1,150 @@
|
||||
<ui version="4.0" >
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<author>Kovid Goyal</author>
|
||||
<class>MainWindow</class>
|
||||
<widget class="QMainWindow" name="MainWindow" >
|
||||
<property name="geometry" >
|
||||
<widget class="QMainWindow" name="MainWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>865</width>
|
||||
<width>1012</width>
|
||||
<height>822</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy vsizetype="Preferred" hsizetype="Preferred" >
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="contextMenuPolicy" >
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::NoContextMenu</enum>
|
||||
</property>
|
||||
<property name="windowTitle" >
|
||||
<property name="windowTitle">
|
||||
<string>__appname__</string>
|
||||
</property>
|
||||
<property name="windowIcon" >
|
||||
<iconset resource="images.qrc" >
|
||||
<property name="windowIcon">
|
||||
<iconset resource="images.qrc">
|
||||
<normaloff>:/library</normaloff>:/library</iconset>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget" >
|
||||
<layout class="QGridLayout" name="gridLayout" >
|
||||
<item row="0" column="0" >
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3" >
|
||||
<widget class="QWidget" name="centralwidget">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="LocationView" name="location_view" >
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
|
||||
<widget class="LocationView" name="location_view">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize" >
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>100</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="verticalScrollBarPolicy" >
|
||||
<property name="verticalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||
</property>
|
||||
<property name="horizontalScrollBarPolicy" >
|
||||
<property name="horizontalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAsNeeded</enum>
|
||||
</property>
|
||||
<property name="tabKeyNavigation" >
|
||||
<property name="tabKeyNavigation">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="showDropIndicator" stdset="0" >
|
||||
<property name="showDropIndicator" stdset="0">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="iconSize" >
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="movement" >
|
||||
<property name="movement">
|
||||
<enum>QListView::Static</enum>
|
||||
</property>
|
||||
<property name="flow" >
|
||||
<property name="flow">
|
||||
<enum>QListView::LeftToRight</enum>
|
||||
</property>
|
||||
<property name="gridSize" >
|
||||
<property name="gridSize">
|
||||
<size>
|
||||
<width>175</width>
|
||||
<height>90</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="viewMode" >
|
||||
<property name="viewMode">
|
||||
<enum>QListView::ListMode</enum>
|
||||
</property>
|
||||
<property name="wordWrap" >
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="donate_button" >
|
||||
<property name="cursor" >
|
||||
<widget class="QToolButton" name="donate_button">
|
||||
<property name="cursor">
|
||||
<cursorShape>PointingHandCursor</cursorShape>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon" >
|
||||
<iconset resource="images.qrc" >
|
||||
<property name="icon">
|
||||
<iconset resource="images.qrc">
|
||||
<normaloff>:/images/donate.svg</normaloff>:/images/donate.svg</iconset>
|
||||
</property>
|
||||
<property name="iconSize" >
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>64</width>
|
||||
<height>64</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="autoRaise" >
|
||||
<property name="autoRaise">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3" >
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="vanity" >
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy vsizetype="Preferred" hsizetype="Preferred" >
|
||||
<widget class="QLabel" name="vanity">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize" >
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>90</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="textFormat" >
|
||||
<property name="textFormat">
|
||||
<enum>Qt::RichText</enum>
|
||||
</property>
|
||||
<property name="openExternalLinks" >
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2" >
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2" >
|
||||
<property name="text" >
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Output:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="output_format" >
|
||||
<property name="toolTip" >
|
||||
<widget class="QComboBox" name="output_format">
|
||||
<property name="toolTip">
|
||||
<string>Set the output format that is used when converting ebooks and downloading news</string>
|
||||
</property>
|
||||
</widget>
|
||||
@ -154,99 +155,99 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0" >
|
||||
<layout class="QHBoxLayout" >
|
||||
<property name="spacing" >
|
||||
<item row="1" column="0">
|
||||
<layout class="QHBoxLayout">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="margin" >
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QToolButton" name="advanced_search_button" >
|
||||
<property name="toolTip" >
|
||||
<widget class="QToolButton" name="advanced_search_button">
|
||||
<property name="toolTip">
|
||||
<string>Advanced search</string>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon" >
|
||||
<iconset resource="images.qrc" >
|
||||
<property name="icon">
|
||||
<iconset resource="images.qrc">
|
||||
<normaloff>:/images/search.svg</normaloff>:/images/search.svg</iconset>
|
||||
</property>
|
||||
<property name="shortcut" >
|
||||
<property name="shortcut">
|
||||
<string>Alt+S</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label" >
|
||||
<property name="text" >
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>&Search:</string>
|
||||
</property>
|
||||
<property name="buddy" >
|
||||
<property name="buddy">
|
||||
<cstring>search</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="SearchBox" name="search" >
|
||||
<property name="enabled" >
|
||||
<widget class="SearchBox" name="search">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy vsizetype="Fixed" hsizetype="Expanding" >
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="acceptDrops" >
|
||||
<property name="acceptDrops">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="toolTip" >
|
||||
<string>Search the list of books by title or author<br><br>Words separated by spaces are ANDed</string>
|
||||
<property name="toolTip">
|
||||
<string>Search the list of books by title or author<br><br>Words separated by spaces are ANDed</string>
|
||||
</property>
|
||||
<property name="whatsThis" >
|
||||
<string>Search the list of books by title, author, publisher, tags and comments<br><br>Words separated by spaces are ANDed</string>
|
||||
<property name="whatsThis">
|
||||
<string>Search the list of books by title, author, publisher, tags and comments<br><br>Words separated by spaces are ANDed</string>
|
||||
</property>
|
||||
<property name="autoFillBackground" >
|
||||
<property name="autoFillBackground">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="frame" >
|
||||
<property name="frame">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="clear_button" >
|
||||
<property name="toolTip" >
|
||||
<widget class="QToolButton" name="clear_button">
|
||||
<property name="toolTip">
|
||||
<string>Reset Quick Search</string>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon" >
|
||||
<iconset resource="images.qrc" >
|
||||
<property name="icon">
|
||||
<iconset resource="images.qrc">
|
||||
<normaloff>:/images/clear_left.svg</normaloff>:/images/clear_left.svg</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line" >
|
||||
<property name="orientation" >
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0" >
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>20</height>
|
||||
@ -255,77 +256,77 @@
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="config_button" >
|
||||
<property name="toolTip" >
|
||||
<widget class="QToolButton" name="config_button">
|
||||
<property name="toolTip">
|
||||
<string>Configuration</string>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon" >
|
||||
<iconset resource="images.qrc" >
|
||||
<property name="icon">
|
||||
<iconset resource="images.qrc">
|
||||
<normaloff>:/images/config.svg</normaloff>:/images/config.svg</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="0" >
|
||||
<widget class="QStackedWidget" name="stack" >
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
|
||||
<item row="2" column="0">
|
||||
<widget class="QStackedWidget" name="stack">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>100</horstretch>
|
||||
<verstretch>100</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="currentIndex" >
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="library" >
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2" >
|
||||
<widget class="QWidget" name="library">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout" >
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout" >
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="match_any" >
|
||||
<property name="text" >
|
||||
<widget class="QRadioButton" name="match_any">
|
||||
<property name="text">
|
||||
<string>Match any</string>
|
||||
</property>
|
||||
<property name="checked" >
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="match_all" >
|
||||
<property name="text" >
|
||||
<widget class="QRadioButton" name="match_all">
|
||||
<property name="text">
|
||||
<string>Match all</string>
|
||||
</property>
|
||||
<property name="checked" >
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="popularity" >
|
||||
<property name="text" >
|
||||
<widget class="QCheckBox" name="popularity">
|
||||
<property name="text">
|
||||
<string>Sort by &popularity</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="TagsView" name="tags_view" >
|
||||
<property name="tabKeyNavigation" >
|
||||
<widget class="TagsView" name="tags_view">
|
||||
<property name="tabKeyNavigation">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="alternatingRowColors" >
|
||||
<property name="alternatingRowColors">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="animated" >
|
||||
<property name="animated">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="headerHidden" >
|
||||
<property name="headerHidden">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
@ -333,35 +334,35 @@
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="BooksView" name="library_view" >
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
|
||||
<widget class="BooksView" name="library_view">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>100</horstretch>
|
||||
<verstretch>10</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="acceptDrops" >
|
||||
<property name="acceptDrops">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="dragEnabled" >
|
||||
<property name="dragEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="dragDropOverwriteMode" >
|
||||
<property name="dragDropOverwriteMode">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="dragDropMode" >
|
||||
<property name="dragDropMode">
|
||||
<enum>QAbstractItemView::DragDrop</enum>
|
||||
</property>
|
||||
<property name="alternatingRowColors" >
|
||||
<property name="alternatingRowColors">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="selectionBehavior" >
|
||||
<property name="selectionBehavior">
|
||||
<enum>QAbstractItemView::SelectRows</enum>
|
||||
</property>
|
||||
<property name="showGrid" >
|
||||
<property name="showGrid">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="wordWrap" >
|
||||
<property name="wordWrap">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
@ -370,76 +371,76 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="main_memory" >
|
||||
<layout class="QGridLayout" >
|
||||
<item row="0" column="0" >
|
||||
<widget class="DeviceBooksView" name="memory_view" >
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
|
||||
<widget class="QWidget" name="main_memory">
|
||||
<layout class="QGridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="DeviceBooksView" name="memory_view">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>100</horstretch>
|
||||
<verstretch>10</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="acceptDrops" >
|
||||
<property name="acceptDrops">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="dragEnabled" >
|
||||
<property name="dragEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="dragDropOverwriteMode" >
|
||||
<property name="dragDropOverwriteMode">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="dragDropMode" >
|
||||
<property name="dragDropMode">
|
||||
<enum>QAbstractItemView::DragDrop</enum>
|
||||
</property>
|
||||
<property name="alternatingRowColors" >
|
||||
<property name="alternatingRowColors">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="selectionBehavior" >
|
||||
<property name="selectionBehavior">
|
||||
<enum>QAbstractItemView::SelectRows</enum>
|
||||
</property>
|
||||
<property name="showGrid" >
|
||||
<property name="showGrid">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="wordWrap" >
|
||||
<property name="wordWrap">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="page" >
|
||||
<layout class="QGridLayout" >
|
||||
<item row="0" column="0" >
|
||||
<widget class="DeviceBooksView" name="card_view" >
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy vsizetype="Expanding" hsizetype="Preferred" >
|
||||
<widget class="QWidget" name="page">
|
||||
<layout class="QGridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="DeviceBooksView" name="card_view">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||
<horstretch>10</horstretch>
|
||||
<verstretch>10</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="acceptDrops" >
|
||||
<property name="acceptDrops">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="dragEnabled" >
|
||||
<property name="dragEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="dragDropOverwriteMode" >
|
||||
<property name="dragDropOverwriteMode">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="dragDropMode" >
|
||||
<property name="dragDropMode">
|
||||
<enum>QAbstractItemView::DragDrop</enum>
|
||||
</property>
|
||||
<property name="alternatingRowColors" >
|
||||
<property name="alternatingRowColors">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="selectionBehavior" >
|
||||
<property name="selectionBehavior">
|
||||
<enum>QAbstractItemView::SelectRows</enum>
|
||||
</property>
|
||||
<property name="showGrid" >
|
||||
<property name="showGrid">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="wordWrap" >
|
||||
<property name="wordWrap">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
@ -450,221 +451,237 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QToolBar" name="tool_bar" >
|
||||
<property name="minimumSize" >
|
||||
<widget class="QToolBar" name="tool_bar">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="contextMenuPolicy" >
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::PreventContextMenu</enum>
|
||||
</property>
|
||||
<property name="movable" >
|
||||
<property name="movable">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="orientation" >
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="iconSize" >
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>48</width>
|
||||
<height>48</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolButtonStyle" >
|
||||
<property name="toolButtonStyle">
|
||||
<enum>Qt::ToolButtonTextUnderIcon</enum>
|
||||
</property>
|
||||
<attribute name="toolBarArea" >
|
||||
<attribute name="toolBarArea">
|
||||
<enum>TopToolBarArea</enum>
|
||||
</attribute>
|
||||
<attribute name="toolBarBreak" >
|
||||
<attribute name="toolBarBreak">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<addaction name="action_add" />
|
||||
<addaction name="action_del" />
|
||||
<addaction name="action_edit" />
|
||||
<addaction name="separator" />
|
||||
<addaction name="action_sync" />
|
||||
<addaction name="action_save" />
|
||||
<addaction name="separator" />
|
||||
<addaction name="action_news" />
|
||||
<addaction name="action_convert" />
|
||||
<addaction name="action_view" />
|
||||
<addaction name="action_add"/>
|
||||
<addaction name="action_edit"/>
|
||||
<addaction name="action_convert"/>
|
||||
<addaction name="action_view"/>
|
||||
<addaction name="action_news"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="action_sync"/>
|
||||
<addaction name="action_save"/>
|
||||
<addaction name="action_del"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="action_preferences"/>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusBar" >
|
||||
<property name="mouseTracking" >
|
||||
<widget class="QStatusBar" name="statusBar">
|
||||
<property name="mouseTracking">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<action name="action_add" >
|
||||
<property name="icon" >
|
||||
<iconset resource="images.qrc" >
|
||||
<action name="action_add">
|
||||
<property name="icon">
|
||||
<iconset resource="images.qrc">
|
||||
<normaloff>:/images/add_book.svg</normaloff>:/images/add_book.svg</iconset>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<property name="text">
|
||||
<string>Add books</string>
|
||||
</property>
|
||||
<property name="shortcut" >
|
||||
<property name="shortcut">
|
||||
<string>A</string>
|
||||
</property>
|
||||
<property name="autoRepeat" >
|
||||
<property name="autoRepeat">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_del" >
|
||||
<property name="icon" >
|
||||
<iconset resource="images.qrc" >
|
||||
<action name="action_del">
|
||||
<property name="icon">
|
||||
<iconset resource="images.qrc">
|
||||
<normaloff>:/images/trash.svg</normaloff>:/images/trash.svg</iconset>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<property name="text">
|
||||
<string>Remove books</string>
|
||||
</property>
|
||||
<property name="toolTip" >
|
||||
<property name="toolTip">
|
||||
<string>Remove books</string>
|
||||
</property>
|
||||
<property name="shortcut" >
|
||||
<property name="shortcut">
|
||||
<string>Del</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_edit" >
|
||||
<property name="icon" >
|
||||
<iconset resource="images.qrc" >
|
||||
<action name="action_edit">
|
||||
<property name="icon">
|
||||
<iconset resource="images.qrc">
|
||||
<normaloff>:/images/edit_input.svg</normaloff>:/images/edit_input.svg</iconset>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<property name="text">
|
||||
<string>Edit meta information</string>
|
||||
</property>
|
||||
<property name="shortcut" >
|
||||
<property name="shortcut">
|
||||
<string>E</string>
|
||||
</property>
|
||||
<property name="autoRepeat" >
|
||||
<property name="autoRepeat">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_sync" >
|
||||
<property name="enabled" >
|
||||
<action name="action_sync">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="icon" >
|
||||
<iconset resource="images.qrc" >
|
||||
<property name="icon">
|
||||
<iconset resource="images.qrc">
|
||||
<normaloff>:/images/sync.svg</normaloff>:/images/sync.svg</iconset>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<property name="text">
|
||||
<string>Send to device</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_save" >
|
||||
<property name="icon" >
|
||||
<iconset resource="images.qrc" >
|
||||
<action name="action_save">
|
||||
<property name="icon">
|
||||
<iconset resource="images.qrc">
|
||||
<normaloff>:/images/save.svg</normaloff>:/images/save.svg</iconset>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<property name="text">
|
||||
<string>Save to disk</string>
|
||||
</property>
|
||||
<property name="shortcut" >
|
||||
<property name="shortcut">
|
||||
<string>S</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_news" >
|
||||
<property name="icon" >
|
||||
<iconset resource="images.qrc" >
|
||||
<action name="action_news">
|
||||
<property name="icon">
|
||||
<iconset resource="images.qrc">
|
||||
<normaloff>:/images/news.svg</normaloff>:/images/news.svg</iconset>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<property name="text">
|
||||
<string>Fetch news</string>
|
||||
</property>
|
||||
<property name="shortcut" >
|
||||
<property name="shortcut">
|
||||
<string>F</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_convert" >
|
||||
<property name="icon" >
|
||||
<iconset resource="images.qrc" >
|
||||
<action name="action_convert">
|
||||
<property name="icon">
|
||||
<iconset resource="images.qrc">
|
||||
<normaloff>:/images/convert.svg</normaloff>:/images/convert.svg</iconset>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<property name="text">
|
||||
<string>Convert E-books</string>
|
||||
</property>
|
||||
<property name="shortcut" >
|
||||
<property name="shortcut">
|
||||
<string>C</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_view" >
|
||||
<property name="icon" >
|
||||
<iconset resource="images.qrc" >
|
||||
<action name="action_view">
|
||||
<property name="icon">
|
||||
<iconset resource="images.qrc">
|
||||
<normaloff>:/images/view.svg</normaloff>:/images/view.svg</iconset>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<property name="text">
|
||||
<string>View</string>
|
||||
</property>
|
||||
<property name="shortcut" >
|
||||
<property name="shortcut">
|
||||
<string>V</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_open_containing_folder" >
|
||||
<property name="icon" >
|
||||
<iconset resource="images.qrc" >
|
||||
<action name="action_open_containing_folder">
|
||||
<property name="icon">
|
||||
<iconset resource="images.qrc">
|
||||
<normaloff>:/images/document_open.svg</normaloff>:/images/document_open.svg</iconset>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<property name="text">
|
||||
<string>Open containing folder</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_show_book_details" >
|
||||
<property name="icon" >
|
||||
<iconset resource="images.qrc" >
|
||||
<action name="action_show_book_details">
|
||||
<property name="icon">
|
||||
<iconset resource="images.qrc">
|
||||
<normaloff>:/images/dialog_information.svg</normaloff>:/images/dialog_information.svg</iconset>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<property name="text">
|
||||
<string>Show book details</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_books_by_same_author" >
|
||||
<property name="icon" >
|
||||
<iconset resource="images.qrc" >
|
||||
<action name="action_books_by_same_author">
|
||||
<property name="icon">
|
||||
<iconset resource="images.qrc">
|
||||
<normaloff>:/images/user_profile.svg</normaloff>:/images/user_profile.svg</iconset>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<property name="text">
|
||||
<string>Books by same author</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_books_in_this_series" >
|
||||
<property name="icon" >
|
||||
<iconset resource="images.qrc" >
|
||||
<action name="action_books_in_this_series">
|
||||
<property name="icon">
|
||||
<iconset resource="images.qrc">
|
||||
<normaloff>:/images/books_in_series.svg</normaloff>:/images/books_in_series.svg</iconset>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<property name="text">
|
||||
<string>Books in this series</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_books_by_this_publisher" >
|
||||
<property name="icon" >
|
||||
<iconset resource="images.qrc" >
|
||||
<action name="action_books_by_this_publisher">
|
||||
<property name="icon">
|
||||
<iconset resource="images.qrc">
|
||||
<normaloff>:/images/publisher.png</normaloff>:/images/publisher.png</iconset>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<property name="text">
|
||||
<string>Books by this publisher</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_books_with_the_same_tags" >
|
||||
<property name="icon" >
|
||||
<iconset resource="images.qrc" >
|
||||
<action name="action_books_with_the_same_tags">
|
||||
<property name="icon">
|
||||
<iconset resource="images.qrc">
|
||||
<normaloff>:/images/tags.svg</normaloff>:/images/tags.svg</iconset>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<property name="text">
|
||||
<string>Books with the same tags</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_send_specific_format_to_device" >
|
||||
<property name="icon" >
|
||||
<iconset resource="images.qrc" >
|
||||
<action name="action_send_specific_format_to_device">
|
||||
<property name="icon">
|
||||
<iconset resource="images.qrc">
|
||||
<normaloff>:/images/book.svg</normaloff>:/images/book.svg</iconset>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<property name="text">
|
||||
<string>Send specific format to device</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_preferences">
|
||||
<property name="icon">
|
||||
<iconset resource="images.qrc">
|
||||
<normaloff>:/images/config.svg</normaloff>:/images/config.svg</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Preferences</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Configure calibre</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+P</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
@ -694,7 +711,7 @@
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="images.qrc" />
|
||||
<include location="images.qrc"/>
|
||||
</resources>
|
||||
<connections>
|
||||
<connection>
|
||||
@ -703,11 +720,11 @@
|
||||
<receiver>search</receiver>
|
||||
<slot>clear()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<hint type="sourcelabel">
|
||||
<x>787</x>
|
||||
<y>215</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<hint type="destinationlabel">
|
||||
<x>755</x>
|
||||
<y>213</y>
|
||||
</hint>
|
||||
|
@ -450,7 +450,9 @@ class DocumentView(QWebView):
|
||||
self.manager.scrolled(self.scroll_fraction)
|
||||
|
||||
def wheel_event(self, down=True):
|
||||
QWebView.wheelEvent(self, QWheelEvent(QPoint(100, 100), (-120 if down else 120), Qt.NoButton, Qt.NoModifier))
|
||||
QWebView.wheelEvent(self,
|
||||
QWheelEvent(QPoint(100, 100), (-120 if down else 120),
|
||||
Qt.NoButton, Qt.NoModifier))
|
||||
|
||||
def next_page(self):
|
||||
if self.document.at_bottom:
|
||||
@ -538,6 +540,26 @@ class DocumentView(QWebView):
|
||||
self.next_page()
|
||||
elif key in [Qt.Key_PageUp, Qt.Key_Backspace, Qt.Key_Up]:
|
||||
self.previous_page()
|
||||
elif key in [Qt.Key_Home]:
|
||||
if event.modifiers() & Qt.ControlModifier:
|
||||
if self.manager is not None:
|
||||
self.manager.goto_start()
|
||||
else:
|
||||
self.scroll_to(0)
|
||||
elif key in [Qt.Key_End]:
|
||||
if event.modifiers() & Qt.ControlModifier:
|
||||
if self.manager is not None:
|
||||
self.manager.goto_end()
|
||||
else:
|
||||
self.scroll_to(1)
|
||||
elif key in [Qt.Key_J]:
|
||||
self.wheel_event()
|
||||
elif key in [Qt.Key_K]:
|
||||
self.wheel_event(down=False)
|
||||
elif key in [Qt.Key_H]:
|
||||
self.scroll_by(x=-15)
|
||||
elif key in [Qt.Key_L]:
|
||||
self.scroll_by(x=15)
|
||||
else:
|
||||
return QWebView.keyPressEvent(self, event)
|
||||
|
||||
|
@ -342,6 +342,12 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
|
||||
if pos is not None:
|
||||
self.goto_page(pos)
|
||||
|
||||
def goto_start(self):
|
||||
self.goto_page(1)
|
||||
|
||||
def goto_end(self):
|
||||
self.goto_page(self.pos.maximum())
|
||||
|
||||
def goto_page(self, new_page):
|
||||
if self.current_page is not None:
|
||||
for page in self.iterator.spine:
|
||||
@ -605,7 +611,7 @@ def config(defaults=None):
|
||||
else:
|
||||
c = StringConfig(defaults, desc)
|
||||
|
||||
c.add_opt('--raise-window', default=False,
|
||||
c.add_opt('raise_window', ['--raise-window'], default=False,
|
||||
help=_('If specified, viewer window will try to come to the '
|
||||
'front when started.'))
|
||||
return c
|
||||
|
@ -244,7 +244,10 @@ def do_add(db, paths, one_book_per_directory, recurse, add_duplicates):
|
||||
if os.path.isdir(path):
|
||||
dirs.append(path)
|
||||
else:
|
||||
if os.path.exists(path):
|
||||
files.append(path)
|
||||
else:
|
||||
print path, 'not found'
|
||||
|
||||
formats, metadata = [], []
|
||||
for book in files:
|
||||
@ -262,12 +265,14 @@ def do_add(db, paths, one_book_per_directory, recurse, add_duplicates):
|
||||
formats.append(format)
|
||||
metadata.append(mi)
|
||||
|
||||
file_duplicates = db.add_books(files, formats, metadata, add_duplicates=add_duplicates)
|
||||
if not file_duplicates[0]:
|
||||
file_duplicates = []
|
||||
else:
|
||||
if files:
|
||||
file_duplicates = db.add_books(files, formats, metadata,
|
||||
add_duplicates=add_duplicates)
|
||||
if file_duplicates:
|
||||
file_duplicates = file_duplicates[0]
|
||||
|
||||
|
||||
dir_dups = []
|
||||
for dir in dirs:
|
||||
if recurse:
|
||||
@ -286,7 +291,9 @@ def do_add(db, paths, one_book_per_directory, recurse, add_duplicates):
|
||||
db.import_book(mi, formats)
|
||||
else:
|
||||
if dir_dups or file_duplicates:
|
||||
print >>sys.stderr, _('The following books were not added as they already exist in the database (see --duplicates option):')
|
||||
print >>sys.stderr, _('The following books were not added as '
|
||||
'they already exist in the database '
|
||||
'(see --duplicates option):')
|
||||
for mi, formats in dir_dups:
|
||||
title = mi.title
|
||||
if isinstance(title, unicode):
|
||||
|
@ -23,6 +23,8 @@ from calibre.resources import jquery, server_resources, build_time
|
||||
from calibre.library import server_config as config
|
||||
from calibre.library.database2 import LibraryDatabase2, FIELD_MAP
|
||||
from calibre.utils.config import config_dir
|
||||
from calibre.utils.mdns import publish as publish_zeroconf, \
|
||||
stop_server as stop_zeroconf
|
||||
|
||||
build_time = datetime.strptime(build_time, '%d %m %Y %H%M%S')
|
||||
server_resources['jquery.js'] = jquery
|
||||
@ -171,11 +173,14 @@ class LibraryServer(object):
|
||||
try:
|
||||
cherrypy.engine.start()
|
||||
self.is_running = True
|
||||
publish_zeroconf('Books in calibre', '_stanza._tcp',
|
||||
self.opts.port, {'path':'/stanza'})
|
||||
cherrypy.engine.block()
|
||||
except Exception, e:
|
||||
self.exception = e
|
||||
finally:
|
||||
self.is_running = False
|
||||
stop_zeroconf()
|
||||
|
||||
def exit(self):
|
||||
cherrypy.engine.exit()
|
||||
@ -332,7 +337,11 @@ class LibraryServer(object):
|
||||
@expose
|
||||
def index(self, **kwargs):
|
||||
'The / URL'
|
||||
stanza = cherrypy.request.headers.get('Stanza-Device-Name', 919)
|
||||
if stanza == 919:
|
||||
return self.static('index.html')
|
||||
return self.stanza()
|
||||
|
||||
|
||||
@expose
|
||||
def get(self, what, id):
|
||||
|
@ -123,13 +123,12 @@ turned into a collection on the reader. Note that the PRS-500 does not support c
|
||||
How do I use |app| with my iPhone?
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
First install the Stanza reader on your iPhone from http://www.lexcycle.com . Then,
|
||||
* Set the output format for calibre to EPUB (this can be done in the configuration dialog accessed by the little hammer icon next to the search bar)
|
||||
|
||||
* Set the output format for calibre to EPUB (The output format can be set next to the big red heart)
|
||||
* Convert the books you want to read on your iPhone to EPUB format by selecting them and clicking the Convert button.
|
||||
* Turn on the Content Server in the configurations dialog and leave |app| running.
|
||||
* In the Stanza reader on your iPhone, add a new catalog. The URL of the catalog is of the form
|
||||
``http://10.34.56.89:8080/stanza``, where you should replace the IP address ``10.34.56.89``
|
||||
with the IP address of your computer. Stanza will the use the |app| content server to access all the
|
||||
EPUB books in your |app| database.
|
||||
* Turn on the Content Server in |app|'s preferences and leave |app| running.
|
||||
|
||||
Now you should be able to access your books on your iPhone.
|
||||
|
||||
Library Management
|
||||
------------------
|
||||
|
@ -227,7 +227,8 @@ class WorkerMother(object):
|
||||
return env
|
||||
|
||||
def spawn_free_spirit_osx(self, arg, type='free_spirit'):
|
||||
script = 'from calibre.parallel import main; main(args=["calibre-parallel", %s]);'%repr(arg)
|
||||
script = ('from calibre.parallel import main; '
|
||||
'main(args=["calibre-parallel", %s]);')%repr(arg)
|
||||
exe = self.gui_executable if type == 'free_spirit' else self.executable
|
||||
cmdline = [exe, '-c', self.prefix+script]
|
||||
child = WorkerStatus(subprocess.Popen(cmdline, env=self.get_env()))
|
||||
|
@ -177,11 +177,11 @@ else:
|
||||
compatibility='%s works on OS X Tiger and above.'%(__appname__,),
|
||||
path=MOBILEREAD+file, app=__appname__,
|
||||
note=Markup(\
|
||||
'''
|
||||
u'''
|
||||
<ol>
|
||||
<li>Before trying to use the command line tools, you must run the app at least once. This will ask you for you password and then setup the symbolic links for the command line tools.</li>
|
||||
<li>The app cannot be run from within the dmg. You must drag it to a folder on your filesystem (The Desktop, Applications, wherever).</li>
|
||||
<li>In order for localization of the user interface in your language, select your language in the configuration dialog (by clicking the hammer icon next to the search bar) and select your language.</li>
|
||||
<li>In order for localization of the user interface in your language, select your language in the preferences (by pressing u\2318+P) and select your language.</li>
|
||||
</ol>
|
||||
'''))
|
||||
return 'binary.html', data, None
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
1578
src/calibre/utils/Zeroconf.py
Executable file
1578
src/calibre/utils/Zeroconf.py
Executable file
File diff suppressed because it is too large
Load Diff
60
src/calibre/utils/mdns.py
Normal file
60
src/calibre/utils/mdns.py
Normal file
@ -0,0 +1,60 @@
|
||||
from __future__ import with_statement
|
||||
__license__ = 'GPL 3'
|
||||
__copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
import socket
|
||||
|
||||
_server = None
|
||||
|
||||
def get_external_ip():
|
||||
'Get IP address of interface used to connect to the outside world'
|
||||
try:
|
||||
ipaddr = socket.gethostbyname(socket.gethostname())
|
||||
except:
|
||||
ipaddr = '127.0.0.1'
|
||||
if ipaddr == '127.0.0.1':
|
||||
try:
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
s.connect(('google.com', 0))
|
||||
ipaddr = s.getsockname()[0]
|
||||
except:
|
||||
pass
|
||||
return ipaddr
|
||||
|
||||
def start_server():
|
||||
global _server
|
||||
if _server is None:
|
||||
from calibre.utils.Zeroconf import Zeroconf
|
||||
_server = Zeroconf()
|
||||
return _server
|
||||
|
||||
def publish(desc, type, port, properties=None, add_hostname=True):
|
||||
'''
|
||||
Publish a service.
|
||||
|
||||
:param desc: Description of service
|
||||
:param type: Name and type of service. For example _stanza._tcp
|
||||
:param port: Port the service listens on
|
||||
:param properties: An optional dictionary whose keys and values will be put
|
||||
into the TXT record.
|
||||
'''
|
||||
port = int(port)
|
||||
server = start_server()
|
||||
hostname = socket.gethostname().partition('.')[0]
|
||||
if add_hostname:
|
||||
desc += ' (on %s)'%hostname
|
||||
local_ip = get_external_ip()
|
||||
type = type+'.local.'
|
||||
from calibre.utils.Zeroconf import ServiceInfo
|
||||
service = ServiceInfo(type, desc+'.'+type,
|
||||
address=socket.inet_aton(local_ip),
|
||||
port=port,
|
||||
properties=properties,
|
||||
server=hostname+'.local.')
|
||||
server.registerService(service)
|
||||
|
||||
def stop_server():
|
||||
global _server
|
||||
if _server is not None:
|
||||
_server.close()
|
@ -34,6 +34,7 @@ recipe_modules = ['recipe_' + r for r in (
|
||||
'al_jazeera', 'winsupersite', 'borba', 'courrierinternational',
|
||||
'lamujerdemivida', 'soldiers', 'theonion', 'news_times',
|
||||
'el_universal', 'mediapart', 'wikinews_en', 'ecogeek', 'daily_mail',
|
||||
'new_york_review_of_books_no_sub', 'politico',
|
||||
)]
|
||||
|
||||
import re, imp, inspect, time, os
|
||||
|
@ -1,14 +1,7 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
__license__ = 'GPL v3'
|
||||
__copyright__ = '2008, Darko Miletic <darko.miletic at gmail.com>'
|
||||
'''
|
||||
newscientist.com
|
||||
'''
|
||||
#!/usr/bin/env python
|
||||
|
||||
__license__ = 'GPL v3'
|
||||
__copyright__ = '2008, Darko Miletic <darko.miletic at gmail.com>, AprilHare'
|
||||
__copyright__ = '2008-2009, AprilHare, Darko Miletic <darko.miletic at gmail.com>'
|
||||
'''
|
||||
newscientist.com
|
||||
'''
|
||||
@ -16,23 +9,34 @@ newscientist.com
|
||||
from calibre.web.feeds.news import BasicNewsRecipe
|
||||
|
||||
class NewScientist(BasicNewsRecipe):
|
||||
title = u'New Scientist - Online News'
|
||||
title = 'New Scientist - Online News'
|
||||
__author__ = 'Darko Miletic'
|
||||
description = 'News from Science'
|
||||
description = 'Science news and science articles from New Scientist.'
|
||||
language = _('English')
|
||||
publisher = 'New Scientist'
|
||||
category = 'science news, science articles, science jobs, drugs, cancer, depression, computer software, sex'
|
||||
delay = 3
|
||||
oldest_article = 7
|
||||
max_articles_per_feed = 100
|
||||
no_stylesheets = True
|
||||
use_embedded_content = False
|
||||
remove_javascript = True
|
||||
encoding = 'utf-8'
|
||||
|
||||
keep_only_tags = [
|
||||
dict(name='div' , attrs={'id':'pgtop' })
|
||||
,dict(name='div' , attrs={'id':'maincol' })
|
||||
html2lrf_options = [
|
||||
'--comment', description
|
||||
, '--category', category
|
||||
, '--publisher', publisher
|
||||
]
|
||||
|
||||
html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"'
|
||||
|
||||
keep_only_tags = [dict(name='div', attrs={'id':['pgtop','maincol']})]
|
||||
|
||||
remove_tags = [
|
||||
dict(name='div' , attrs={'class':'hldBd' })
|
||||
,dict(name='div' , attrs={'id':'compnl' })
|
||||
,dict(name='div' , attrs={'id':'artIssueInfo' })
|
||||
dict(name='div', attrs={'class':['hldBd','adline','pnl','infotext' ]})
|
||||
,dict(name='div', attrs={'id' :['compnl','artIssueInfo','artTools']})
|
||||
,dict(name='p' , attrs={'class':['marker','infotext' ]})
|
||||
]
|
||||
|
||||
feeds = [
|
||||
@ -46,3 +50,20 @@ class NewScientist(BasicNewsRecipe):
|
||||
,(u'Science in Society' , u'http://www.newscientist.com/feed/view?id=5&type=channel' )
|
||||
,(u'Tech' , u'http://www.newscientist.com/feed/view?id=7&type=channel' )
|
||||
]
|
||||
|
||||
def get_article_url(self, article):
|
||||
url = article.get('link', None)
|
||||
raw = article.get('description', None)
|
||||
rsoup = self.index_to_soup(raw)
|
||||
atags = rsoup.findAll('a',href=True)
|
||||
for atag in atags:
|
||||
if atag['href'].startswith('http://res.feedsportal.com/viral/sendemail2.html?'):
|
||||
st, sep, rest = atag['href'].partition('&link=')
|
||||
real_url, sep2, drest = rest.partition('" target=')
|
||||
return real_url
|
||||
return url
|
||||
|
||||
def print_version(self, url):
|
||||
rawurl, sep, params = url.partition('?')
|
||||
return rawurl + '?full=true&print=true'
|
||||
|
@ -0,0 +1,44 @@
|
||||
#!/usr/bin/env python
|
||||
__license__ = 'GPL v3'
|
||||
__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
'''
|
||||
nybooks.com
|
||||
'''
|
||||
|
||||
from calibre.web.feeds.news import BasicNewsRecipe
|
||||
from lxml import html
|
||||
from calibre.constants import preferred_encoding
|
||||
|
||||
class NewYorkReviewOfBooks(BasicNewsRecipe):
|
||||
|
||||
title = u'New York Review of Books (no subscription)'
|
||||
description = u'Book reviews'
|
||||
language = _('English')
|
||||
__author__ = 'Kovid Goyal'
|
||||
remove_tags_before = {'id':'container'}
|
||||
remove_tags = [{'class':['noprint', 'ad', 'footer']}, {'id':'right-content'}]
|
||||
|
||||
def parse_index(self):
|
||||
root = html.fromstring(self.browser.open('http://www.nybooks.com/current-issue').read())
|
||||
date = root.xpath('//h4[@class = "date"]')[0]
|
||||
self.timefmt = ' ['+date.text.encode(preferred_encoding)+']'
|
||||
articles = []
|
||||
for tag in date.itersiblings():
|
||||
if tag.tag == 'h4': break
|
||||
if tag.tag == 'p':
|
||||
if tag.get('class') == 'indented':
|
||||
articles[-1]['description'] += html.tostring(tag)
|
||||
else:
|
||||
href = tag.xpath('descendant::a[@href]')[0].get('href')
|
||||
article = {
|
||||
'title': u''.join(tag.xpath('descendant::text()')),
|
||||
'date' : '',
|
||||
'url' : 'http://www.nybooks.com'+href,
|
||||
'description': '',
|
||||
}
|
||||
articles.append(article)
|
||||
|
||||
return [('Current Issue', articles)]
|
||||
|
66
src/calibre/web/feeds/recipes/recipe_politico.py
Normal file
66
src/calibre/web/feeds/recipes/recipe_politico.py
Normal file
@ -0,0 +1,66 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
__license__ = 'GPL v3'
|
||||
__copyright__ = '2009, Darko Miletic <darko.miletic at gmail.com>'
|
||||
'''
|
||||
politico.com
|
||||
'''
|
||||
|
||||
from calibre.web.feeds.news import BasicNewsRecipe
|
||||
|
||||
class Politico(BasicNewsRecipe):
|
||||
title = 'Politico'
|
||||
__author__ = 'Darko Miletic'
|
||||
description = 'Political news from USA'
|
||||
publisher = 'Capitol News Company, LLC'
|
||||
category = 'news, politics, USA'
|
||||
oldest_article = 7
|
||||
max_articles_per_feed = 100
|
||||
use_embedded_content = False
|
||||
no_stylesheets = True
|
||||
remove_javascript = True
|
||||
encoding = 'cp1252'
|
||||
language = _('English')
|
||||
|
||||
html2lrf_options = [
|
||||
'--comment', description
|
||||
, '--category', category
|
||||
, '--publisher', publisher
|
||||
, '--ignore-tables'
|
||||
]
|
||||
|
||||
html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"\nlinearize_tables=True'
|
||||
|
||||
remove_tags = [dict(name=['notags','embed','object','link','img'])]
|
||||
|
||||
feeds = [
|
||||
(u'Top Stories' , u'http://www.politico.com/rss/politicopicks.xml' )
|
||||
,(u'Congress' , u'http://www.politico.com/rss/congress.xml' )
|
||||
,(u'Ideas' , u'http://www.politico.com/rss/ideas.xml' )
|
||||
,(u'Life' , u'http://www.politico.com/rss/life.xml' )
|
||||
,(u'Lobbyists' , u'http://www.politico.com/rss/lobbyists.xml' )
|
||||
,(u'Pitboss' , u'http://www.politico.com/rss/pitboss.xml' )
|
||||
,(u'Politics' , u'http://www.politico.com/rss/politics.xml' )
|
||||
,(u'Roger Simon' , u'http://www.politico.com/rss/rogersimon.xml' )
|
||||
,(u'Suite Talk' , u'http://www.politico.com/rss/suitetalk.xml' )
|
||||
,(u'Playbook' , u'http://www.politico.com/rss/playbook.xml' )
|
||||
,(u'The Huddle' , u'http://www.politico.com/rss/huddle.xml' )
|
||||
]
|
||||
|
||||
def preprocess_html(self, soup):
|
||||
mtag = '<meta http-equiv="Content-Language" content="en-US"/>'
|
||||
soup.head.insert(0,mtag)
|
||||
for item in soup.findAll(style=True):
|
||||
del item['style']
|
||||
return soup
|
||||
|
||||
def print_url(self, soup, default):
|
||||
printtags = soup.findAll('a',href=True)
|
||||
for printtag in printtags:
|
||||
if printtag.string == "Print":
|
||||
return printtag['href']
|
||||
return default
|
||||
|
||||
def print_version(self, url):
|
||||
soup = self.index_to_soup(url)
|
||||
return self.print_url(soup, None)
|
@ -14,6 +14,7 @@ class Time(BasicNewsRecipe):
|
||||
description = 'Weekly magazine'
|
||||
oldest_article = 7
|
||||
max_articles_per_feed = 100
|
||||
encoding = 'utf-8'
|
||||
no_stylesheets = True
|
||||
language = _('English')
|
||||
use_embedded_content = False
|
||||
|
@ -5,3 +5,4 @@
|
||||
|
||||
* Use multiprocessing for cpu_count instead of QThread
|
||||
|
||||
* Rationalize books table. Add a pubdate column, remove the uri column (and associated support in add_books) and convert series_index to a float.
|
@ -709,7 +709,8 @@ class upload(OptionlessCommand):
|
||||
('stage3', None)
|
||||
]
|
||||
|
||||
class upload_rss(OptionlessCommand):
|
||||
try:
|
||||
class upload_rss(OptionlessCommand):
|
||||
|
||||
from bzrlib import log as blog
|
||||
|
||||
@ -769,5 +770,6 @@ class upload_rss(OptionlessCommand):
|
||||
log.show_log(b, lf)
|
||||
lf.rss.write_xml(open('/tmp/releases.xml', 'wb'))
|
||||
subprocess.check_call('scp /tmp/releases.xml divok:/var/www/calibre.kovidgoyal.net/htdocs/downloads'.split())
|
||||
|
||||
except ImportError:
|
||||
upload_rss = None
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user