Merge lp:~tomek3d/calibre/store into lp:calibre

Proposed by Tomasz Długosz
Status: Merged
Merged at revision: 13729
Proposed branch: lp:~tomek3d/calibre/store
Merge into: lp:calibre
Diff against target: 303 lines (+109/-107)
4 files modified
src/calibre/customize/builtins.py (+11/-11)
src/calibre/gui2/store/stores/gandalf_plugin.py (+0/-82)
src/calibre/gui2/store/stores/legimi_plugin.py (+18/-14)
src/calibre/gui2/store/stores/publio_plugin.py (+80/-0)
To merge this branch: bzr merge lp:~tomek3d/calibre/store
Reviewer Review Type Date Requested Status
Kovid Goyal Pending
Review via email: mp+135792@code.launchpad.net

Description of the change

Publio added, Legimi updated, Gandalf removed.

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/calibre/customize/builtins.py'
2--- src/calibre/customize/builtins.py 2012-11-20 10:47:44 +0000
3+++ src/calibre/customize/builtins.py 2012-11-22 22:41:20 +0000
4@@ -1433,15 +1433,6 @@
5 formats = ['EPUB', 'PDF']
6 affiliate = True
7
8-class StoreGandalfStore(StoreBase):
9- name = 'Gandalf'
10- author = u'Tomasz Długosz'
11- description = u'Księgarnia internetowa Gandalf.'
12- actual_plugin = 'calibre.gui2.store.stores.gandalf_plugin:GandalfStore'
13-
14- headquarters = 'PL'
15- formats = ['EPUB', 'PDF']
16-
17 class StoreGoogleBooksStore(StoreBase):
18 name = 'Google Books'
19 description = u'Google Books'
20@@ -1472,7 +1463,7 @@
21 class StoreLegimiStore(StoreBase):
22 name = 'Legimi'
23 author = u'Tomasz Długosz'
24- description = u'Tanie oraz darmowe ebooki, egazety i blogi w formacie EPUB, wprost na Twój e-czytnik, iPhone, iPad, Android i komputer'
25+ description = u'Ebooki w formacie EPUB, MOBI i PDF'
26 actual_plugin = 'calibre.gui2.store.stores.legimi_plugin:LegimiStore'
27
28 headquarters = 'PL'
29@@ -1566,6 +1557,15 @@
30 headquarters = 'US'
31 formats = ['EPUB', 'MOBI', 'PDF']
32
33+class StorePublioStore(StoreBase):
34+ name = 'Publio'
35+ description = u'Publio.pl to księgarnia internetowa, w której mogą Państwo nabyć e-booki i audiobooki.'
36+ actual_plugin = 'calibre.gui2.store.stores.publio_plugin:PublioStore'
37+ author = u'Tomasz Długosz'
38+
39+ headquarters = 'PL'
40+ formats = ['EPUB', 'MOBI', 'PDF']
41+
42 class StoreRW2010Store(StoreBase):
43 name = 'RW2010'
44 description = u'Polski serwis self-publishingowy. Pliki PDF, EPUB i MOBI. Maksymalna cena utworu nie przekracza u nas 10 złotych!'
45@@ -1675,7 +1675,6 @@
46 StoreEscapeMagazineStore,
47 StoreFeedbooksStore,
48 StoreFoylesUKStore,
49- StoreGandalfStore,
50 StoreGoogleBooksStore,
51 StoreGutenbergStore,
52 StoreKoboStore,
53@@ -1689,6 +1688,7 @@
54 StoreOpenBooksStore,
55 StoreOzonRUStore,
56 StorePragmaticBookshelfStore,
57+ StorePublioStore,
58 StoreRW2010Store,
59 StoreSmashwordsStore,
60 StoreVirtualoStore,
61
62=== removed file 'src/calibre/gui2/store/stores/gandalf_plugin.py'
63--- src/calibre/gui2/store/stores/gandalf_plugin.py 2012-01-30 21:43:19 +0000
64+++ src/calibre/gui2/store/stores/gandalf_plugin.py 1970-01-01 00:00:00 +0000
65@@ -1,82 +0,0 @@
66-# -*- coding: utf-8 -*-
67-
68-from __future__ import (unicode_literals, division, absolute_import, print_function)
69-
70-__license__ = 'GPL 3'
71-__copyright__ = '2011-2012, Tomasz Długosz <tomek3d@gmail.com>'
72-__docformat__ = 'restructuredtext en'
73-
74-import re
75-import urllib
76-from contextlib import closing
77-
78-from lxml import html
79-
80-from PyQt4.Qt import QUrl
81-
82-from calibre import browser, url_slash_cleaner
83-from calibre.gui2 import open_url
84-from calibre.gui2.store import StorePlugin
85-from calibre.gui2.store.basic_config import BasicStoreConfig
86-from calibre.gui2.store.search_result import SearchResult
87-from calibre.gui2.store.web_store_dialog import WebStoreDialog
88-
89-class GandalfStore(BasicStoreConfig, StorePlugin):
90-
91- def open(self, parent=None, detail_item=None, external=False):
92- url = 'http://www.gandalf.com.pl/ebooks/'
93-
94- if external or self.config.get('open_external', False):
95- open_url(QUrl(url_slash_cleaner(detail_item if detail_item else url)))
96- else:
97- d = WebStoreDialog(self.gui, url, parent, detail_item)
98- d.setWindowTitle(self.name)
99- d.set_tags(self.config.get('tags', ''))
100- d.exec_()
101-
102- def search(self, query, max_results=10, timeout=60):
103- counter = max_results
104- page = 1
105- url = 'http://www.gandalf.com.pl/we/' + urllib.quote_plus(query.decode('utf-8').encode('iso8859_2')) + '/bdb'
106-
107- br = browser()
108-
109- while counter:
110- with closing(br.open((url + str(page-1) + '/#s') if (page-1) else (url + '/#s'), timeout=timeout)) as f:
111- doc = html.fromstring(f.read())
112- for data in doc.xpath('//div[@class="box"]'):
113- if counter <= 0:
114- break
115-
116- id = ''.join(data.xpath('.//div[@class="info"]/h3/a/@href'))
117- if not id:
118- continue
119-
120- cover_url = ''.join(data.xpath('.//div[@class="info"]/h3/a/@id'))
121- title = ''.join(data.xpath('.//div[@class="info"]/h3/a/@title'))
122- formats = ''.join(data.xpath('.//div[@class="info"]/p[1]/text()'))
123- formats = re.findall(r'\((.*?)\)',formats)[0]
124- author = ''.join(data.xpath('.//div[@class="info"]/h4/text() | .//div[@class="info"]/h4/span/text()'))
125- price = ''.join(data.xpath('.//div[@class="options"]/h3/text()'))
126- price = re.sub('PLN', 'zł', price)
127- price = re.sub('\.', ',', price)
128- drm = data.xpath('boolean(.//div[@class="info" and contains(., "Zabezpieczenie: DRM")])')
129-
130- counter -= 1
131-
132- s = SearchResult()
133- s.cover_url = 'http://imguser.gandalf.com.pl/' + re.sub('p', 'p_', cover_url) + '.jpg'
134- s.title = title.strip()
135- s.author = author.strip()
136- s.price = price
137- s.detail_item = id.strip()
138- if drm:
139- s.drm = SearchResult.DRM_LOCKED
140- else:
141- s.drm = SearchResult.DRM_UNLOCKED
142- s.formats = formats.upper().strip()
143-
144- yield s
145- if not doc.xpath('boolean(//div[@class="wyszukiwanie_podstawowe_header"]//div[@class="box"])'):
146- break
147- page+=1
148
149=== modified file 'src/calibre/gui2/store/stores/legimi_plugin.py'
150--- src/calibre/gui2/store/stores/legimi_plugin.py 2012-08-15 20:09:42 +0000
151+++ src/calibre/gui2/store/stores/legimi_plugin.py 2012-11-22 22:41:20 +0000
152@@ -25,7 +25,7 @@
153
154 def open(self, parent=None, detail_item=None, external=False):
155
156- plain_url = 'http://www.legimi.com/pl/ebooks/?price=any'
157+ plain_url = 'http://www.legimi.com/pl/ebooki/'
158 url = 'https://ssl.afiliant.com/affskrypt,,2f9de2,,11483,,,?u=(' + plain_url + ')'
159 detail_url = None
160
161@@ -41,32 +41,36 @@
162 d.exec_()
163
164 def search(self, query, max_results=10, timeout=60):
165- url = 'http://www.legimi.com/pl/ebooks/?price=any&lang=pl&search=' + urllib.quote_plus(query) + '&sort=relevance'
166+ url = 'http://www.legimi.com/pl/ebooki/?szukaj=' + urllib.quote_plus(query)
167
168 br = browser()
169- drm_pattern = re.compile("(DRM)")
170+ drm_pattern = re.compile("zabezpieczona DRM")
171
172 counter = max_results
173 with closing(br.open(url, timeout=timeout)) as f:
174 doc = html.fromstring(f.read())
175- for data in doc.xpath('//div[@class="list"]/ul/li'):
176+ for data in doc.xpath('//div[@id="listBooks"]/div'):
177 if counter <= 0:
178 break
179
180- id = ''.join(data.xpath('.//div[@class="item_cover_container"]/a[1]/@href'))
181+ id = ''.join(data.xpath('.//a[@class="plainLink"]/@href'))
182 if not id:
183 continue
184
185- cover_url = ''.join(data.xpath('.//div[@class="item_cover_container"]/a/img/@src'))
186- title = ''.join(data.xpath('.//div[@class="item_entries"]/h2/a/text()'))
187- author = ''.join(data.xpath('.//div[@class="item_entries"]/span[1]/a/text()'))
188+ cover_url = ''.join(data.xpath('.//img[1]/@src'))
189+ title = ''.join(data.xpath('.//span[@class="bookListTitle ellipsis"]/text()'))
190+ author = ''.join(data.xpath('.//span[@class="bookListAuthor ellipsis"]/text()'))
191 author = re.sub(',','',author)
192 author = re.sub(';',',',author)
193- price = ''.join(data.xpath('.//span[@class="ebook_price"]/text()'))
194- formats = ''.join(data.xpath('.//div[@class="item_entries"]/span[3]/text()'))
195- formats = re.sub('Format:','',formats)
196- drm = drm_pattern.search(formats)
197- formats = re.sub('\(DRM\)','',formats)
198+ price = ''.join(data.xpath('.//div[@class="bookListPrice"]/span/text()'))
199+ formats = []
200+ with closing(br.open(id.strip(), timeout=timeout/4)) as nf:
201+ idata = html.fromstring(nf.read())
202+ formatlist = idata.xpath('.//div[@id="fullBookFormats"]//span[@class="bookFormat"]/text()')
203+ for x in formatlist:
204+ if x.strip() not in formats:
205+ formats.append(x.strip())
206+ drm = drm_pattern.search(''.join(idata.xpath('.//div[@id="fullBookFormats"]/p/text()')))
207
208 counter -= 1
209
210@@ -76,7 +80,7 @@
211 s.author = author.strip()
212 s.price = price
213 s.detail_item = 'http://www.legimi.com/' + id.strip()
214+ s.formats = ', '.join(formats)
215 s.drm = SearchResult.DRM_LOCKED if drm else SearchResult.DRM_UNLOCKED
216- s.formats = formats.strip()
217
218 yield s
219
220=== added file 'src/calibre/gui2/store/stores/publio_plugin.py'
221--- src/calibre/gui2/store/stores/publio_plugin.py 1970-01-01 00:00:00 +0000
222+++ src/calibre/gui2/store/stores/publio_plugin.py 2012-11-22 22:41:20 +0000
223@@ -0,0 +1,80 @@
224+# -*- coding: utf-8 -*-
225+
226+from __future__ import (unicode_literals, division, absolute_import, print_function)
227+
228+__license__ = 'GPL 3'
229+__copyright__ = '2012, Tomasz Długosz <tomek3d@gmail.com>'
230+__docformat__ = 'restructuredtext en'
231+
232+import re
233+import urllib
234+from contextlib import closing
235+
236+from lxml import html
237+
238+from PyQt4.Qt import QUrl
239+
240+from calibre import browser, url_slash_cleaner
241+from calibre.gui2 import open_url
242+from calibre.gui2.store import StorePlugin
243+from calibre.gui2.store.basic_config import BasicStoreConfig
244+from calibre.gui2.store.search_result import SearchResult
245+from calibre.gui2.store.web_store_dialog import WebStoreDialog
246+
247+class PublioStore(BasicStoreConfig, StorePlugin):
248+
249+ def open(self, parent=None, detail_item=None, external=False):
250+ google_analytics = '?utm_source=tdcalibre&utm_medium=calibre'
251+ url = 'http://www.publio.pl/e-booki.html' + google_analytics
252+
253+ if external or self.config.get('open_external', False):
254+ open_url(QUrl(url_slash_cleaner((detail_item + google_analytics) if detail_item else url)))
255+ else:
256+ d = WebStoreDialog(self.gui, url, parent, detail_item)
257+ d.setWindowTitle(self.name)
258+ d.set_tags(self.config.get('tags', ''))
259+ d.exec_()
260+
261+ def search(self, query, max_results=20, timeout=60):
262+
263+ br = browser()
264+
265+ counter = max_results
266+ page = 1
267+ while counter:
268+ with closing(br.open('http://www.publio.pl/e-booki,strona' + str(page) + '.html?q=' + urllib.quote(query), timeout=timeout)) as f:
269+ doc = html.fromstring(f.read())
270+ for data in doc.xpath('//div[@class="item"]'):
271+ if counter <= 0:
272+ break
273+
274+ id = ''.join(data.xpath('.//div[@class="img"]/a/@href'))
275+ if not id:
276+ continue
277+
278+ cover_url = ''.join(data.xpath('.//div[@class="img"]/a/img/@data-original'))
279+ title = ''.join(data.xpath('.//div[@class="desc"]/h4/a/text()'))
280+ title2 = ''.join(data.xpath('.//div[@class="desc"]/h5/a/text()'))
281+ if title2:
282+ title = title + '. ' + title2
283+ author = ', '.join(data.xpath('./div[@class="desc"]/div[@class="detailShortList"]/div[@class="row"]/a/text()'))
284+ price = ''.join(data.xpath('.//div[@class="priceBoxContener "]/div/ins/text()'))
285+ if not price:
286+ price = ''.join(data.xpath('.//div[@class="priceBoxContener "]/div/text()'))
287+ formats = ', '.join(data.xpath('.//div[@class="formats"]/a/img/@alt'))
288+
289+ counter -= 1
290+
291+ s = SearchResult()
292+ s.cover_url = 'http://www.publio.pl' + cover_url
293+ s.title = title.strip()
294+ s.author = author.strip()
295+ s.price = price.strip()
296+ s.detail_item = 'http://www.publio.pl' + id.strip()
297+ s.drm = SearchResult.DRM_LOCKED if 'DRM' in formats else SearchResult.DRM_UNLOCKED
298+ s.formats = formats.replace(' DRM','').strip()
299+
300+ yield s
301+ if not doc.xpath('boolean(//a[@class="next"])'):
302+ break
303+ page+=1

Subscribers

People subscribed via source and target branches