From 4a615ee09c93a3f89549a7638cc828cd89eaaf88 Mon Sep 17 00:00:00 2001 From: Eli Schwartz Date: Thu, 18 Apr 2019 02:02:48 -0400 Subject: [PATCH 1/5] py3: when shuffling dictionary keys, use an explicit list --- src/calibre/gui2/store/search/search.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/calibre/gui2/store/search/search.py b/src/calibre/gui2/store/search/search.py index 24bde0cf62..2e50445e82 100644 --- a/src/calibre/gui2/store/search/search.py +++ b/src/calibre/gui2/store/search/search.py @@ -207,7 +207,7 @@ class SearchDialog(QDialog, Ui_Dialog): # there is a search. This way plugins closer # to a don't have an unfair advantage over # plugins further from a. - store_names = self.store_checks.keys() + store_names = list(self.store_checks) if not store_names: return # Remove all of our internal filtering logic from the query. From 85378356dbadece340f83ea450325522379da09c Mon Sep 17 00:00:00 2001 From: Eli Schwartz Date: Thu, 18 Apr 2019 02:28:53 -0400 Subject: [PATCH 2/5] py3: cannot decode the result of urlencode() It is already both a str, and reduced to url-friendly ascii. --- src/calibre/gui2/store/stores/amazon_au_plugin.py | 2 +- src/calibre/gui2/store/stores/amazon_ca_plugin.py | 2 +- src/calibre/gui2/store/stores/amazon_de_plugin.py | 2 +- src/calibre/gui2/store/stores/amazon_es_plugin.py | 2 +- src/calibre/gui2/store/stores/amazon_fr_plugin.py | 2 +- src/calibre/gui2/store/stores/amazon_in_plugin.py | 2 +- src/calibre/gui2/store/stores/amazon_it_plugin.py | 2 +- src/calibre/gui2/store/stores/amazon_plugin.py | 2 +- src/calibre/gui2/store/stores/amazon_uk_plugin.py | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/calibre/gui2/store/stores/amazon_au_plugin.py b/src/calibre/gui2/store/stores/amazon_au_plugin.py index ff697eb2cc..61a4387ed4 100644 --- a/src/calibre/gui2/store/stores/amazon_au_plugin.py +++ b/src/calibre/gui2/store/stores/amazon_au_plugin.py @@ -47,7 +47,7 @@ def search_amazon(query, max_results=10, timeout=60, x = x.encode('utf-8') return x uquery = {asbytes(k):asbytes(v) for k, v in uquery.items()} - url = base_url + '?' + urlencode(uquery).decode('ascii') + url = base_url + '?' + urlencode(uquery) br = browser(user_agent=get_user_agent()) counter = max_results diff --git a/src/calibre/gui2/store/stores/amazon_ca_plugin.py b/src/calibre/gui2/store/stores/amazon_ca_plugin.py index 2f06e574cd..6f4dd4794d 100644 --- a/src/calibre/gui2/store/stores/amazon_ca_plugin.py +++ b/src/calibre/gui2/store/stores/amazon_ca_plugin.py @@ -47,7 +47,7 @@ def search_amazon(query, max_results=10, timeout=60, x = x.encode('utf-8') return x uquery = {asbytes(k):asbytes(v) for k, v in uquery.items()} - url = base_url + '?' + urlencode(uquery).decode('ascii') + url = base_url + '?' + urlencode(uquery) br = browser(user_agent=get_user_agent()) counter = max_results diff --git a/src/calibre/gui2/store/stores/amazon_de_plugin.py b/src/calibre/gui2/store/stores/amazon_de_plugin.py index 1b798c3b83..5979e82c8c 100644 --- a/src/calibre/gui2/store/stores/amazon_de_plugin.py +++ b/src/calibre/gui2/store/stores/amazon_de_plugin.py @@ -49,7 +49,7 @@ def search_amazon(query, max_results=10, timeout=60, x = x.encode('utf-8') return x uquery = {asbytes(k):asbytes(v) for k, v in uquery.items()} - url = base_url + '?' + urlencode(uquery).decode('ascii') + url = base_url + '?' + urlencode(uquery) br = browser(user_agent=get_user_agent()) counter = max_results diff --git a/src/calibre/gui2/store/stores/amazon_es_plugin.py b/src/calibre/gui2/store/stores/amazon_es_plugin.py index 5d5ce09808..f95bcc4010 100644 --- a/src/calibre/gui2/store/stores/amazon_es_plugin.py +++ b/src/calibre/gui2/store/stores/amazon_es_plugin.py @@ -49,7 +49,7 @@ def search_amazon(query, max_results=10, timeout=60, x = x.encode('utf-8') return x uquery = {asbytes(k):asbytes(v) for k, v in uquery.items()} - url = base_url + '?' + urlencode(uquery).decode('ascii') + url = base_url + '?' + urlencode(uquery) br = browser(user_agent=get_user_agent()) counter = max_results diff --git a/src/calibre/gui2/store/stores/amazon_fr_plugin.py b/src/calibre/gui2/store/stores/amazon_fr_plugin.py index c1318416f5..3594af9499 100644 --- a/src/calibre/gui2/store/stores/amazon_fr_plugin.py +++ b/src/calibre/gui2/store/stores/amazon_fr_plugin.py @@ -49,7 +49,7 @@ def search_amazon(query, max_results=10, timeout=60, x = x.encode('utf-8') return x uquery = {asbytes(k):asbytes(v) for k, v in uquery.items()} - url = base_url + '?' + urlencode(uquery).decode('ascii') + url = base_url + '?' + urlencode(uquery) br = browser(user_agent=get_user_agent()) counter = max_results diff --git a/src/calibre/gui2/store/stores/amazon_in_plugin.py b/src/calibre/gui2/store/stores/amazon_in_plugin.py index 4c83efc097..c659696fa2 100644 --- a/src/calibre/gui2/store/stores/amazon_in_plugin.py +++ b/src/calibre/gui2/store/stores/amazon_in_plugin.py @@ -47,7 +47,7 @@ def search_amazon(query, max_results=10, timeout=60, x = x.encode('utf-8') return x uquery = {asbytes(k):asbytes(v) for k, v in uquery.items()} - url = base_url + '?' + urlencode(uquery).decode('ascii') + url = base_url + '?' + urlencode(uquery) br = browser(user_agent=get_user_agent()) counter = max_results diff --git a/src/calibre/gui2/store/stores/amazon_it_plugin.py b/src/calibre/gui2/store/stores/amazon_it_plugin.py index 326a74d372..922e9c524c 100644 --- a/src/calibre/gui2/store/stores/amazon_it_plugin.py +++ b/src/calibre/gui2/store/stores/amazon_it_plugin.py @@ -49,7 +49,7 @@ def search_amazon(query, max_results=10, timeout=60, x = x.encode('utf-8') return x uquery = {asbytes(k):asbytes(v) for k, v in uquery.items()} - url = base_url + '?' + urlencode(uquery).decode('ascii') + url = base_url + '?' + urlencode(uquery) br = browser(user_agent=get_user_agent()) counter = max_results diff --git a/src/calibre/gui2/store/stores/amazon_plugin.py b/src/calibre/gui2/store/stores/amazon_plugin.py index 162439f8c9..8e6dfee91b 100644 --- a/src/calibre/gui2/store/stores/amazon_plugin.py +++ b/src/calibre/gui2/store/stores/amazon_plugin.py @@ -47,7 +47,7 @@ def search_amazon(query, max_results=10, timeout=60, x = x.encode('utf-8') return x uquery = {asbytes(k):asbytes(v) for k, v in uquery.items()} - url = base_url + '?' + urlencode(uquery).decode('ascii') + url = base_url + '?' + urlencode(uquery) br = browser(user_agent=get_user_agent()) counter = max_results diff --git a/src/calibre/gui2/store/stores/amazon_uk_plugin.py b/src/calibre/gui2/store/stores/amazon_uk_plugin.py index 38197e270e..fb04a61c84 100644 --- a/src/calibre/gui2/store/stores/amazon_uk_plugin.py +++ b/src/calibre/gui2/store/stores/amazon_uk_plugin.py @@ -47,7 +47,7 @@ def search_amazon(query, max_results=10, timeout=60, x = x.encode('utf-8') return x uquery = {asbytes(k):asbytes(v) for k, v in uquery.items()} - url = base_url + '?' + urlencode(uquery).decode('ascii') + url = base_url + '?' + urlencode(uquery) br = browser(user_agent=get_user_agent()) counter = max_results From 52f915d7070b2e7be69f68d58890d57130e0ede6 Mon Sep 17 00:00:00 2001 From: Eli Schwartz Date: Thu, 18 Apr 2019 02:45:43 -0400 Subject: [PATCH 3/5] py3: allow SearchResult instances to be hashed --- src/calibre/gui2/store/search_result.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/calibre/gui2/store/search_result.py b/src/calibre/gui2/store/search_result.py index 0f870ee770..d1d4b33411 100644 --- a/src/calibre/gui2/store/search_result.py +++ b/src/calibre/gui2/store/search_result.py @@ -33,6 +33,9 @@ class SearchResult(object): def __eq__(self, other): return self.title == other.title and self.author == other.author and self.store_name == other.store_name and self.formats == other.formats + def __hash__(self): + return id(self) + def __str__(self): items = [] for x in 'store_name title author price formats detail_item cover_url'.split(): From 69cf3d345abf27c4dd43be519c0939dfb978f19b Mon Sep 17 00:00:00 2001 From: Eli Schwartz Date: Thu, 18 Apr 2019 02:47:29 -0400 Subject: [PATCH 4/5] py3: fix sort method being called with implicit parameters Passing None as the first argument in order to not use cmp, is not portable. --- src/calibre/gui2/store/search/models.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/calibre/gui2/store/search/models.py b/src/calibre/gui2/store/search/models.py index 7f21d130b6..8a1d0738c0 100644 --- a/src/calibre/gui2/store/search/models.py +++ b/src/calibre/gui2/store/search/models.py @@ -291,9 +291,9 @@ class Matches(QAbstractItemModel): if not self.matches: return descending = order == Qt.DescendingOrder - self.all_matches.sort(None, - lambda x: sort_key(unicode_type(self.data_as_text(x, col))), - descending) + self.all_matches.sort( + key=lambda x: sort_key(unicode_type(self.data_as_text(x, col))), + reverse=descending) self.reorder_matches() if reset: self.beginResetModel(), self.endResetModel() From 1edab4b8182dcd7268d1fc26f8fd4e2f9c38541e Mon Sep 17 00:00:00 2001 From: Eli Schwartz Date: Thu, 18 Apr 2019 02:59:22 -0400 Subject: [PATCH 5/5] py3: store plugins always receive bytes query ... and cannot be further encoded. When interpolating into strings, however, they do need to decode it. --- src/calibre/gui2/store/stores/bn_plugin.py | 2 +- src/calibre/gui2/store/stores/woblink_plugin.py | 2 +- src/calibre/gui2/store/stores/wolnelektury_plugin.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/calibre/gui2/store/stores/bn_plugin.py b/src/calibre/gui2/store/stores/bn_plugin.py index 30164199b9..bc4a3cd4da 100644 --- a/src/calibre/gui2/store/stores/bn_plugin.py +++ b/src/calibre/gui2/store/stores/bn_plugin.py @@ -40,7 +40,7 @@ class BNStore(BasicStoreConfig, StorePlugin): d.exec_() def search(self, query, max_results=10, timeout=60): - url = 'http://www.barnesandnoble.com/s/%s?keyword=%s&store=ebook&view=list' % (query.replace(' ', '-'), quote_plus(query)) + url = 'http://www.barnesandnoble.com/s/%s?keyword=%s&store=ebook&view=list' % (query.decode('utf-8').replace(' ', '-'), quote_plus(query)) br = browser() diff --git a/src/calibre/gui2/store/stores/woblink_plugin.py b/src/calibre/gui2/store/stores/woblink_plugin.py index 258a12a0cf..9258813d95 100644 --- a/src/calibre/gui2/store/stores/woblink_plugin.py +++ b/src/calibre/gui2/store/stores/woblink_plugin.py @@ -36,7 +36,7 @@ def as_base64(data): def search(query, max_results=10, timeout=60): - url = 'http://woblink.com/publication/ajax?mode=none&query=' + quote_plus(query.encode('utf-8')) + url = 'http://woblink.com/publication/ajax?mode=none&query=' + quote_plus(query) if max_results > 10: if max_results > 20: url += '&limit=30' diff --git a/src/calibre/gui2/store/stores/wolnelektury_plugin.py b/src/calibre/gui2/store/stores/wolnelektury_plugin.py index 18358d61b6..317791b194 100644 --- a/src/calibre/gui2/store/stores/wolnelektury_plugin.py +++ b/src/calibre/gui2/store/stores/wolnelektury_plugin.py @@ -44,7 +44,7 @@ class WolneLekturyStore(BasicStoreConfig, StorePlugin): d.exec_() def search(self, query, max_results=10, timeout=60): - url = 'http://wolnelektury.pl/szukaj?q=' + quote_plus(query.encode('utf-8')) + url = 'http://wolnelektury.pl/szukaj?q=' + quote_plus(query) br = browser()