mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
...
This commit is contained in:
commit
f805cc60d6
@ -19,7 +19,7 @@ class StoreAction(InterfaceAction):
|
||||
action_spec = (_('Get books'), 'store.png', None, None)
|
||||
|
||||
def genesis(self):
|
||||
self.config = JSONConfig('store_action')
|
||||
self.config = JSONConfig('store/action')
|
||||
|
||||
self.qaction.triggered.connect(self.search)
|
||||
self.store_menu = QMenu()
|
||||
|
@ -18,19 +18,18 @@ from PyQt4.Qt import Qt, QUrl, QDialog, QAbstractItemModel, QModelIndex, QVarian
|
||||
pyqtSignal
|
||||
|
||||
from calibre import browser
|
||||
from calibre.gui2 import open_url, NONE
|
||||
from calibre.gui2 import open_url, NONE, JSONConfig
|
||||
from calibre.gui2.store import StorePlugin
|
||||
from calibre.gui2.store.basic_config import BasicStoreConfig
|
||||
from calibre.gui2.store.mobileread_store_dialog_ui import Ui_Dialog
|
||||
from calibre.gui2.store.search_result import SearchResult
|
||||
from calibre.gui2.store.web_store_dialog import WebStoreDialog
|
||||
from calibre.utils.config import DynamicConfig
|
||||
from calibre.utils.icu import sort_key
|
||||
|
||||
class MobileReadStore(BasicStoreConfig, StorePlugin):
|
||||
|
||||
def genesis(self):
|
||||
self.config = DynamicConfig('store_' + self.name)
|
||||
self.config = JSONConfig('store/store/' + self.name)
|
||||
self.rlock = RLock()
|
||||
|
||||
def open(self, parent=None, detail_item=None, external=False):
|
||||
@ -83,7 +82,7 @@ class MobileReadStore(BasicStoreConfig, StorePlugin):
|
||||
with self.rlock:
|
||||
url = 'http://www.mobileread.com/forums/ebooks.php?do=getlist&type=html'
|
||||
|
||||
last_download = self.config.get(self.name + '_last_download', None)
|
||||
last_download = self.config.get('last_download', None)
|
||||
# Don't update the book list if our cache is less than one week old.
|
||||
if last_download and (time.time() - last_download) < 604800:
|
||||
return
|
||||
@ -118,12 +117,34 @@ class MobileReadStore(BasicStoreConfig, StorePlugin):
|
||||
|
||||
# Save the book list and it's create time.
|
||||
if books:
|
||||
self.config[self.name + '_last_download'] = time.time()
|
||||
self.config[self.name + '_book_list'] = books
|
||||
self.config['last_download'] = time.time()
|
||||
self.config['book_list'] = self.seralize_books(books)
|
||||
|
||||
def get_book_list(self, timeout=10):
|
||||
self.update_book_list(timeout=timeout)
|
||||
return self.config.get(self.name + '_book_list', [])
|
||||
return self.deseralize_books(self.config.get('book_list', []))
|
||||
|
||||
def seralize_books(self, books):
|
||||
sbooks = []
|
||||
for b in books:
|
||||
data = {}
|
||||
data['author'] = b.author
|
||||
data['title'] = b.title
|
||||
data['detail_item'] = b.detail_item
|
||||
data['formats'] = b.formats
|
||||
sbooks.append(data)
|
||||
return sbooks
|
||||
|
||||
def deseralize_books(self, sbooks):
|
||||
books = []
|
||||
for s in sbooks:
|
||||
b = SearchResult()
|
||||
b.author = s.get('author', '')
|
||||
b.title = s.get('title', '')
|
||||
b.detail_item = s.get('detail_item', '')
|
||||
b.formats = s.get('formats', '')
|
||||
books.append(b)
|
||||
return books
|
||||
|
||||
|
||||
class MobeReadStoreDialog(QDialog, Ui_Dialog):
|
||||
@ -152,11 +173,11 @@ class MobeReadStoreDialog(QDialog, Ui_Dialog):
|
||||
self.plugin.open(self, result.detail_item)
|
||||
|
||||
def restore_state(self):
|
||||
geometry = self.plugin.config['store_mobileread_dialog_geometry']
|
||||
geometry = self.plugin.config.get('dialog_geometry', None)
|
||||
if geometry:
|
||||
self.restoreGeometry(geometry)
|
||||
|
||||
results_cwidth = self.plugin.config['store_mobileread_dialog_results_view_column_width']
|
||||
results_cwidth = self.plugin.config.get('dialog_results_view_column_width')
|
||||
if results_cwidth:
|
||||
for i, x in enumerate(results_cwidth):
|
||||
if i >= self.results_view.model().columnCount():
|
||||
@ -166,16 +187,16 @@ class MobeReadStoreDialog(QDialog, Ui_Dialog):
|
||||
for i in xrange(self.results_view.model().columnCount()):
|
||||
self.results_view.resizeColumnToContents(i)
|
||||
|
||||
self.results_view.model().sort_col = self.plugin.config.get('store_mobileread_dialog_sort_col', 0)
|
||||
self.results_view.model().sort_order = self.plugin.config.get('store_mobileread_dialog_sort_order', Qt.AscendingOrder)
|
||||
self.results_view.model().sort_col = self.plugin.config.get('dialog_sort_col', 0)
|
||||
self.results_view.model().sort_order = self.plugin.config.get('dialog_sort_order', Qt.AscendingOrder)
|
||||
self.results_view.model().sort(self.results_view.model().sort_col, self.results_view.model().sort_order)
|
||||
self.results_view.header().setSortIndicator(self.results_view.model().sort_col, self.results_view.model().sort_order)
|
||||
|
||||
def save_state(self):
|
||||
self.plugin.config['store_mobileread_dialog_geometry'] = self.saveGeometry()
|
||||
self.plugin.config['store_mobileread_dialog_results_view_column_width'] = [self.results_view.columnWidth(i) for i in range(self.model.columnCount())]
|
||||
self.plugin.config['store_mobileread_dialog_sort_col'] = self.results_view.model().sort_col
|
||||
self.plugin.config['store_mobileread_dialog_sort_order'] = self.results_view.model().sort_order
|
||||
self.plugin.config['dialog_geometry'] = bytearray(self.saveGeometry())
|
||||
self.plugin.config['dialog_results_view_column_width'] = [self.results_view.columnWidth(i) for i in range(self.model.columnCount())]
|
||||
self.plugin.config['dialog_sort_col'] = self.results_view.model().sort_col
|
||||
self.plugin.config['dialog_sort_order'] = self.results_view.model().sort_order
|
||||
|
||||
def dialog_closed(self, result):
|
||||
self.save_state()
|
||||
|
@ -10,6 +10,7 @@ import re
|
||||
import time
|
||||
import traceback
|
||||
from contextlib import closing
|
||||
from operator import attrgetter
|
||||
from random import shuffle
|
||||
from threading import Thread
|
||||
from Queue import Queue
|
||||
@ -18,13 +19,12 @@ from PyQt4.Qt import (Qt, QAbstractItemModel, QDialog, QTimer, QVariant,
|
||||
QModelIndex, QPixmap, QSize, QCheckBox, QVBoxLayout)
|
||||
|
||||
from calibre import browser
|
||||
from calibre.gui2 import NONE
|
||||
from calibre.gui2 import NONE, JSONConfig
|
||||
from calibre.gui2.progress_indicator import ProgressIndicator
|
||||
from calibre.gui2.store.search_ui import Ui_Dialog
|
||||
from calibre.gui2.store.search_result import SearchResult
|
||||
from calibre.library.caches import _match, CONTAINS_MATCH, EQUALS_MATCH, \
|
||||
REGEXP_MATCH
|
||||
from calibre.utils.config import DynamicConfig
|
||||
from calibre.utils.icu import sort_key
|
||||
from calibre.utils.magick.draw import thumbnail
|
||||
from calibre.utils.search_query_parser import SearchQueryParser
|
||||
@ -48,7 +48,7 @@ class SearchDialog(QDialog, Ui_Dialog):
|
||||
QDialog.__init__(self, *args)
|
||||
self.setupUi(self)
|
||||
|
||||
self.config = DynamicConfig('store_search')
|
||||
self.config = JSONConfig('store/search')
|
||||
|
||||
# We keep a cache of store plugins and reference them by name.
|
||||
self.store_plugins = istores
|
||||
@ -163,8 +163,8 @@ class SearchDialog(QDialog, Ui_Dialog):
|
||||
return query
|
||||
|
||||
def save_state(self):
|
||||
self.config['store_search_geometry'] = self.saveGeometry()
|
||||
self.config['store_search_store_splitter_state'] = self.store_splitter.saveState()
|
||||
self.config['store_search_geometry'] = bytearray(self.saveGeometry())
|
||||
self.config['store_search_store_splitter_state'] = bytearray(self.store_splitter.saveState())
|
||||
self.config['store_search_results_view_column_width'] = [self.results_view.columnWidth(i) for i in range(self.model.columnCount())]
|
||||
|
||||
store_check = {}
|
||||
@ -173,15 +173,15 @@ class SearchDialog(QDialog, Ui_Dialog):
|
||||
self.config['store_search_store_checked'] = store_check
|
||||
|
||||
def restore_state(self):
|
||||
geometry = self.config['store_search_geometry']
|
||||
geometry = self.config.get('store_search_geometry', None)
|
||||
if geometry:
|
||||
self.restoreGeometry(geometry)
|
||||
|
||||
splitter_state = self.config['store_search_store_splitter_state']
|
||||
splitter_state = self.config.get('store_search_store_splitter_state', None)
|
||||
if splitter_state:
|
||||
self.store_splitter.restoreState(splitter_state)
|
||||
|
||||
results_cwidth = self.config['store_search_results_view_column_width']
|
||||
results_cwidth = self.config.get('store_search_results_view_column_width', None)
|
||||
if results_cwidth:
|
||||
for i, x in enumerate(results_cwidth):
|
||||
if i >= self.model.columnCount():
|
||||
@ -190,7 +190,7 @@ class SearchDialog(QDialog, Ui_Dialog):
|
||||
else:
|
||||
self.resize_columns()
|
||||
|
||||
store_check = self.config['store_search_store_checked']
|
||||
store_check = self.config.get('store_search_store_checked', None)
|
||||
if store_check:
|
||||
for n in store_check:
|
||||
if hasattr(self, 'store_check_' + n):
|
||||
@ -463,17 +463,18 @@ class Matches(QAbstractItemModel):
|
||||
self.reset()
|
||||
|
||||
def add_result(self, result, store_plugin):
|
||||
self.layoutAboutToBeChanged.emit()
|
||||
self.all_matches.append(result)
|
||||
self.search_filter.add_search_result(result)
|
||||
if result.cover_url:
|
||||
result.cover_queued = True
|
||||
self.cover_pool.add_task(result, self.filter_results)
|
||||
else:
|
||||
result.cover_queued = False
|
||||
self.details_pool.add_task(result, store_plugin, self.got_result_details)
|
||||
self.filter_results()
|
||||
self.layoutChanged.emit()
|
||||
if result not in self.all_matches:
|
||||
self.layoutAboutToBeChanged.emit()
|
||||
self.all_matches.append(result)
|
||||
self.search_filter.add_search_result(result)
|
||||
if result.cover_url:
|
||||
result.cover_queued = True
|
||||
self.cover_pool.add_task(result, self.filter_results)
|
||||
else:
|
||||
result.cover_queued = False
|
||||
self.details_pool.add_task(result, store_plugin, self.got_result_details)
|
||||
self.filter_results()
|
||||
self.layoutChanged.emit()
|
||||
|
||||
def get_result(self, index):
|
||||
row = index.row()
|
||||
@ -670,9 +671,9 @@ class SearchFilter(SearchQueryParser):
|
||||
locations = all_locs if location == 'all' else [location]
|
||||
q = {
|
||||
'author': lambda x: x.author.lower(),
|
||||
'cover': lambda x: x.cover_url,
|
||||
'drm': lambda x: x.drm,
|
||||
'format': lambda x: x.formats,
|
||||
'cover': attrgetter('cover_url'),
|
||||
'drm': attrgetter('drm'),
|
||||
'format': attrgetter('formats'),
|
||||
'price': lambda x: comparable_price(x.price),
|
||||
'store': lambda x: x.store_name.lower(),
|
||||
'title': lambda x: x.title.lower(),
|
||||
@ -692,7 +693,7 @@ class SearchFilter(SearchQueryParser):
|
||||
continue
|
||||
if query == 'false':
|
||||
if locvalue == 'drm':
|
||||
if accessor(sr) == SearchResult.DRM_UNKNOWN:
|
||||
if accessor(sr) == SearchResult.DRM_UNLOCKED:
|
||||
matches.add(sr)
|
||||
else:
|
||||
if accessor(sr) is None:
|
||||
|
@ -22,3 +22,6 @@ class SearchResult(object):
|
||||
self.detail_item = ''
|
||||
self.drm = None
|
||||
self.formats = ''
|
||||
|
||||
def __eq__(self, other):
|
||||
return self.title == other.title and self.author == other.author and self.store_name == other.store_name
|
||||
|
Loading…
x
Reference in New Issue
Block a user