mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Pull from trunk
This commit is contained in:
commit
c29cff431a
@ -26,12 +26,16 @@ mimetypes.add_type('text/x-sony-bbeb+xml', '.lrs')
|
|||||||
mimetypes.add_type('application/xhtml+xml', '.xhtml')
|
mimetypes.add_type('application/xhtml+xml', '.xhtml')
|
||||||
mimetypes.add_type('image/svg+xml', '.svg')
|
mimetypes.add_type('image/svg+xml', '.svg')
|
||||||
mimetypes.add_type('application/x-sony-bbeb', '.lrf')
|
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/x-dtbncx+xml', '.ncx')
|
||||||
mimetypes.add_type('application/adobe-page-template+xml', '.xpgt')
|
mimetypes.add_type('application/adobe-page-template+xml', '.xpgt')
|
||||||
mimetypes.add_type('application/x-font-opentype', '.otf')
|
mimetypes.add_type('application/x-font-opentype', '.otf')
|
||||||
mimetypes.add_type('application/x-font-truetype', '.ttf')
|
mimetypes.add_type('application/x-font-truetype', '.ttf')
|
||||||
mimetypes.add_type('application/oebps-package+xml', '.opf')
|
mimetypes.add_type('application/oebps-package+xml', '.opf')
|
||||||
mimetypes.add_type('application/ereader', '.pdb')
|
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
|
guess_type = mimetypes.guess_type
|
||||||
import cssutils
|
import cssutils
|
||||||
cssutils.log.setLevel(logging.WARN)
|
cssutils.log.setLevel(logging.WARN)
|
||||||
|
@ -132,13 +132,24 @@ class HTMLMetadataReader(MetadataReaderPlugin):
|
|||||||
class MOBIMetadataReader(MetadataReaderPlugin):
|
class MOBIMetadataReader(MetadataReaderPlugin):
|
||||||
|
|
||||||
name = 'Read MOBI metadata'
|
name = 'Read MOBI metadata'
|
||||||
file_types = set(['mobi', 'prc', '.azw'])
|
file_types = set(['mobi', 'prc', 'azw'])
|
||||||
description = _('Read metadata from %s files')%'MOBI'
|
description = _('Read metadata from %s files')%'MOBI'
|
||||||
|
|
||||||
def get_metadata(self, stream, ftype):
|
def get_metadata(self, stream, ftype):
|
||||||
from calibre.ebooks.mobi.reader import get_metadata
|
from calibre.ebooks.mobi.reader import get_metadata
|
||||||
return get_metadata(stream)
|
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):
|
class ODTMetadataReader(MetadataReaderPlugin):
|
||||||
|
|
||||||
name = 'Read ODT metadata'
|
name = 'Read ODT metadata'
|
||||||
|
@ -4,9 +4,9 @@ __copyright__ = '2009, John Schember <john at nachtimwald.com>'
|
|||||||
Device driver for Amazon's Kindle
|
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):
|
class KINDLE(USBMS):
|
||||||
# Ordered list of supported formats
|
# Ordered list of supported formats
|
||||||
@ -30,6 +30,9 @@ class KINDLE(USBMS):
|
|||||||
EBOOK_DIR_CARD = "documents"
|
EBOOK_DIR_CARD = "documents"
|
||||||
SUPPORTS_SUB_DIRS = True
|
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):
|
def delete_books(self, paths, end_session=True):
|
||||||
for path in paths:
|
for path in paths:
|
||||||
if os.path.exists(path):
|
if os.path.exists(path):
|
||||||
@ -41,6 +44,16 @@ class KINDLE(USBMS):
|
|||||||
if os.path.exists(filepath + '.mbp'):
|
if os.path.exists(filepath + '.mbp'):
|
||||||
os.unlink(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):
|
class KINDLE2(KINDLE):
|
||||||
|
|
||||||
PRODUCT_ID = [0x0002]
|
PRODUCT_ID = [0x0002]
|
||||||
|
@ -1,19 +1,20 @@
|
|||||||
__license__ = 'GPL v3'
|
from __future__ import with_statement
|
||||||
__copyright__ = '2009, John Schember <john at nachtimwald.com>'
|
__license__ = 'GPL 3'
|
||||||
'''
|
__copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||||
Global Mime mapping of ebook types.
|
__docformat__ = 'restructuredtext en'
|
||||||
'''
|
|
||||||
|
|
||||||
MIME_MAP = {
|
from calibre import guess_type
|
||||||
'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',
|
|
||||||
}
|
|
||||||
|
|
||||||
|
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.device import Device
|
||||||
from calibre.devices.usbms.books import BookList, Book
|
from calibre.devices.usbms.books import BookList, Book
|
||||||
from calibre.devices.errors import FreeSpaceError, PathError
|
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):
|
class File(object):
|
||||||
def __init__(self, path):
|
def __init__(self, path):
|
||||||
@ -226,14 +226,17 @@ class USBMS(Device):
|
|||||||
if not os.path.isdir(path):
|
if not os.path.isdir(path):
|
||||||
os.utime(path, None)
|
os.utime(path, None)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def metadata_from_path(cls, path):
|
||||||
|
return metadata_from_formats([path])
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def book_from_path(cls, path):
|
def book_from_path(cls, path):
|
||||||
fileext = path_to_ext(path)
|
fileext = path_to_ext(path)
|
||||||
|
mi = cls.metadata_from_path(path)
|
||||||
mi = metadata_from_formats([path])
|
mime = mime_type_ext(fileext)
|
||||||
mime = MIME_MAP[fileext] if fileext in MIME_MAP.keys() else 'Unknown'
|
|
||||||
|
|
||||||
authors = authors_to_string(mi.authors)
|
authors = authors_to_string(mi.authors)
|
||||||
|
|
||||||
return Book(path, mi.title, authors, mime)
|
book = Book(path, mi.title, authors, mime)
|
||||||
|
return book
|
||||||
|
|
||||||
|
@ -118,11 +118,17 @@ class EbookIterator(object):
|
|||||||
self.spine = [SpineItem(i.path) for i in self.opf.spine]
|
self.spine = [SpineItem(i.path) for i in self.opf.spine]
|
||||||
|
|
||||||
cover = self.opf.cover
|
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')
|
cfile = os.path.join(os.path.dirname(self.spine[0]), 'calibre_ei_cover.html')
|
||||||
open(cfile, 'wb').write(TITLEPAGE%cover)
|
open(cfile, 'wb').write(TITLEPAGE%cover)
|
||||||
self.spine[0:0] = [SpineItem(cfile)]
|
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]
|
sizes = [i.character_count for i in self.spine]
|
||||||
self.pages = [math.ceil(i/float(self.CHARACTERS_PER_PAGE)) for i in sizes]
|
self.pages = [math.ceil(i/float(self.CHARACTERS_PER_PAGE)) for i in sizes]
|
||||||
for p, s in zip(self.pages, self.spine):
|
for p, s in zip(self.pages, self.spine):
|
||||||
|
@ -15,7 +15,7 @@ _METADATA_PRIORITIES = [
|
|||||||
'html', 'htm', 'xhtml', 'xhtm',
|
'html', 'htm', 'xhtml', 'xhtm',
|
||||||
'rtf', 'fb2', 'pdf', 'prc', 'odt',
|
'rtf', 'fb2', 'pdf', 'prc', 'odt',
|
||||||
'epub', 'lit', 'lrx', 'lrf', 'mobi',
|
'epub', 'lit', 'lrx', 'lrf', 'mobi',
|
||||||
'rb', 'imp'
|
'rb', 'imp', 'azw'
|
||||||
]
|
]
|
||||||
|
|
||||||
# The priorities for loading metadata from different file types
|
# 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):
|
for path, ext in zip(formats, extensions):
|
||||||
with open(path, 'rb') as stream:
|
with open(path, 'rb') as stream:
|
||||||
try:
|
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:
|
except:
|
||||||
continue
|
continue
|
||||||
if getattr(mi, 'application_id', None) is not None:
|
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: stream_type = stream_type.lower()
|
||||||
if stream_type in ('html', 'html', 'xhtml', 'xhtm', 'xml'):
|
if stream_type in ('html', 'html', 'xhtml', 'xhtm', 'xml'):
|
||||||
stream_type = 'html'
|
stream_type = 'html'
|
||||||
if stream_type in ('mobi', 'prc'):
|
if stream_type in ('mobi', 'prc', 'azw'):
|
||||||
stream_type = 'mobi'
|
stream_type = 'mobi'
|
||||||
if stream_type in ('odt', 'ods', 'odp', 'odg', 'odf'):
|
if stream_type in ('odt', 'ods', 'odp', 'odg', 'odf'):
|
||||||
stream_type = 'odt'
|
stream_type = 'odt'
|
||||||
|
@ -444,6 +444,7 @@ class OPF(object):
|
|||||||
if not hasattr(stream, 'read'):
|
if not hasattr(stream, 'read'):
|
||||||
stream = open(stream, 'rb')
|
stream = open(stream, 'rb')
|
||||||
self.basedir = self.base_dir = basedir
|
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, self.encoding = xml_to_unicode(stream.read(), strip_encoding_pats=True, resolve_entities=True)
|
||||||
raw = raw[raw.find('<'):]
|
raw = raw[raw.find('<'):]
|
||||||
self.root = etree.fromstring(raw, self.PARSER)
|
self.root = etree.fromstring(raw, self.PARSER)
|
||||||
@ -495,6 +496,7 @@ class OPF(object):
|
|||||||
if f:
|
if f:
|
||||||
self.toc.read_ncx_toc(f[0])
|
self.toc.read_ncx_toc(f[0])
|
||||||
else:
|
else:
|
||||||
|
self.path_to_html_toc = toc
|
||||||
self.toc.read_html_toc(toc)
|
self.toc.read_html_toc(toc)
|
||||||
except:
|
except:
|
||||||
pass
|
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.sublanguage = 'NEUTRAL'
|
||||||
self.exth_flag, self.exth = 0, None
|
self.exth_flag, self.exth = 0, None
|
||||||
self.ancient = True
|
self.ancient = True
|
||||||
|
self.first_image_index = -1
|
||||||
|
self.mobi_version = 1
|
||||||
else:
|
else:
|
||||||
self.ancient = False
|
self.ancient = False
|
||||||
self.doctype = raw[16:20]
|
self.doctype = raw[16:20]
|
||||||
@ -537,7 +539,7 @@ class MobiReader(object):
|
|||||||
os.makedirs(output_dir)
|
os.makedirs(output_dir)
|
||||||
image_index = 0
|
image_index = 0
|
||||||
self.image_names = []
|
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:
|
if start > self.num_sections or start < 0:
|
||||||
# BAEN PRC files have bad headers
|
# BAEN PRC files have bad headers
|
||||||
start=0
|
start=0
|
||||||
|
@ -224,7 +224,10 @@ class AddRecursive(Add):
|
|||||||
files = _('<p>Books with the same title as the following already '
|
files = _('<p>Books with the same title as the following already '
|
||||||
'exist in the database. Add them anyway?<ul>')
|
'exist in the database. Add them anyway?<ul>')
|
||||||
for mi in self.duplicates:
|
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!'),
|
d = WarningDialog (_('Duplicates found!'),
|
||||||
_('Duplicates found!'),
|
_('Duplicates found!'),
|
||||||
files+'</ul></p>', parent=self._parent)
|
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>
|
<class>MetadataSingleDialog</class>
|
||||||
<widget class="QDialog" name="MetadataSingleDialog" >
|
<widget class="QDialog" name="MetadataSingleDialog">
|
||||||
<property name="geometry" >
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
@ -9,36 +10,36 @@
|
|||||||
<height>750</height>
|
<height>750</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizePolicy" >
|
<property name="sizePolicy">
|
||||||
<sizepolicy vsizetype="MinimumExpanding" hsizetype="MinimumExpanding" >
|
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||||
<horstretch>0</horstretch>
|
<horstretch>0</horstretch>
|
||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle" >
|
<property name="windowTitle">
|
||||||
<string>Edit Meta Information</string>
|
<string>Edit Meta Information</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowIcon" >
|
<property name="windowIcon">
|
||||||
<iconset resource="../images.qrc" >
|
<iconset resource="../images.qrc">
|
||||||
<normaloff>:/images/edit_input.svg</normaloff>:/images/edit_input.svg</iconset>
|
<normaloff>:/images/edit_input.svg</normaloff>:/images/edit_input.svg</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizeGripEnabled" >
|
<property name="sizeGripEnabled">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
<property name="modal" >
|
<property name="modal">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_6" >
|
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QScrollArea" name="scrollArea" >
|
<widget class="QScrollArea" name="scrollArea">
|
||||||
<property name="frameShape" >
|
<property name="frameShape">
|
||||||
<enum>QFrame::NoFrame</enum>
|
<enum>QFrame::NoFrame</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="widgetResizable" >
|
<property name="widgetResizable">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="scrollAreaWidgetContents" >
|
<widget class="QWidget" name="scrollAreaWidgetContents">
|
||||||
<property name="geometry" >
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
@ -46,65 +47,65 @@
|
|||||||
<height>710</height>
|
<height>710</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_5" >
|
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||||
<property name="margin" >
|
<property name="margin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QWidget" native="1" name="central_widget" >
|
<widget class="QWidget" name="central_widget" native="true">
|
||||||
<property name="minimumSize" >
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>800</width>
|
<width>800</width>
|
||||||
<height>665</height>
|
<height>665</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_3" >
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QSplitter" name="splitter" >
|
<widget class="QSplitter" name="splitter">
|
||||||
<property name="orientation" >
|
<property name="orientation">
|
||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="layoutWidget" >
|
<widget class="QWidget" name="layoutWidget">
|
||||||
<layout class="QVBoxLayout" >
|
<layout class="QVBoxLayout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="meta_box" >
|
<widget class="QGroupBox" name="meta_box">
|
||||||
<property name="title" >
|
<property name="title">
|
||||||
<string>Meta information</string>
|
<string>Meta information</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout_3" >
|
<layout class="QGridLayout" name="gridLayout_3">
|
||||||
<item row="0" column="0" >
|
<item row="0" column="0">
|
||||||
<widget class="QLabel" name="label" >
|
<widget class="QLabel" name="label">
|
||||||
<property name="text" >
|
<property name="text">
|
||||||
<string>&Title: </string>
|
<string>&Title: </string>
|
||||||
</property>
|
</property>
|
||||||
<property name="alignment" >
|
<property name="alignment">
|
||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
</property>
|
</property>
|
||||||
<property name="buddy" >
|
<property name="buddy">
|
||||||
<cstring>title</cstring>
|
<cstring>title</cstring>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="1" >
|
<item row="0" column="1">
|
||||||
<widget class="QLineEdit" name="title" >
|
<widget class="QLineEdit" name="title">
|
||||||
<property name="toolTip" >
|
<property name="toolTip">
|
||||||
<string>Change the title of this book</string>
|
<string>Change the title of this book</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item rowspan="2" row="0" column="2" >
|
<item row="0" column="2" rowspan="2">
|
||||||
<widget class="QToolButton" name="swap_button" >
|
<widget class="QToolButton" name="swap_button">
|
||||||
<property name="toolTip" >
|
<property name="toolTip">
|
||||||
<string>Swap the author and title</string>
|
<string>Swap the author and title</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="text" >
|
<property name="text">
|
||||||
<string>...</string>
|
<string>...</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon" >
|
<property name="icon">
|
||||||
<iconset resource="../images.qrc" >
|
<iconset resource="../images.qrc">
|
||||||
<normaloff>:/images/swap.svg</normaloff>:/images/swap.svg</iconset>
|
<normaloff>:/images/swap.svg</normaloff>:/images/swap.svg</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="iconSize" >
|
<property name="iconSize">
|
||||||
<size>
|
<size>
|
||||||
<width>16</width>
|
<width>16</width>
|
||||||
<height>16</height>
|
<height>16</height>
|
||||||
@ -112,305 +113,305 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="0" >
|
<item row="1" column="0">
|
||||||
<widget class="QLabel" name="label_2" >
|
<widget class="QLabel" name="label_2">
|
||||||
<property name="text" >
|
<property name="text">
|
||||||
<string>&Author(s): </string>
|
<string>&Author(s): </string>
|
||||||
</property>
|
</property>
|
||||||
<property name="alignment" >
|
<property name="alignment">
|
||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
</property>
|
</property>
|
||||||
<property name="buddy" >
|
<property name="buddy">
|
||||||
<cstring>authors</cstring>
|
<cstring>authors</cstring>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0" >
|
<item row="2" column="0">
|
||||||
<widget class="QLabel" name="label_8" >
|
<widget class="QLabel" name="label_8">
|
||||||
<property name="text" >
|
<property name="text">
|
||||||
<string>Author S&ort: </string>
|
<string>Author S&ort: </string>
|
||||||
</property>
|
</property>
|
||||||
<property name="alignment" >
|
<property name="alignment">
|
||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
</property>
|
</property>
|
||||||
<property name="buddy" >
|
<property name="buddy">
|
||||||
<cstring>author_sort</cstring>
|
<cstring>author_sort</cstring>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="1" colspan="2" >
|
<item row="2" column="1" colspan="2">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout" >
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLineEdit" name="author_sort" >
|
<widget class="QLineEdit" name="author_sort">
|
||||||
<property name="toolTip" >
|
<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>
|
<string>Specify how the author(s) of this book should be sorted. For example Charles Dickens should be sorted as Dickens, Charles.</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QToolButton" name="auto_author_sort" >
|
<widget class="QToolButton" name="auto_author_sort">
|
||||||
<property name="toolTip" >
|
<property name="toolTip">
|
||||||
<string>Automatically create the author sort entry based on the current author entry</string>
|
<string>Automatically create the author sort entry based on the current author entry</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="text" >
|
<property name="text">
|
||||||
<string>...</string>
|
<string>...</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon" >
|
<property name="icon">
|
||||||
<iconset resource="../images.qrc" >
|
<iconset resource="../images.qrc">
|
||||||
<normaloff>:/images/auto_author_sort.svg</normaloff>:/images/auto_author_sort.svg</iconset>
|
<normaloff>:/images/auto_author_sort.svg</normaloff>:/images/auto_author_sort.svg</iconset>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="0" >
|
<item row="3" column="0">
|
||||||
<widget class="QLabel" name="label_6" >
|
<widget class="QLabel" name="label_6">
|
||||||
<property name="text" >
|
<property name="text">
|
||||||
<string>&Rating:</string>
|
<string>&Rating:</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="alignment" >
|
<property name="alignment">
|
||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
</property>
|
</property>
|
||||||
<property name="buddy" >
|
<property name="buddy">
|
||||||
<cstring>rating</cstring>
|
<cstring>rating</cstring>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="1" colspan="2" >
|
<item row="3" column="1" colspan="2">
|
||||||
<widget class="QSpinBox" name="rating" >
|
<widget class="QSpinBox" name="rating">
|
||||||
<property name="toolTip" >
|
<property name="toolTip">
|
||||||
<string>Rating of this book. 0-5 stars</string>
|
<string>Rating of this book. 0-5 stars</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="whatsThis" >
|
<property name="whatsThis">
|
||||||
<string>Rating of this book. 0-5 stars</string>
|
<string>Rating of this book. 0-5 stars</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="buttonSymbols" >
|
<property name="buttonSymbols">
|
||||||
<enum>QAbstractSpinBox::PlusMinus</enum>
|
<enum>QAbstractSpinBox::PlusMinus</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="suffix" >
|
<property name="suffix">
|
||||||
<string> stars</string>
|
<string> stars</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="maximum" >
|
<property name="maximum">
|
||||||
<number>5</number>
|
<number>5</number>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="4" column="0" >
|
<item row="4" column="0">
|
||||||
<widget class="QLabel" name="label_3" >
|
<widget class="QLabel" name="label_3">
|
||||||
<property name="text" >
|
<property name="text">
|
||||||
<string>&Publisher: </string>
|
<string>&Publisher: </string>
|
||||||
</property>
|
</property>
|
||||||
<property name="alignment" >
|
<property name="alignment">
|
||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
</property>
|
</property>
|
||||||
<property name="buddy" >
|
<property name="buddy">
|
||||||
<cstring>publisher</cstring>
|
<cstring>publisher</cstring>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="5" column="0" >
|
<item row="5" column="0">
|
||||||
<widget class="QLabel" name="label_4" >
|
<widget class="QLabel" name="label_4">
|
||||||
<property name="text" >
|
<property name="text">
|
||||||
<string>Ta&gs: </string>
|
<string>Ta&gs: </string>
|
||||||
</property>
|
</property>
|
||||||
<property name="alignment" >
|
<property name="alignment">
|
||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
</property>
|
</property>
|
||||||
<property name="buddy" >
|
<property name="buddy">
|
||||||
<cstring>tags</cstring>
|
<cstring>tags</cstring>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="5" column="1" colspan="2" >
|
<item row="5" column="1" colspan="2">
|
||||||
<layout class="QHBoxLayout" name="_2" >
|
<layout class="QHBoxLayout" name="_2">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLineEdit" name="tags" >
|
<widget class="QLineEdit" name="tags">
|
||||||
<property name="toolTip" >
|
<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>
|
<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>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QToolButton" name="tag_editor_button" >
|
<widget class="QToolButton" name="tag_editor_button">
|
||||||
<property name="toolTip" >
|
<property name="toolTip">
|
||||||
<string>Open Tag Editor</string>
|
<string>Open Tag Editor</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="text" >
|
<property name="text">
|
||||||
<string>Open Tag Editor</string>
|
<string>Open Tag Editor</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon" >
|
<property name="icon">
|
||||||
<iconset resource="../images.qrc" >
|
<iconset resource="../images.qrc">
|
||||||
<normaloff>:/images/chapters.svg</normaloff>:/images/chapters.svg</iconset>
|
<normaloff>:/images/chapters.svg</normaloff>:/images/chapters.svg</iconset>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="6" column="0" >
|
<item row="6" column="0">
|
||||||
<widget class="QLabel" name="label_7" >
|
<widget class="QLabel" name="label_7">
|
||||||
<property name="text" >
|
<property name="text">
|
||||||
<string>&Series:</string>
|
<string>&Series:</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="textFormat" >
|
<property name="textFormat">
|
||||||
<enum>Qt::PlainText</enum>
|
<enum>Qt::PlainText</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="alignment" >
|
<property name="alignment">
|
||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
</property>
|
</property>
|
||||||
<property name="buddy" >
|
<property name="buddy">
|
||||||
<cstring>series</cstring>
|
<cstring>series</cstring>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="6" column="1" colspan="2" >
|
<item row="6" column="1" colspan="2">
|
||||||
<layout class="QHBoxLayout" name="_3" >
|
<layout class="QHBoxLayout" name="_3">
|
||||||
<property name="spacing" >
|
<property name="spacing">
|
||||||
<number>5</number>
|
<number>5</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QComboBox" name="series" >
|
<widget class="QComboBox" name="series">
|
||||||
<property name="sizePolicy" >
|
<property name="sizePolicy">
|
||||||
<sizepolicy vsizetype="Fixed" hsizetype="MinimumExpanding" >
|
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||||
<horstretch>0</horstretch>
|
<horstretch>0</horstretch>
|
||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="toolTip" >
|
<property name="toolTip">
|
||||||
<string>List of known series. You can add new series.</string>
|
<string>List of known series. You can add new series.</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="whatsThis" >
|
<property name="whatsThis">
|
||||||
<string>List of known series. You can add new series.</string>
|
<string>List of known series. You can add new series.</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="editable" >
|
<property name="editable">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
<property name="insertPolicy" >
|
<property name="insertPolicy">
|
||||||
<enum>QComboBox::InsertAlphabetically</enum>
|
<enum>QComboBox::InsertAlphabetically</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizeAdjustPolicy" >
|
<property name="sizeAdjustPolicy">
|
||||||
<enum>QComboBox::AdjustToContents</enum>
|
<enum>QComboBox::AdjustToContents</enum>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QToolButton" name="remove_series_button" >
|
<widget class="QToolButton" name="remove_series_button">
|
||||||
<property name="toolTip" >
|
<property name="toolTip">
|
||||||
<string>Remove unused series (Series that have no books)</string>
|
<string>Remove unused series (Series that have no books)</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="text" >
|
<property name="text">
|
||||||
<string>...</string>
|
<string>...</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon" >
|
<property name="icon">
|
||||||
<iconset resource="../images.qrc" >
|
<iconset resource="../images.qrc">
|
||||||
<normaloff>:/images/trash.svg</normaloff>:/images/trash.svg</iconset>
|
<normaloff>:/images/trash.svg</normaloff>:/images/trash.svg</iconset>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="7" column="1" colspan="2" >
|
<item row="7" column="1" colspan="2">
|
||||||
<widget class="QSpinBox" name="series_index" >
|
<widget class="QSpinBox" name="series_index">
|
||||||
<property name="enabled" >
|
<property name="enabled">
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</property>
|
</property>
|
||||||
<property name="toolTip" >
|
<property name="toolTip">
|
||||||
<string>Series index.</string>
|
<string>Series index.</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="whatsThis" >
|
<property name="whatsThis">
|
||||||
<string>Series index.</string>
|
<string>Series index.</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="prefix" >
|
<property name="prefix">
|
||||||
<string>Book </string>
|
<string>Book </string>
|
||||||
</property>
|
</property>
|
||||||
<property name="minimum" >
|
<property name="minimum">
|
||||||
<number>1</number>
|
<number>1</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="maximum" >
|
<property name="maximum">
|
||||||
<number>10000</number>
|
<number>10000</number>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="8" column="0" >
|
<item row="8" column="0">
|
||||||
<widget class="QLabel" name="label_9" >
|
<widget class="QLabel" name="label_9">
|
||||||
<property name="text" >
|
<property name="text">
|
||||||
<string>IS&BN:</string>
|
<string>IS&BN:</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="alignment" >
|
<property name="alignment">
|
||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
</property>
|
</property>
|
||||||
<property name="buddy" >
|
<property name="buddy">
|
||||||
<cstring>isbn</cstring>
|
<cstring>isbn</cstring>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="8" column="1" colspan="2" >
|
<item row="8" column="1" colspan="2">
|
||||||
<widget class="QLineEdit" name="isbn" />
|
<widget class="QLineEdit" name="isbn"/>
|
||||||
</item>
|
</item>
|
||||||
<item row="4" column="1" >
|
<item row="4" column="1">
|
||||||
<widget class="QComboBox" name="publisher" >
|
<widget class="QComboBox" name="publisher">
|
||||||
<property name="editable" >
|
<property name="editable">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="1" >
|
<item row="1" column="1">
|
||||||
<widget class="QLineEdit" name="authors" />
|
<widget class="QLineEdit" name="authors"/>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="groupBox_2" >
|
<widget class="QGroupBox" name="groupBox_2">
|
||||||
<property name="title" >
|
<property name="title">
|
||||||
<string>Comments</string>
|
<string>Comments</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout_4" >
|
<layout class="QGridLayout" name="gridLayout_4">
|
||||||
<item row="0" column="0" >
|
<item row="0" column="0">
|
||||||
<widget class="QTextEdit" name="comments" />
|
<widget class="QTextEdit" name="comments"/>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="fetch_metadata_button" >
|
<widget class="QPushButton" name="fetch_metadata_button">
|
||||||
<property name="text" >
|
<property name="text">
|
||||||
<string>Fetch metadata from server</string>
|
<string>&Fetch metadata from server</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QWidget" name="layoutWidget_2" >
|
<widget class="QWidget" name="layoutWidget_2">
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_2" >
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="af_group_box" >
|
<widget class="QGroupBox" name="af_group_box">
|
||||||
<property name="sizePolicy" >
|
<property name="sizePolicy">
|
||||||
<sizepolicy vsizetype="Minimum" hsizetype="Preferred" >
|
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
|
||||||
<horstretch>0</horstretch>
|
<horstretch>0</horstretch>
|
||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="title" >
|
<property name="title">
|
||||||
<string>Available Formats</string>
|
<string>Available Formats</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout" >
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
<item>
|
<item>
|
||||||
<layout class="QGridLayout" name="gridLayout" >
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
<item rowspan="3" row="0" column="0" >
|
<item row="0" column="0" rowspan="3">
|
||||||
<widget class="QListWidget" name="formats" >
|
<widget class="QListWidget" name="formats">
|
||||||
<property name="sizePolicy" >
|
<property name="sizePolicy">
|
||||||
<sizepolicy vsizetype="Minimum" hsizetype="Minimum" >
|
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||||
<horstretch>0</horstretch>
|
<horstretch>0</horstretch>
|
||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="maximumSize" >
|
<property name="maximumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>16777215</width>
|
<width>16777215</width>
|
||||||
<height>130</height>
|
<height>130</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="iconSize" >
|
<property name="iconSize">
|
||||||
<size>
|
<size>
|
||||||
<width>64</width>
|
<width>64</width>
|
||||||
<height>64</height>
|
<height>64</height>
|
||||||
@ -418,19 +419,19 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="1" >
|
<item row="0" column="1">
|
||||||
<widget class="QToolButton" name="add_format_button" >
|
<widget class="QToolButton" name="add_format_button">
|
||||||
<property name="toolTip" >
|
<property name="toolTip">
|
||||||
<string>Add a new format for this book to the database</string>
|
<string>Add a new format for this book to the database</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="text" >
|
<property name="text">
|
||||||
<string>...</string>
|
<string>...</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon" >
|
<property name="icon">
|
||||||
<iconset resource="../images.qrc" >
|
<iconset resource="../images.qrc">
|
||||||
<normaloff>:/images/add_book.svg</normaloff>:/images/add_book.svg</iconset>
|
<normaloff>:/images/add_book.svg</normaloff>:/images/add_book.svg</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="iconSize" >
|
<property name="iconSize">
|
||||||
<size>
|
<size>
|
||||||
<width>32</width>
|
<width>32</width>
|
||||||
<height>32</height>
|
<height>32</height>
|
||||||
@ -438,19 +439,19 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="1" >
|
<item row="2" column="1">
|
||||||
<widget class="QToolButton" name="remove_format_button" >
|
<widget class="QToolButton" name="remove_format_button">
|
||||||
<property name="toolTip" >
|
<property name="toolTip">
|
||||||
<string>Remove the selected formats for this book from the database.</string>
|
<string>Remove the selected formats for this book from the database.</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="text" >
|
<property name="text">
|
||||||
<string>...</string>
|
<string>...</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon" >
|
<property name="icon">
|
||||||
<iconset resource="../images.qrc" >
|
<iconset resource="../images.qrc">
|
||||||
<normaloff>:/images/trash.svg</normaloff>:/images/trash.svg</iconset>
|
<normaloff>:/images/trash.svg</normaloff>:/images/trash.svg</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="iconSize" >
|
<property name="iconSize">
|
||||||
<size>
|
<size>
|
||||||
<width>32</width>
|
<width>32</width>
|
||||||
<height>32</height>
|
<height>32</height>
|
||||||
@ -458,19 +459,19 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="1" >
|
<item row="1" column="1">
|
||||||
<widget class="QToolButton" name="button_set_cover" >
|
<widget class="QToolButton" name="button_set_cover">
|
||||||
<property name="toolTip" >
|
<property name="toolTip">
|
||||||
<string>Set the cover for the book from the selected format</string>
|
<string>Set the cover for the book from the selected format</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="text" >
|
<property name="text">
|
||||||
<string>...</string>
|
<string>...</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon" >
|
<property name="icon">
|
||||||
<iconset resource="../images.qrc" >
|
<iconset resource="../images.qrc">
|
||||||
<normaloff>:/images/book.svg</normaloff>:/images/book.svg</iconset>
|
<normaloff>:/images/book.svg</normaloff>:/images/book.svg</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="iconSize" >
|
<property name="iconSize">
|
||||||
<size>
|
<size>
|
||||||
<width>32</width>
|
<width>32</width>
|
||||||
<height>32</height>
|
<height>32</height>
|
||||||
@ -485,96 +486,96 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="bc_box" >
|
<widget class="QGroupBox" name="bc_box">
|
||||||
<property name="sizePolicy" >
|
<property name="sizePolicy">
|
||||||
<sizepolicy vsizetype="Expanding" hsizetype="Preferred" >
|
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||||
<horstretch>0</horstretch>
|
<horstretch>0</horstretch>
|
||||||
<verstretch>10</verstretch>
|
<verstretch>10</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="title" >
|
<property name="title">
|
||||||
<string>Book Cover</string>
|
<string>Book Cover</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_4" >
|
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||||
<item>
|
<item>
|
||||||
<widget class="ImageView" name="cover" >
|
<widget class="ImageView" name="cover">
|
||||||
<property name="sizePolicy" >
|
<property name="sizePolicy">
|
||||||
<sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
|
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||||
<horstretch>0</horstretch>
|
<horstretch>0</horstretch>
|
||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="text" >
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
<property name="pixmap" >
|
<property name="pixmap">
|
||||||
<pixmap resource="../images.qrc" >:/images/book.svg</pixmap>
|
<pixmap resource="../images.qrc">:/images/book.svg</pixmap>
|
||||||
</property>
|
</property>
|
||||||
<property name="scaledContents" >
|
<property name="scaledContents">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QVBoxLayout" name="_4" >
|
<layout class="QVBoxLayout" name="_4">
|
||||||
<property name="spacing" >
|
<property name="spacing">
|
||||||
<number>6</number>
|
<number>6</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizeConstraint" >
|
<property name="sizeConstraint">
|
||||||
<enum>QLayout::SetMaximumSize</enum>
|
<enum>QLayout::SetMaximumSize</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="margin" >
|
<property name="margin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label_5" >
|
<widget class="QLabel" name="label_5">
|
||||||
<property name="text" >
|
<property name="text">
|
||||||
<string>Change &cover image:</string>
|
<string>Change &cover image:</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="buddy" >
|
<property name="buddy">
|
||||||
<cstring>cover_path</cstring>
|
<cstring>cover_path</cstring>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="_5" >
|
<layout class="QHBoxLayout" name="_5">
|
||||||
<property name="spacing" >
|
<property name="spacing">
|
||||||
<number>6</number>
|
<number>6</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="margin" >
|
<property name="margin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLineEdit" name="cover_path" >
|
<widget class="QLineEdit" name="cover_path">
|
||||||
<property name="readOnly" >
|
<property name="readOnly">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QToolButton" name="cover_button" >
|
<widget class="QToolButton" name="cover_button">
|
||||||
<property name="toolTip" >
|
<property name="toolTip">
|
||||||
<string>Browse for an image to use as the cover of this book.</string>
|
<string>Browse for an image to use as the cover of this book.</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="text" >
|
<property name="text">
|
||||||
<string>...</string>
|
<string>...</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon" >
|
<property name="icon">
|
||||||
<iconset resource="../images.qrc" >
|
<iconset resource="../images.qrc">
|
||||||
<normaloff>:/images/document_open.svg</normaloff>:/images/document_open.svg</iconset>
|
<normaloff>:/images/document_open.svg</normaloff>:/images/document_open.svg</iconset>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QToolButton" name="reset_cover" >
|
<widget class="QToolButton" name="reset_cover">
|
||||||
<property name="toolTip" >
|
<property name="toolTip">
|
||||||
<string>Reset cover to default</string>
|
<string>Reset cover to default</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="text" >
|
<property name="text">
|
||||||
<string>...</string>
|
<string>...</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon" >
|
<property name="icon">
|
||||||
<iconset resource="../images.qrc" >
|
<iconset resource="../images.qrc">
|
||||||
<normaloff>:/images/trash.svg</normaloff>:/images/trash.svg</iconset>
|
<normaloff>:/images/trash.svg</normaloff>:/images/trash.svg</iconset>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
@ -584,21 +585,21 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="_6" >
|
<layout class="QHBoxLayout" name="_6">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="fetch_cover_button" >
|
<widget class="QPushButton" name="fetch_cover_button">
|
||||||
<property name="text" >
|
<property name="text">
|
||||||
<string>Fetch cover image from server</string>
|
<string>Fetch &cover image from server</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="password_button" >
|
<widget class="QPushButton" name="password_button">
|
||||||
<property name="toolTip" >
|
<property name="toolTip">
|
||||||
<string>Change the username and/or password for your account at LibraryThing.com</string>
|
<string>Change the username and/or password for your account at LibraryThing.com</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="text" >
|
<property name="text">
|
||||||
<string>Change password</string>
|
<string>Change &password</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@ -619,11 +620,11 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QDialogButtonBox" name="button_box" >
|
<widget class="QDialogButtonBox" name="button_box">
|
||||||
<property name="orientation" >
|
<property name="orientation">
|
||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="standardButtons" >
|
<property name="standardButtons">
|
||||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
@ -666,7 +667,7 @@
|
|||||||
<tabstop>button_box</tabstop>
|
<tabstop>button_box</tabstop>
|
||||||
</tabstops>
|
</tabstops>
|
||||||
<resources>
|
<resources>
|
||||||
<include location="../images.qrc" />
|
<include location="../images.qrc"/>
|
||||||
</resources>
|
</resources>
|
||||||
<connections>
|
<connections>
|
||||||
<connection>
|
<connection>
|
||||||
@ -675,11 +676,11 @@
|
|||||||
<receiver>MetadataSingleDialog</receiver>
|
<receiver>MetadataSingleDialog</receiver>
|
||||||
<slot>accept()</slot>
|
<slot>accept()</slot>
|
||||||
<hints>
|
<hints>
|
||||||
<hint type="sourcelabel" >
|
<hint type="sourcelabel">
|
||||||
<x>261</x>
|
<x>261</x>
|
||||||
<y>710</y>
|
<y>710</y>
|
||||||
</hint>
|
</hint>
|
||||||
<hint type="destinationlabel" >
|
<hint type="destinationlabel">
|
||||||
<x>157</x>
|
<x>157</x>
|
||||||
<y>274</y>
|
<y>274</y>
|
||||||
</hint>
|
</hint>
|
||||||
@ -691,11 +692,11 @@
|
|||||||
<receiver>MetadataSingleDialog</receiver>
|
<receiver>MetadataSingleDialog</receiver>
|
||||||
<slot>reject()</slot>
|
<slot>reject()</slot>
|
||||||
<hints>
|
<hints>
|
||||||
<hint type="sourcelabel" >
|
<hint type="sourcelabel">
|
||||||
<x>329</x>
|
<x>329</x>
|
||||||
<y>710</y>
|
<y>710</y>
|
||||||
</hint>
|
</hint>
|
||||||
<hint type="destinationlabel" >
|
<hint type="destinationlabel">
|
||||||
<x>286</x>
|
<x>286</x>
|
||||||
<y>274</y>
|
<y>274</y>
|
||||||
</hint>
|
</hint>
|
||||||
|
@ -450,7 +450,9 @@ class DocumentView(QWebView):
|
|||||||
self.manager.scrolled(self.scroll_fraction)
|
self.manager.scrolled(self.scroll_fraction)
|
||||||
|
|
||||||
def wheel_event(self, down=True):
|
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):
|
def next_page(self):
|
||||||
if self.document.at_bottom:
|
if self.document.at_bottom:
|
||||||
@ -538,6 +540,26 @@ class DocumentView(QWebView):
|
|||||||
self.next_page()
|
self.next_page()
|
||||||
elif key in [Qt.Key_PageUp, Qt.Key_Backspace, Qt.Key_Up]:
|
elif key in [Qt.Key_PageUp, Qt.Key_Backspace, Qt.Key_Up]:
|
||||||
self.previous_page()
|
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:
|
else:
|
||||||
return QWebView.keyPressEvent(self, event)
|
return QWebView.keyPressEvent(self, event)
|
||||||
|
|
||||||
|
@ -342,6 +342,12 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
|
|||||||
if pos is not None:
|
if pos is not None:
|
||||||
self.goto_page(pos)
|
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):
|
def goto_page(self, new_page):
|
||||||
if self.current_page is not None:
|
if self.current_page is not None:
|
||||||
for page in self.iterator.spine:
|
for page in self.iterator.spine:
|
||||||
|
@ -7,7 +7,7 @@ __docformat__ = 'restructuredtext en'
|
|||||||
HTTP server for remote access to the calibre database.
|
HTTP server for remote access to the calibre database.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import sys, textwrap, operator, os, re, logging, subprocess
|
import sys, textwrap, operator, os, re, logging
|
||||||
from itertools import repeat
|
from itertools import repeat
|
||||||
from logging.handlers import RotatingFileHandler
|
from logging.handlers import RotatingFileHandler
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
@ -123,15 +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?
|
How do I use |app| with my iPhone?
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
First install the Stanza reader on your iPhone from http://www.lexcycle.com . Then,
|
First install the Stanza reader on your iPhone from http://www.lexcycle.com . Then,
|
||||||
|
|
||||||
* Set the output format for calibre to EPUB (The output format can be set next to the big red heart)
|
* 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.
|
* 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 |app|'s preferences and leave |app| running.
|
* 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. If not, try the following:
|
|
||||||
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.
|
|
||||||
|
|
||||||
|
Now you should be able to access your books on your iPhone.
|
||||||
|
|
||||||
Library Management
|
Library Management
|
||||||
------------------
|
------------------
|
||||||
|
@ -177,11 +177,11 @@ else:
|
|||||||
compatibility='%s works on OS X Tiger and above.'%(__appname__,),
|
compatibility='%s works on OS X Tiger and above.'%(__appname__,),
|
||||||
path=MOBILEREAD+file, app=__appname__,
|
path=MOBILEREAD+file, app=__appname__,
|
||||||
note=Markup(\
|
note=Markup(\
|
||||||
'''
|
u'''
|
||||||
<ol>
|
<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>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>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>
|
</ol>
|
||||||
'''))
|
'''))
|
||||||
return 'binary.html', data, None
|
return 'binary.html', data, None
|
||||||
|
@ -933,7 +933,11 @@ class Reaper(threading.Thread):
|
|||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
while 1:
|
while 1:
|
||||||
|
try:
|
||||||
self.zeroconf.wait(10 * 1000)
|
self.zeroconf.wait(10 * 1000)
|
||||||
|
except TypeError: # By Kovid
|
||||||
|
globals()['_GLOBAL_DONE'] = 1
|
||||||
|
return
|
||||||
if globals()['_GLOBAL_DONE']:
|
if globals()['_GLOBAL_DONE']:
|
||||||
return
|
return
|
||||||
now = currentTimeMillis()
|
now = currentTimeMillis()
|
||||||
|
@ -41,7 +41,7 @@ def publish(desc, type, port, properties=None, add_hostname=True):
|
|||||||
'''
|
'''
|
||||||
port = int(port)
|
port = int(port)
|
||||||
server = start_server()
|
server = start_server()
|
||||||
hostname = socket.gethostname()
|
hostname = socket.gethostname().partition('.')[0]
|
||||||
if add_hostname:
|
if add_hostname:
|
||||||
desc += ' (on %s)'%hostname
|
desc += ' (on %s)'%hostname
|
||||||
local_ip = get_external_ip()
|
local_ip = get_external_ip()
|
||||||
@ -58,40 +58,3 @@ def stop_server():
|
|||||||
global _server
|
global _server
|
||||||
if _server is not None:
|
if _server is not None:
|
||||||
_server.close()
|
_server.close()
|
||||||
|
|
||||||
'''
|
|
||||||
class Publish(object):
|
|
||||||
|
|
||||||
def __init__(self, desc, name, port, txt=''):
|
|
||||||
self.desc = desc
|
|
||||||
self.name = name
|
|
||||||
self.port = port
|
|
||||||
self.txt = txt
|
|
||||||
|
|
||||||
def start(self):
|
|
||||||
if iswindows:
|
|
||||||
return
|
|
||||||
if isosx:
|
|
||||||
args = ['dns-sd', self.desc, self.name, '.', self.port]
|
|
||||||
else:
|
|
||||||
args = ['avahi-publish-service', self.desc, self.name, self.port]
|
|
||||||
if self.txt:
|
|
||||||
args.append(self.txt)
|
|
||||||
|
|
||||||
self.process = subprocess.Popen(args)
|
|
||||||
|
|
||||||
def stop(self):
|
|
||||||
if iswindows:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
process = getattr(self, 'process', None)
|
|
||||||
if process is not None:
|
|
||||||
process.poll()
|
|
||||||
if process.returncode is not None:
|
|
||||||
process.terminate()
|
|
||||||
process.poll()
|
|
||||||
if process.returncode is not None:
|
|
||||||
process.kill()
|
|
||||||
|
|
||||||
def publish(desc, name, port, txt):
|
|
||||||
'''
|
|
@ -1,14 +1,7 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2008, Darko Miletic <darko.miletic at gmail.com>'
|
__copyright__ = '2008-2009, AprilHare, 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'
|
|
||||||
'''
|
'''
|
||||||
newscientist.com
|
newscientist.com
|
||||||
'''
|
'''
|
||||||
@ -16,23 +9,34 @@ newscientist.com
|
|||||||
from calibre.web.feeds.news import BasicNewsRecipe
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
class NewScientist(BasicNewsRecipe):
|
class NewScientist(BasicNewsRecipe):
|
||||||
title = u'New Scientist - Online News'
|
title = 'New Scientist - Online News'
|
||||||
__author__ = 'Darko Miletic'
|
__author__ = 'Darko Miletic'
|
||||||
description = 'News from Science'
|
description = 'Science news and science articles from New Scientist.'
|
||||||
language = _('English')
|
language = _('English')
|
||||||
|
publisher = 'New Scientist'
|
||||||
|
category = 'science news, science articles, science jobs, drugs, cancer, depression, computer software, sex'
|
||||||
|
delay = 3
|
||||||
oldest_article = 7
|
oldest_article = 7
|
||||||
max_articles_per_feed = 100
|
max_articles_per_feed = 100
|
||||||
no_stylesheets = True
|
no_stylesheets = True
|
||||||
use_embedded_content = False
|
use_embedded_content = False
|
||||||
|
remove_javascript = True
|
||||||
|
encoding = 'utf-8'
|
||||||
|
|
||||||
keep_only_tags = [
|
html2lrf_options = [
|
||||||
dict(name='div' , attrs={'id':'pgtop' })
|
'--comment', description
|
||||||
,dict(name='div' , attrs={'id':'maincol' })
|
, '--category', category
|
||||||
|
, '--publisher', publisher
|
||||||
]
|
]
|
||||||
|
|
||||||
|
html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"'
|
||||||
|
|
||||||
|
keep_only_tags = [dict(name='div', attrs={'id':['pgtop','maincol']})]
|
||||||
|
|
||||||
remove_tags = [
|
remove_tags = [
|
||||||
dict(name='div' , attrs={'class':'hldBd' })
|
dict(name='div', attrs={'class':['hldBd','adline','pnl','infotext' ]})
|
||||||
,dict(name='div' , attrs={'id':'compnl' })
|
,dict(name='div', attrs={'id' :['compnl','artIssueInfo','artTools']})
|
||||||
,dict(name='div' , attrs={'id':'artIssueInfo' })
|
,dict(name='p' , attrs={'class':['marker','infotext' ]})
|
||||||
]
|
]
|
||||||
|
|
||||||
feeds = [
|
feeds = [
|
||||||
@ -46,3 +50,20 @@ class NewScientist(BasicNewsRecipe):
|
|||||||
,(u'Science in Society' , u'http://www.newscientist.com/feed/view?id=5&type=channel' )
|
,(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' )
|
,(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'
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user