KG updates

This commit is contained in:
GRiker 2011-06-14 05:14:38 -06:00
commit de4534e150
15 changed files with 105 additions and 77 deletions

View file

@ -594,7 +594,7 @@ def set_metadata(self, stream, mi, type):
from calibre.devices.irexdr.driver import IREXDR1000, IREXDR800
from calibre.devices.jetbook.driver import JETBOOK, MIBUK, JETBOOK_MINI
from calibre.devices.kindle.driver import KINDLE, KINDLE2, KINDLE_DX
from calibre.devices.nook.driver import NOOK, NOOK_COLOR, NOOK_TSR
from calibre.devices.nook.driver import NOOK, NOOK_COLOR
from calibre.devices.prs505.driver import PRS505
from calibre.devices.user_defined.driver import USER_DEFINED
from calibre.devices.android.driver import ANDROID, S60
@ -603,10 +603,11 @@ def set_metadata(self, stream, mi, type):
from calibre.devices.nuut2.driver import NUUT2
from calibre.devices.iriver.driver import IRIVER_STORY
from calibre.devices.binatone.driver import README
from calibre.devices.hanvon.driver import N516, EB511, ALEX, AZBOOKA, THEBOOK
from calibre.devices.hanvon.driver import (N516, EB511, ALEX, AZBOOKA, THEBOOK,
LIBREAIR)
from calibre.devices.edge.driver import EDGE
from calibre.devices.teclast.driver import TECLAST_K3, NEWSMY, IPAPYRUS, \
SOVOS, PICO, SUNSTECH_EB700, ARCHOS7O, STASH, WEXLER
from calibre.devices.teclast.driver import (TECLAST_K3, NEWSMY, IPAPYRUS,
SOVOS, PICO, SUNSTECH_EB700, ARCHOS7O, STASH, WEXLER)
from calibre.devices.sne.driver import SNE
from calibre.devices.misc import (PALMPRE, AVANT, SWEEX, PDNOVEL,
GEMEI, VELOCITYMICRO, PDNOVEL_KOBO, LUMIREAD, ALURATEK_COLOR,
@ -693,7 +694,7 @@ def set_metadata(self, stream, mi, type):
KINDLE,
KINDLE2,
KINDLE_DX,
NOOK, NOOK_COLOR, NOOK_TSR,
NOOK, NOOK_COLOR,
PRS505,
ANDROID,
S60,
@ -716,7 +717,7 @@ def set_metadata(self, stream, mi, type):
EB600,
README,
N516,
THEBOOK,
THEBOOK, LIBREAIR,
EB511,
ELONEX,
TECLAST_K3,

View file

@ -52,6 +52,18 @@ class THEBOOK(N516):
EBOOK_DIR_MAIN = 'My books'
WINDOWS_CARD_A_MEM = '_FILE-STOR_GADGE'
class LIBREAIR(N516):
name = 'Libre Air Driver'
gui_name = 'Libre Air'
description = _('Communicate with the Libre Air reader.')
author = 'Kovid Goyal'
FORMATS = ['epub', 'mobi', 'prc', 'fb2', 'rtf', 'txt', 'pdf']
BCD = [0x399]
VENDOR_NAME = 'ALURATEK'
WINDOWS_MAIN_MEM = WINDOWS_CARD_A_MEM = '_FILE-STOR_GADGET'
EBOOK_DIR_MAIN = 'Books'
class ALEX(N516):
name = 'Alex driver'

View file

@ -81,55 +81,27 @@ def sanitize_path_components(self, components):
return [x.replace('#', '_') for x in components]
class NOOK_COLOR(NOOK):
gui_name = _('Nook Color')
description = _('Communicate with the Nook Color eBook reader.')
description = _('Communicate with the Nook Color and TSR eBook readers.')
PRODUCT_ID = [0x002]
PRODUCT_ID = [0x002, 0x003]
BCD = [0x216]
WINDOWS_MAIN_MEM = WINDOWS_CARD_A_MEM = 'EBOOK_DISK'
WINDOWS_MAIN_MEM = WINDOWS_CARD_A_MEM = 'EBOOK_DISK'
EBOOK_DIR_MAIN = 'My Files'
def upload_cover(self, path, filename, metadata, filepath):
pass
def get_carda_ebook_dir(self, for_upload=False):
if for_upload:
return self.EBOOK_DIR_MAIN
return ''
def create_upload_path(self, path, mdata, fname, create_dirs=True):
filepath = NOOK.create_upload_path(self, path, mdata, fname,
create_dirs=False)
edm = self.EBOOK_DIR_MAIN
subdir = 'Books'
if mdata.tags:
if _('News') in mdata.tags:
subdir = 'Magazines'
filepath = filepath.replace(os.sep+edm+os.sep,
os.sep+edm+os.sep+subdir+os.sep)
filedir = os.path.dirname(filepath)
if create_dirs and not os.path.exists(filedir):
os.makedirs(filedir)
return filepath
def upload_cover(self, path, filename, metadata, filepath):
pass
def get_carda_ebook_dir(self, for_upload=False):
if for_upload:
return 'My Files/Books'
return ''
class NOOK_TSR(NOOK):
gui_name = _('Nook Simple')
description = _('Communicate with the Nook TSR eBook reader.')
PRODUCT_ID = [0x003]
BCD = [0x216]
EBOOK_DIR_MAIN = 'My Files/Books'
WINDOWS_MAIN_MEM = WINDOWS_CARD_A_MEM = 'EBOOK_DISK'
def upload_cover(self, path, filename, metadata, filepath):
pass
def get_carda_ebook_dir(self, for_upload=False):
if for_upload:
return 'My Files/Books'
return ''
is_news = mdata.tags and _('News') in mdata.tags
subdir = 'Magazines' if is_news else 'Books'
path = os.path.join(path, subdir)
return USBMS.create_upload_path(self, path, mdata, fname,
create_dirs=create_dirs)

View file

@ -394,6 +394,13 @@ def workaround_ade_quirks(self): # {{{
for tag in XPath('//h:img[@src]')(root):
tag.set('src', tag.get('src', '').replace('&', ''))
# ADE whimpers in fright when it encounters a <td> outside a
# <table>
in_table = XPath('ancestor::h:table')
for tag in XPath('//h:td|//h:tr|//h:th')(root):
if not in_table(tag):
tag.tag = XHTML('div')
special_chars = re.compile(u'[\u200b\u00ad]')
for elem in root.iterdescendants():
if getattr(elem, 'text', False):
@ -413,7 +420,7 @@ def workaround_ade_quirks(self): # {{{
rule.style.removeProperty('margin-left')
# padding-left breaks rendering in webkit and gecko
rule.style.removeProperty('padding-left')
# Change whitespace:pre to pre-line to accommodate readers that
# Change whitespace:pre to pre-wrap to accommodate readers that
# cannot scroll horizontally
for rule in stylesheet.data.cssRules.rulesOfType(CSSRule.STYLE_RULE):
style = rule.style

View file

@ -455,13 +455,16 @@ def resource_adder(self, link_, base=None):
bhref = os.path.basename(link)
id, href = self.oeb.manifest.generate(id='added',
href=bhref)
guessed = self.guess_type(href)[0]
media_type = guessed or self.BINARY_MIME
if 'text' in media_type:
self.log.warn('Ignoring link to text file %r'%link_)
return None
self.oeb.log.debug('Added', link)
self.oeb.container = self.DirContainer(os.path.dirname(link),
self.oeb.log, ignore_opf=True)
# Load into memory
guessed = self.guess_type(href)[0]
media_type = guessed or self.BINARY_MIME
item = self.oeb.manifest.add(id, href, media_type)
item.html_input_href = bhref
if guessed in self.OEB_STYLES:

View file

@ -442,9 +442,12 @@ def mobimlize_elem(self, elem, stylizer, bstate, istates,
if tag in TABLE_TAGS and self.ignore_tables:
tag = 'span' if tag == 'td' else 'div'
# GR: Added 'width', 'border' and 'scope'
if tag == 'table':
css = style.cssdict()
if 'border' in css or 'border-width' in css:
elem.set('border', '1')
if tag in TABLE_TAGS:
for attr in ('rowspan', 'colspan','width','border','scope'):
for attr in ('rowspan', 'colspan', 'width', 'border', 'scope'):
if attr in elem.attrib:
istate.attrib[attr] = elem.attrib[attr]
if tag == 'q':

View file

@ -1110,6 +1110,8 @@ def search(self, text, reset=True):
if self.last_search:
self.searched.emit(True)
def research(self, reset=True):
self.search(self.last_search, reset)
def sort(self, col, order, reset=True):
descending = order != Qt.AscendingOrder
@ -1171,6 +1173,8 @@ def set_database(self, db):
self.custom_columns = {}
self.db = db
self.map = list(range(0, len(db)))
self.research(reset=False)
self.resort()
def cover(self, row):
item = self.db[self.map[row]]
@ -1319,8 +1323,6 @@ def data(self, index, role):
ans = Qt.AlignVCenter | ALIGNMENT_MAP[self.alignment_map.get(cname,
'left')]
return QVariant(ans)
return NONE
def headerData(self, section, orientation, role):

View file

@ -48,7 +48,7 @@ class BooksView(QTableView): # {{{
files_dropped = pyqtSignal(object)
add_column_signal = pyqtSignal()
def __init__(self, parent, modelcls=BooksModel):
def __init__(self, parent, modelcls=BooksModel, use_edit_metadata_dialog=True):
QTableView.__init__(self, parent)
self.setEditTriggers(self.EditKeyPressed)
@ -60,8 +60,12 @@ def __init__(self, parent, modelcls=BooksModel):
elif tweaks['doubleclick_on_library_view'] == 'edit_metadata':
# Must not enable single-click to edit, or the field will remain
# open in edit mode underneath the edit metadata dialog
self.doubleClicked.connect(
partial(parent.iactions['Edit Metadata'].edit_metadata, checked=False))
if use_edit_metadata_dialog:
self.doubleClicked.connect(
partial(parent.iactions['Edit Metadata'].edit_metadata,
checked=False))
else:
self.setEditTriggers(self.DoubleClicked|self.editTriggers())
self.drag_allowed = True
self.setDragEnabled(True)
@ -792,7 +796,8 @@ def row_count(self):
class DeviceBooksView(BooksView): # {{{
def __init__(self, parent):
BooksView.__init__(self, parent, DeviceBooksModel)
BooksView.__init__(self, parent, DeviceBooksModel,
use_edit_metadata_dialog=False)
self.can_add_columns = False
self.columns_resized = False
self.resize_on_select = False

View file

@ -22,11 +22,7 @@
class ConditionEditor(QWidget): # {{{
def __init__(self, fm, parent=None):
QWidget.__init__(self, parent)
self.fm = fm
self.action_map = {
ACTION_MAP = {
'bool' : (
(_('is true'), 'is true',),
(_('is false'), 'is false'),
@ -61,10 +57,17 @@ def __init__(self, fm, parent=None):
(_('is set'), 'is set'),
(_('is not set'), 'is not set'),
),
}
}
for x in ('float', 'rating', 'datetime'):
self.action_map[x] = self.action_map['int']
for x in ('float', 'rating', 'datetime'):
ACTION_MAP[x] = ACTION_MAP['int']
def __init__(self, fm, parent=None):
QWidget.__init__(self, parent)
self.fm = fm
self.action_map = self.ACTION_MAP
self.l = l = QGridLayout(self)
self.setLayout(l)
@ -446,9 +449,15 @@ def rule_to_html(self, col, rule):
def condition_to_html(self, condition):
c, a, v = condition
action_name = a
for actions in ConditionEditor.ACTION_MAP.itervalues():
for trans, ac in actions:
if ac == a:
action_name = trans
return (
_('<li>If the <b>%s</b> column <b>%s</b> value: <b>%s</b>') %
(c, a, prepare_string_for_xml(v)))
(c, action_name, prepare_string_for_xml(v)))
# }}}

View file

@ -6,7 +6,7 @@
__copyright__ = '2011, John Schember <john@nachtimwald.com>'
__docformat__ = 'restructuredtext en'
from PyQt4.Qt import (QWidget, QIcon, QDialog)
from PyQt4.Qt import (QWidget, QIcon, QDialog, QComboBox)
from calibre.gui2.store.config.chooser.adv_search_builder import AdvSearchBuilderDialog
from calibre.gui2.store.config.chooser.chooser_widget_ui import Ui_Form
@ -18,6 +18,8 @@ def __init__(self):
self.setupUi(self)
self.query.initialize('store_config_chooser_query')
self.query.setSizeAdjustPolicy(QComboBox.AdjustToMinimumContentsLengthWithIcon)
self.query.setMinimumContentsLength(25)
self.adv_search_builder.setIcon(QIcon(I('search.png')))

View file

@ -7,7 +7,7 @@
__docformat__ = 'restructuredtext en'
from PyQt4.Qt import (Qt, QDialog, QIcon)
from PyQt4.Qt import (Qt, QDialog, QIcon, QComboBox)
from calibre.gui2.store.mobileread.adv_search_builder import AdvSearchBuilderDialog
from calibre.gui2.store.mobileread.models import BooksModel
@ -21,6 +21,8 @@ def __init__(self, plugin, *args):
self.plugin = plugin
self.search_query.initialize('store_mobileread_search')
self.search_query.setSizeAdjustPolicy(QComboBox.AdjustToMinimumContentsLengthWithIcon)
self.search_query.setMinimumContentsLength(25)
self.adv_search_button.setIcon(QIcon(I('search.png')))

View file

@ -10,7 +10,8 @@
from random import shuffle
from PyQt4.Qt import (Qt, QDialog, QDialogButtonBox, QTimer, QCheckBox, QLabel,
QVBoxLayout, QIcon, QWidget, QTabWidget, QGridLayout)
QVBoxLayout, QIcon, QWidget, QTabWidget, QGridLayout,
QComboBox)
from calibre.gui2 import JSONConfig, info_dialog
from calibre.gui2.progress_indicator import ProgressIndicator
@ -57,6 +58,8 @@ def __init__(self, gui, parent=None, query=''):
# Set the search query
self.search_edit.setText(query)
self.search_edit.setSizeAdjustPolicy(QComboBox.AdjustToMinimumContentsLengthWithIcon)
self.search_edit.setMinimumContentsLength(25)
# Create and add the progress indicator
self.pi = ProgressIndicator(self, 24)

View file

@ -610,7 +610,7 @@ def __init__(self, data=None, category_icon=None, icon_map=None,
self.temporary = temporary
self.tag = Tag(data, category=category_key,
is_editable=category_key not in ['news', 'search', 'identifiers'],
is_searchable=category_key not in ['news', 'search'])
is_searchable=category_key not in ['search'])
elif self.type == self.TAG:
self.icon_state_map[0] = QVariant(data.icon)
@ -1642,7 +1642,13 @@ def tokens(self):
for node in self.category_nodes:
if node.tag.state:
ans.append('%s:%s'%(node.category_key, node_searches[node.tag.state]))
if node.category_key == "news":
if node_searches[node.tag.state] == 'true':
ans.append('tags:=news')
else:
ans.append('( not tags:=news )')
else:
ans.append('%s:%s'%(node.category_key, node_searches[node.tag.state]))
key = node.category_key
for tag_item in node.child_tags():

View file

@ -417,7 +417,7 @@ You might find the following tips useful.
* Create a custom composite column to test templates. Once you have the column, you can change its template simply by double-clicking on the column. Hide the column when you are not testing.
* Templates can use other templates by referencing a composite custom column.
* In a plugboard, you can set a field to empty (or whatever is equivalent to empty) by using the special template ``{null}``. This template will always evaluate to an empty string.
* In a plugboard, you can set a field to empty (or whatever is equivalent to empty) by using the special template ``{}``. This template will always evaluate to an empty string.
* The technique described above to show numbers even if they have a zero value works with the standard field series_index.
.. toctree::

View file

@ -101,6 +101,7 @@ def get_custom_recipe_collection(*args):
if recipe_class is not None:
rmap['custom:%s'%id_] = recipe_class
except:
print 'Failed to load recipe from: %r'%fname
import traceback
traceback.print_exc()
continue