From aee791c4a07f1e1e1fa4b74a3ebdd4c7c66fd9ae Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 2 Mar 2011 09:09:44 -0700 Subject: [PATCH 01/23] Thai Post Daily by Chotechai. Fixes #9239 (Thai Post Daily Newspaper recipe) --- resources/recipes/thai_post_daily.recipe | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 resources/recipes/thai_post_daily.recipe diff --git a/resources/recipes/thai_post_daily.recipe b/resources/recipes/thai_post_daily.recipe new file mode 100644 index 0000000000..9cd943e593 --- /dev/null +++ b/resources/recipes/thai_post_daily.recipe @@ -0,0 +1,18 @@ +from calibre.web.feeds.news import BasicNewsRecipe + +class AdvancedUserRecipe1299054026(BasicNewsRecipe): + title = u'Thai Post Daily' + __author__ = 'Chotechai P.' + language = 'th' + oldest_article = 7 + max_articles_per_feed = 100 + + feeds = [(u'\u0e02\u0e48\u0e32\u0e27\u0e2b\u0e19\u0e49\u0e32\u0e2b\u0e19\u0e36\u0e48\u0e07', u'http://thaipost.net/taxonomy/term/1/all/feed'), (u'\u0e1a\u0e17\u0e1a\u0e23\u0e23\u0e13\u0e32\u0e18\u0e34\u0e01\u0e32\u0e23', u'http://thaipost.net/taxonomy/term/11/all/feed'), (u'\u0e40\u0e1b\u0e25\u0e27 \u0e2a\u0e35\u0e40\u0e07\u0e34\u0e19', u'http://thaipost.net/taxonomy/term/2/all/feed'), (u'\u0e2a\u0e20\u0e32\u0e1b\u0e23\u0e30\u0e0a\u0e32\u0e0a\u0e19', u'http://thaipost.net/taxonomy/term/3/all/feed'), (u'\u0e16\u0e39\u0e01\u0e17\u0e38\u0e01\u0e02\u0e49\u0e2d', u'http://thaipost.net/taxonomy/term/4/all/feed'), (u'\u0e01\u0e32\u0e23\u0e40\u0e21\u0e37\u0e2d\u0e07', u'http://thaipost.net/taxonomy/term/5/all/feed'), (u'\u0e17\u0e48\u0e32\u0e19\u0e02\u0e38\u0e19\u0e19\u0e49\u0e2d\u0e22', u'http://thaipost.net/taxonomy/term/12/all/feed'), (u'\u0e1a\u0e17\u0e04\u0e27\u0e32\u0e21\u0e1e\u0e34\u0e40\u0e28\u0e29', u'http://thaipost.net/taxonomy/term/66/all/feed'), (u'\u0e23\u0e32\u0e22\u0e07\u0e32\u0e19\u0e1e\u0e34\u0e40\u0e28\u0e29', u'http://thaipost.net/taxonomy/term/67/all/feed'), (u'\u0e1a\u0e31\u0e19\u0e17\u0e36\u0e01\u0e2b\u0e19\u0e49\u0e32 4', u'http://thaipost.net/taxonomy/term/13/all/feed'), (u'\u0e40\u0e2a\u0e35\u0e22\u0e1a\u0e0b\u0e36\u0e48\u0e07\u0e2b\u0e19\u0e49\u0e32', u'http://thaipost.net/taxonomy/term/64/all/feed'), (u'\u0e04\u0e31\u0e19\u0e1b\u0e32\u0e01\u0e2d\u0e22\u0e32\u0e01\u0e40\u0e25\u0e48\u0e32', u'http://thaipost.net/taxonomy/term/65/all/feed'), (u'\u0e40\u0e28\u0e23\u0e29\u0e10\u0e01\u0e34\u0e08', u'http://thaipost.net/taxonomy/term/6/all/feed'), (u'\u0e01\u0e23\u0e30\u0e08\u0e01\u0e44\u0e23\u0e49\u0e40\u0e07\u0e32', u'http://thaipost.net/taxonomy/term/14/all/feed'), (u'\u0e01\u0e23\u0e30\u0e08\u0e01\u0e2b\u0e31\u0e01\u0e21\u0e38\u0e21', u'http://thaipost.net/taxonomy/term/71/all/feed'), (u'\u0e04\u0e34\u0e14\u0e40\u0e2b\u0e19\u0e37\u0e2d\u0e01\u0e23\u0e30\u0e41\u0e2a', u'http://thaipost.net/taxonomy/term/69/all/feed'), (u'\u0e23\u0e32\u0e22\u0e07\u0e32\u0e19', u'http://thaipost.net/taxonomy/term/68/all/feed'), (u'\u0e2d\u0e34\u0e42\u0e04\u0e42\u0e1f\u0e01\u0e31\u0e2a', u'http://thaipost.net/taxonomy/term/10/all/feed'), (u'\u0e01\u0e32\u0e23\u0e28\u0e36\u0e01\u0e29\u0e32-\u0e2a\u0e32\u0e18\u0e32\u0e23\u0e13\u0e2a\u0e38\u0e02', u'http://thaipost.net/taxonomy/term/7/all/feed'), (u'\u0e15\u0e48\u0e32\u0e07\u0e1b\u0e23\u0e30\u0e40\u0e17\u0e28', u'http://thaipost.net/taxonomy/term/8/all/feed'), (u'\u0e01\u0e35\u0e2c\u0e32', u'http://thaipost.net/taxonomy/term/9/all/feed')] + + def print_version(self, url): + return url.replace(url, 'http://www.thaipost.net/print/' + url [32:]) + + remove_tags = [] + remove_tags.append(dict(name = 'div', attrs = {'class' : 'print-logo'})) + remove_tags.append(dict(name = 'div', attrs = {'class' : 'print-site_name'})) + remove_tags.append(dict(name = 'div', attrs = {'class' : 'print-breadcrumb'})) From 95da860ee2b668c66e35746d5fe94abdae53adf6 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 2 Mar 2011 09:16:04 -0700 Subject: [PATCH 02/23] Post Today by Chotechai. Fixes #9240 (Post Today newspaper recipe) --- resources/recipes/post_today.recipe | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 resources/recipes/post_today.recipe diff --git a/resources/recipes/post_today.recipe b/resources/recipes/post_today.recipe new file mode 100644 index 0000000000..dc86e68191 --- /dev/null +++ b/resources/recipes/post_today.recipe @@ -0,0 +1,21 @@ +from calibre.web.feeds.news import BasicNewsRecipe + +class AdvancedUserRecipe1299061355(BasicNewsRecipe): + title = u'Post Today' + language = 'th' + __author__ = "Chotechai" + oldest_article = 7 + max_articles_per_feed = 100 + cover_url = 'http://upload.wikimedia.org/wikipedia/th/2/2e/Posttoday_Logo.png' + feeds = [(u'Breaking News', u'http://www.posttoday.com/rss/src/breakingnews.xml'), (u'\u0e02\u0e48\u0e32\u0e27', u'http://www.posttoday.com/rss/src/news.xml'), (u'\u0e27\u0e34\u0e40\u0e04\u0e23\u0e32\u0e30\u0e2b\u0e4c', u'http://www.posttoday.com/rss/src/analyse.xml'), (u'\u0e40\u0e21\u0e32\u0e17\u0e4c\u0e01\u0e31\u0e19\u0e43\u0e2b\u0e49 z', u'http://www.posttoday.com/rss/src/mouth.xml'), (u'\u0e44\u0e17\u0e22\u0e42\u0e0b\u0e44\u0e0b\u0e15\u0e35\u0e49', u'http://www.posttoday.com/rss/src/thaisociety.xml'), (u'\u0e44\u0e25\u0e1f\u0e4c\u0e2a\u0e44\u0e15\u0e25\u0e4c', u'http://www.posttoday.com/rss/src/lifestyle.xml'), (u'\u0e0a\u0e35\u0e49\u0e0a\u0e48\u0e2d\u0e07\u0e23\u0e27\u0e22', u'http://www.posttoday.com/rss/src/moneyguide.xml'), (u'\u0e1a\u0e49\u0e32\u0e19-\u0e04\u0e2d\u0e19\u0e42\u0e14', u'http://www.posttoday.com/rss/src/homecondo.xml'), (u'\u0e22\u0e32\u0e19\u0e22\u0e19\u0e15\u0e4c', u'http://www.posttoday.com/rss/src/motor.xml'), (u'\u0e14\u0e34\u0e08\u0e34\u0e15\u0e2d\u0e25\u0e44\u0e25\u0e1f\u0e4c', u'http://www.posttoday.com/rss/src/digitallife.xml'), (u'\u0e01\u0e35\u0e2c\u0e32', u'http://www.posttoday.com/rss/src/sport.xml'), (u'\u0e23\u0e2d\u0e1a\u0e42\u0e25\u0e01', u'http://www.posttoday.com/rss/src/world.xml'), (u'\u0e01\u0e34\u0e19-\u0e40\u0e17\u0e35\u0e48\u0e22\u0e27', u'http://www.posttoday.com/rss/src/eattravel.xml'), (u'Mind & Soul', u'http://www.posttoday.com/rss/src/mindsoul.xml'), (u'\u0e1a\u0e25\u0e47\u0e2d\u0e01 \u0e1a\u0e01.', u'http://www.posttoday.com/rss/src/blogs.xml')] + keep_only_tags = [] + keep_only_tags.append(dict(name = 'div', attrs = {'class' : +'articleContents'})) + + remove_tags = [] + remove_tags.append(dict(name = 'label')) + remove_tags.append(dict(name = 'span')) + remove_tags.append(dict(name = 'div', attrs = {'class' : +'socialBookmark'})) + remove_tags.append(dict(name = 'div', attrs = {'class' : +'misc'})) From 36fba3beac60f4edfde0a89de5988814d0099513 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 2 Mar 2011 09:35:36 -0700 Subject: [PATCH 03/23] RBC.ru by Chewi --- resources/recipes/rbc_ru.recipe | 49 +++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 resources/recipes/rbc_ru.recipe diff --git a/resources/recipes/rbc_ru.recipe b/resources/recipes/rbc_ru.recipe new file mode 100644 index 0000000000..4c377a334b --- /dev/null +++ b/resources/recipes/rbc_ru.recipe @@ -0,0 +1,49 @@ +from calibre.web.feeds.news import BasicNewsRecipe + +class AdvancedUserRecipe1286819935(BasicNewsRecipe): + title = u'RBC.ru' + __author__ = 'A. Chewi' + oldest_article = 7 + max_articles_per_feed = 100 + no_stylesheets = True + use_embedded_content = False + conversion_options = {'linearize_tables' : True} + remove_attributes = ['style'] + language = 'ru' + timefmt = ' [%a, %d %b, %Y]' + + keep_only_tags = [dict(name='h2', attrs={}), + dict(name='div', attrs={'class': 'box _ga1_on_'}), + dict(name='h1', attrs={'class': 'news_section'}), + dict(name='div', attrs={'class': 'news_body dotted_border_bottom'}), + dict(name='table', attrs={'class': 'newsBody'}), + dict(name='h2', attrs={'class': 'black'})] + + feeds = [(u'Главные новости', u'http://static.feed.rbc.ru/rbc/internal/rss.rbc.ru/rbc.ru/mainnews.rss'), + (u'Политика', u'http://static.feed.rbc.ru/rbc/internal/rss.rbc.ru/rbc.ru/politics.rss'), + (u'Экономика', u'http://static.feed.rbc.ru/rbc/internal/rss.rbc.ru/rbc.ru/economics.rss'), + (u'Общество', u'http://static.feed.rbc.ru/rbc/internal/rss.rbc.ru/rbc.ru/society.rss'), + (u'Происшествия', u'http://static.feed.rbc.ru/rbc/internal/rss.rbc.ru/rbc.ru/incidents.rss'), + (u'Финансовые новости Quote.rbc.ru', u'http://static.feed.rbc.ru/rbc/internal/rss.rbc.ru/quote.ru/mainnews.rss')] + + + remove_tags = [dict(name='div', attrs={'class': "video-frame"}), + dict(name='div', attrs={'class': "photo-container videoContainer videoSWFLinks videoPreviewSlideContainer notes"}), + dict(name='div', attrs={'class': "notes"}), + dict(name='div', attrs={'class': "publinks"}), + dict(name='a', attrs={'class': "print"}), + dict(name='div', attrs={'class': "photo-report_new notes newslider"}), + dict(name='div', attrs={'class': "videoContainer"}), + dict(name='div', attrs={'class': "videoPreviewSlideContainer"}), + dict(name='a', attrs={'class': "videoPreviewContainer"}), + dict(name='a', attrs={'class': "red"}),] + + def preprocess_html(self, soup): + for alink in soup.findAll('a'): + if alink.string is not None: + tstr = alink.string + alink.replaceWith(tstr) + return soup + + def print_version(self, url): + return url + '?print=true' From 0a05ba617a58b17369d534f5ecb79e0b782e79f9 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 2 Mar 2011 10:51:58 -0700 Subject: [PATCH 04/23] Fix bug that caused preferences->behavior to not show the output format set by the welcome wizard, and instead default to showing epub --- src/calibre/gui2/wizard/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/calibre/gui2/wizard/__init__.py b/src/calibre/gui2/wizard/__init__.py index 5f9f1828fa..c629b10b5d 100644 --- a/src/calibre/gui2/wizard/__init__.py +++ b/src/calibre/gui2/wizard/__init__.py @@ -51,7 +51,7 @@ class Device(object): @classmethod def set_output_format(cls): if cls.output_format: - prefs.set('output_format', cls.output_format) + prefs.set('output_format', cls.output_format.lower()) @classmethod def commit(cls): From a4fe0095dfc50ab7c60ef3bba602b08eeeb56f2b Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 2 Mar 2011 10:57:58 -0700 Subject: [PATCH 05/23] Update Credit Slips --- resources/images/news/credit_slips.png | Bin 0 -> 4847 bytes resources/recipes/credit_slips.recipe | 47 +++++++++++++++---------- 2 files changed, 28 insertions(+), 19 deletions(-) create mode 100644 resources/images/news/credit_slips.png diff --git a/resources/images/news/credit_slips.png b/resources/images/news/credit_slips.png new file mode 100644 index 0000000000000000000000000000000000000000..50ac1dc02ec55eff5c2be056e01f15ce70014ad0 GIT binary patch literal 4847 zcmY+Ic{r3`*vFqFNw)lkCP_n+pBRj3(%6@bOd(UoUiLMzP1ed9nL} zdU&}Y$RWNi2whWCWemjkU&Dv^uPC45!(vaLQaP#Ocv=;WMk|Ag1r-zwZs*G9w)fCu z2s%I|=Vh?Et_CCYs(uNy$h>h*{@mJ9^KWb9?al*YRs+t1R72FRjD?LGVWt1us8gZG;b7w z7m7gjz+-nohEycsA{EIi73)Bw{nAkC!9Wp(oY9uS9G+5BSqL&CkzltGyt={=B&{$4)hcbWk z?19e3kfkZ(Y>kkF41j2yN)G2r_=3|&@HNcj3ON){1HB`f+tc|&j@qliQ%$$DEY;-3`3-|l^FM~WF&!l=iM%d*H|m( z>?ohqXLl?=!ye8f)g*$F=vS^WlI%7)A!@rK|w)wc6Kr;4sf2E@_3?bd%BT~c!G?`KBO%a zp-r~Vmz5ET&(4-4k%<2K(#c*br8G~)w7VUSf^oYUl|ov7zHy3jZq4Myi78lP!&bfz z)VPfX4tcMB4d`VEY5)Cv=|VHGE4y23lehOD6p7cbg6?v*!|eSe4)XJag@)o1qlNt? z`uqFo*M=LWbHcZ3`>)J>|Na2!;p_YJW#sOHf`b0bL0LVM(!6@Gj$n-u@TSjb%lr^s zdu<}chJJ0H!vQAV@yrcAg+YnhhHSE_$OC$Z^y(3lyYBD0?}G1&w`ye8ZQSj3=SdUQ zt>~XP*`0NCb5pOk#rX!G{cXtlIEcB1XQ;OHG64duYu_U^H zTIB<^eVXdE4hDn}PO!%7N^!D@w36+{b3Z z$qFTA_Vmu4imYEWn%Mb+n@N_!DcuuO?=tCL1LKRqp`oF5-a{+DfGaM(KHS{ge5K+v zoPTyXG_401nTDhg^m1X9+!)akwwolxvb zX!BOe1+9UG>sQa7?d&`n-sHh7d?;@*a=rhuyhZu*p?Sr$(!#>m&KMSpF{7(dB9_a<#irEr|6E6N3Z zy+-eL{^X85e*AcCZLNZW!hDiu-L1{_+N=F78$TL*wYUFPyYy5KcwxoMN=vW0yT2HV zJ=|AjxBZ)Wq4n1rdG)~WUmAlJwl+7^)zygJB&kUVLOOW-ZIja7Q0_Nd^*bGX z5DlHvyQGoC#&!CEFv@?1iA`k7#lY}V1x|2-BBq~299No2kyUDfNxNf}zDkd%zN*Nf zg@vQS_>zW(!t(OSX*}`4*B^jHF;Hi`W97fBKB zX>1%7d0j1QbYX$R(e-qq4;_k4*Sguj7y}Wgl;w&!M1+Cm;NZX4Ze+!&H#RiH#>UFX z$atyPczA?l|D&%f2Xm%Kdr%|=Vxpcn;LX>Xx~4lUQAAlCyg6RCp6fi(jI@Ww=PQx> zn1R+I!U$A;#>CRv*qB4>s8UZg%kz4@t?cP!oBp|FBtfh!QkH@wSeKb+zH`NjTcz%S zxTD*Ed+8v+wyK(Z!)c{-KV@bI2UBT9(PNaVcIsDl(BBoZatPTl~r@l{L34cDKVF z%LQHRCaYwoxZFmb5REdE(^Ni?VBnN*>0AG`puh#&;apSii=%csd#rD>6(m|eTa4kd zO^O2QA0v4A84n<hZIf6QkPfLFArZD(*fJ_*+=7%=|nP%Rr-g#1jl2DBo(;hVgY* zd(nrE2=0wRi^Rt;#=us}!ob8BWA;`ml1XQ!lk<~wbh)93o;L!%61yQ}3V~NjSJ>c5 zRdsbWaI#5%fJ0B3?73pt{e4q7!Lc)s0rLCjG|4j`zJ1F@@OE(}Bqa$63K~2i@-w~% zs`pgG@B}K1@3vzVJdr&+sju`&Q)eQNrb9FX6I~8HlV^%a*S~i=u?!6G?Af#Y{8#gV z-~d4EuNkmaOk;AeneWU?NfrH1nqq|W8|edHCPhqV3~&=`{DZ>fr@S$1&oBj%wZd8ypn03SvA6bT_Borbk9b>L5(L{`oNAjumhI zSbQ4pB^Wp0T4P-%d&Ru8wyv(Otjv3)$>!=+w{N%uKljGPZAO_^4xKABD({=S2S@zf z`qyi{U_65Aig$TO9N^KboK>UHbQ z2D@ZxVbQWInrWCY=n7 zKiQDG(=V-uL?Rt0Q1fN0EK!n4S8J_Py7j3OBr;`J6@m&w80t`8^v~U#uiXyaT<%Xg zqAnJHZ>j0gJO7aKmy_+z(wTSMKArHpfzlMG>^;^!_OgBL)@b+s-9=%|mxnbwFWAj! zF*k0m)-SYZ2aJEd;1;H#>9)};ux=8@6MAc_o89_o{G`i67njNMU`IWMee}VNzmd9S ziMf`!-=xbJ$N9xLFe);BBt|cQPnyiLT^hqd)=G2TV&R z8)C)rJQ@JrDcwL~7|A3by-;v5&$Me{bz^fYFE4LvYpcesS5hAt?u49NFK&b${SeFHY;8bc+aSaqNug4e{ib+w=q(2ap z!^6V>2zKF{%RpZR{P{Ts0GOo_^6T%~(&pwSgTc5`(a&DAZ3Cuqsto;WSZD0601OzNSv#J52OPT+!zO-c0 z^sC$Z!&ZMhbg6G?8R5ttz!PD3tO<>e*}_wrOvUd2pzUEzx* zpWEBpySlo7HU`%(Uo7Pwf<>I^c2LO#^I&qwjlow$aTQQ?V8g^%vZKoQ9E7XJHf zv#UN~%UGUwDTV!WQZZGQZx>c`)UJE3{ul-tY7<~pYx6e~@SRp#+QVLa%JhhJ0C6lN zq@KxnKHz0u%5tni#J`>N*XRY^W|siDzt{A(sDAJpZ;v;Xjd6nO3RCiDuwKB9NTi2+ zQaq6Pgu?IX^NKJ%=X>rM1|BoMIGGFCUk3*p92l{zQVaU?=U6QEg{@-tbXZuJkOZz0 zSdjNno%cYs3m^cXz7~1rekc0?cbj9?gS0dYb8{}pNQU{F!z_~tKnQ;e8JYK&O1E(7 z03xNof6h`tTw7Fi*Fijy2%IK4mkSEcKC28E?tUc#J9LdcN@f}_P50V?ZOb@yRmFSo zxgYyAsnmQpY@xZVtPJSPYLt+Gz;!bD`w+c%ZaFa_0i54BbSEUc*AF1hUsb|B-N>Mn zMXP>=Ho9~vh3KQxvYYkwxTRr4a=LCS7zwWfj2Olz znPm+P4J9QWzz%y-6^1Gu82go)DuLz&&TEYl16ZoEv`l^Ia;WM^gdC;f<>W4ib*U&d z?crsb>K?A*Pq5ANPSL2kHhZ04@r5u{PlIhakZi2apTXAHpv00o1OEP5)C^l`S{(rk zS{(t&QKE$ECnhr*e$~-Yk3<5Bz1I4axWF6kA|@xW;a=!&Jds=16c@>U!5Dj_>=euL zG!W3#rFPVJ9k=XglZf#heD0AVV_ZEnj|I}kBd7NuFERd(Zh%=^x?FT0E{Y#Zn%OA&$mHEcNd9|DCWK4QH`d)sqk(|Or2tUL0Uxi;y zJNPWj1HMA$67A}EDRqpp(%~j`=e~Kl?b_Ruy&52W$W-yRZVp`r!|X(Pk59-f6AM`w zpfygy1Suk{*EoE|!Xl_gf&RR%PVq`pa0f+nCmXp5lEkHVr$Oq8(39qUWslC4e3}Z&|hme09>_HBm}3ILMHZ@ZroNo`{ZLWlVh2B+|O2+n?RLN z2?OR~a7JE)8xlsIh?jnV^ktpgE5SfdJQhBIkP^XH;k5McI>1X=*5>9aPOt9)8&JG* zqnAb!qSNUWw)NFzW%DaTJ~=1d-UD;@RyoWk*6GJ)vqAE_!{qKe8aeM=K^P-Yf!VTH zq;E8p23%;HqK~4n8L@`)Qu-qPpOx|AnwhU2eE;r?crC(j{Kb39gOyUz+EV2*7Ipmm zpyYc0UdgcURVyniqVncnLB?imY#iDwIb2Djxz^OvXm7yLKuF^2ef)<4qYC{fTu^bx zS3TUF(xw2vjOeL!i)(urvJ`3P&+=XF2q@wev`Z(Rg>4S~_3Uuw4;%m9R?QdV=|z2; z8|$@6wH2Or8#4jhYe)BI_@tYWcu0oINF8r1!FJFddeS9dxmB`XudDjm&^+K=w%T>M z4F0Wkt2U*+?Oi61hfqi4Wlh2Np5r^;dz>A}E^1ExE}(%hXk}#u^hpIY#!MNlcIuSc zDOCmZX*D#Og-9&?e;vGioIPAa{%;4gsv7pR+9}X~r-Na@V@c5Az|IJszAkQRPCi~f z{sF!YPGA(&by5y^i1^=!0S?~2ULM!n6kHvg$UgoMCK!WK4p!c&g!RJb;9ZD-H_Posted by ' + article.author + '

') From 5611a96148e1fdf959b665ddd60059c33698a1c9 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 2 Mar 2011 11:05:13 -0700 Subject: [PATCH 06/23] ... --- src/calibre/gui2/preferences/__init__.py | 7 +++++-- src/calibre/gui2/preferences/behavior.py | 8 ++++++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/calibre/gui2/preferences/__init__.py b/src/calibre/gui2/preferences/__init__.py index 7267716ea8..54eb2f713c 100644 --- a/src/calibre/gui2/preferences/__init__.py +++ b/src/calibre/gui2/preferences/__init__.py @@ -8,7 +8,7 @@ __docformat__ = 'restructuredtext en' import textwrap from PyQt4.Qt import QWidget, pyqtSignal, QCheckBox, QAbstractSpinBox, \ - QLineEdit, QComboBox, QVariant + QLineEdit, QComboBox, QVariant, Qt from calibre.customize.ui import preferences_plugins from calibre.utils.config import ConfigProxy @@ -82,6 +82,8 @@ class ConfigWidgetInterface(object): class Setting(object): + CHOICES_SEARCH_FLAGS = Qt.MatchExactly | Qt.MatchCaseSensitive + def __init__(self, name, config_obj, widget, gui_name=None, empty_string_is_None=True, choices=None, restart_required=False): self.name, self.gui_name = name, gui_name @@ -168,7 +170,8 @@ class Setting(object): elif self.datatype == 'string': self.gui_obj.setText(val if val else '') elif self.datatype == 'choice': - idx = self.gui_obj.findData(QVariant(val)) + idx = self.gui_obj.findData(QVariant(val), role=Qt.UserRole, + flags=self.CHOICES_SEARCH_FLAGS) if idx == -1: idx = 0 self.gui_obj.setCurrentIndex(idx) diff --git a/src/calibre/gui2/preferences/behavior.py b/src/calibre/gui2/preferences/behavior.py index aeee6e5064..45a63ce529 100644 --- a/src/calibre/gui2/preferences/behavior.py +++ b/src/calibre/gui2/preferences/behavior.py @@ -9,7 +9,7 @@ import re from PyQt4.Qt import Qt, QVariant, QListWidgetItem -from calibre.gui2.preferences import ConfigWidgetBase, test_widget +from calibre.gui2.preferences import ConfigWidgetBase, test_widget, Setting from calibre.gui2.preferences.behavior_ui import Ui_Form from calibre.gui2 import config, info_dialog, dynamic from calibre.utils.config import prefs @@ -20,6 +20,10 @@ from calibre.ebooks.oeb.iterator import is_supported from calibre.constants import iswindows from calibre.utils.icu import sort_key +class OutputFormatSetting(Setting): + + CHOICES_SEARCH_FLAGS = Qt.MatchFixedString + class ConfigWidget(ConfigWidgetBase, Ui_Form): def genesis(self, gui): @@ -43,7 +47,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): output_formats = list(sorted(available_output_formats())) output_formats.remove('oeb') choices = [(x.upper(), x) for x in output_formats] - r('output_format', prefs, choices=choices) + r('output_format', prefs, choices=choices, setting=OutputFormatSetting) restrictions = sorted(saved_searches().names(), key=sort_key) choices = [('', '')] + [(x, x) for x in restrictions] From f0ef93ead559804814029317ee6a135c314e8c1f Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 2 Mar 2011 12:16:19 -0700 Subject: [PATCH 07/23] ... --- src/calibre/gui2/dialogs/metadata_bulk.ui | 2 +- src/calibre/gui2/dialogs/metadata_single.ui | 2 +- src/calibre/gui2/metadata/basic_widgets.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/calibre/gui2/dialogs/metadata_bulk.ui b/src/calibre/gui2/dialogs/metadata_bulk.ui index ae3445998b..1654ff8261 100644 --- a/src/calibre/gui2/dialogs/metadata_bulk.ui +++ b/src/calibre/gui2/dialogs/metadata_bulk.ui @@ -341,7 +341,7 @@ from the value in the box 1 - 990000 + 99000000 1 diff --git a/src/calibre/gui2/dialogs/metadata_single.ui b/src/calibre/gui2/dialogs/metadata_single.ui index 5bcf268aaa..ced5030f94 100644 --- a/src/calibre/gui2/dialogs/metadata_single.ui +++ b/src/calibre/gui2/dialogs/metadata_single.ui @@ -419,7 +419,7 @@ If the box is colored green, then text matches the individual author's sort stri Book - 9999.989999999999782 + 99999999.989999994635582 diff --git a/src/calibre/gui2/metadata/basic_widgets.py b/src/calibre/gui2/metadata/basic_widgets.py index a135176daf..d5a8de7b67 100644 --- a/src/calibre/gui2/metadata/basic_widgets.py +++ b/src/calibre/gui2/metadata/basic_widgets.py @@ -351,7 +351,7 @@ class SeriesIndexEdit(QDoubleSpinBox): QDoubleSpinBox.__init__(self, parent) self.dialog = parent self.db = self.original_series_name = None - self.setMaximum(1000000) + self.setMaximum(10000000) self.series_edit = series_edit series_edit.currentIndexChanged.connect(self.enable) series_edit.editTextChanged.connect(self.enable) From 46bcddc10f87bd4a688f1538f3981079d477cb5d Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 2 Mar 2011 12:47:36 -0700 Subject: [PATCH 08/23] Fix regression that caused memory leak in Tag Browser. This would show up as the memory usage of calibre increasing when switching libraries. Fixes #9246 (Memory allocation while changing library) --- src/calibre/gui2/actions/choose_library.py | 1 + src/calibre/gui2/tag_view.py | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/src/calibre/gui2/actions/choose_library.py b/src/calibre/gui2/actions/choose_library.py index f3a7f1742d..6f4ca624cb 100644 --- a/src/calibre/gui2/actions/choose_library.py +++ b/src/calibre/gui2/actions/choose_library.py @@ -355,6 +355,7 @@ class ChooseLibraryAction(InterfaceAction): print print 'before:', self.before_mem print 'after:', memory()/1024**2 + print self.dbref = self.before_mem = None diff --git a/src/calibre/gui2/tag_view.py b/src/calibre/gui2/tag_view.py index b310ce55fb..d03a4f4cca 100644 --- a/src/calibre/gui2/tag_view.py +++ b/src/calibre/gui2/tag_view.py @@ -572,6 +572,13 @@ class TagTreeItem(object): # {{{ else: self.tooltip = '' + def break_cycles(self): + for x in self.children: + if hasattr(x, 'break_cycles'): + x.break_cycles() + self.parent = self.icon_state_map = self.bold_font = self.tag = \ + self.icon = self.children = None + def __str__(self): if self.type == self.ROOT: return 'ROOT' @@ -780,6 +787,7 @@ class TagsModel(QAbstractItemModel): # {{{ self.refresh(data=data) def break_cycles(self): + self.root_item.break_cycles() self.db = self.root_item = None def mimeTypes(self): From 18f048fdb22ea60334d78f88d72c0338f05849c6 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 2 Mar 2011 13:02:33 -0700 Subject: [PATCH 09/23] ... --- src/calibre/devices/misc.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/calibre/devices/misc.py b/src/calibre/devices/misc.py index 8cf0fb5a06..07b381d11a 100644 --- a/src/calibre/devices/misc.py +++ b/src/calibre/devices/misc.py @@ -272,6 +272,7 @@ class NEXTBOOK(USBMS): VENDOR_NAME = 'NEXT2' WINDOWS_MAIN_MEM = WINDOWS_CARD_A_MEM = '1.0.14' SUPPORTS_SUB_DIRS = True + THUMBNAIL_HEIGHT = 120 ''' def upload_cover(self, path, filename, metadata, filepath): From 3ade7e7e33cc2c1ed98cd3077509a4c021ad768d Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 2 Mar 2011 13:34:31 -0700 Subject: [PATCH 10/23] Add code to measure memory usage on windows --- src/calibre/utils/mem.py | 112 ++++++++++++++++++++++++++------------- 1 file changed, 75 insertions(+), 37 deletions(-) diff --git a/src/calibre/utils/mem.py b/src/calibre/utils/mem.py index 1f9bff8d63..930870abd1 100644 --- a/src/calibre/utils/mem.py +++ b/src/calibre/utils/mem.py @@ -5,53 +5,91 @@ __license__ = 'GPL v3' __copyright__ = '2010, Kovid Goyal ' __docformat__ = 'restructuredtext en' -import gc +import gc, os -## {{{ http://code.activestate.com/recipes/286222/ (r1) -import os +from calibre.constants import iswindows, islinux -_proc_status = '/proc/%d/status' % os.getpid() +if islinux: + ## {{{ http://code.activestate.com/recipes/286222/ (r1) -_scale = {'kB': 1024.0, 'mB': 1024.0*1024.0, - 'KB': 1024.0, 'MB': 1024.0*1024.0} + _proc_status = '/proc/%d/status' % os.getpid() -def _VmB(VmKey): - '''Private. - ''' - global _proc_status, _scale - # get pseudo file /proc//status - try: - t = open(_proc_status) - v = t.read() - t.close() - except: - return 0.0 # non-Linux? - # get VmKey line e.g. 'VmRSS: 9999 kB\n ...' - i = v.index(VmKey) - v = v[i:].split(None, 3) # whitespace - if len(v) < 3: - return 0.0 # invalid format? - # convert Vm value to bytes - return float(v[1]) * _scale[v[2]] + _scale = {'kB': 1024.0, 'mB': 1024.0*1024.0, + 'KB': 1024.0, 'MB': 1024.0*1024.0} + + def _VmB(VmKey): + '''Private. + ''' + global _proc_status, _scale + # get pseudo file /proc//status + try: + t = open(_proc_status) + v = t.read() + t.close() + except: + return 0.0 # non-Linux? + # get VmKey line e.g. 'VmRSS: 9999 kB\n ...' + i = v.index(VmKey) + v = v[i:].split(None, 3) # whitespace + if len(v) < 3: + return 0.0 # invalid format? + # convert Vm value to bytes + return float(v[1]) * _scale[v[2]] -def memory(since=0.0): - '''Return memory usage in bytes. - ''' - return _VmB('VmSize:') - since + def linux_memory(since=0.0): + '''Return memory usage in bytes. + ''' + return _VmB('VmSize:') - since -def resident(since=0.0): - '''Return resident memory usage in bytes. - ''' - return _VmB('VmRSS:') - since + def resident(since=0.0): + '''Return resident memory usage in bytes. + ''' + return _VmB('VmRSS:') - since -def stacksize(since=0.0): - '''Return stack size in bytes. - ''' - return _VmB('VmStk:') - since -## end of http://code.activestate.com/recipes/286222/ }}} + def stacksize(since=0.0): + '''Return stack size in bytes. + ''' + return _VmB('VmStk:') - since + ## end of http://code.activestate.com/recipes/286222/ }}} + memory = linux_memory +elif iswindows: + import win32process + import win32con + import win32api + + # See http://msdn.microsoft.com/en-us/library/ms684877.aspx + # for details on the info returned by get_meminfo + + def get_handle(pid): + return win32api.OpenProcess(win32con.PROCESS_QUERY_INFORMATION, 0, + pid) + + def listprocesses(self): + for process in win32process.EnumProcesses(): + try: + han = get_handle(process) + procmeminfo = meminfo(han) + procmemusage = procmeminfo["WorkingSetSize"] + yield process, procmemusage + except: + pass + + def get_meminfo(pid): + han = win32api.OpenProcess(win32con.PROCESS_QUERY_INFORMATION, 0, + pid) + return meminfo(han) + + def meminfo(handle): + return win32process.GetProcessMemoryInfo(handle) + + def win_memory(since=0.0): + info = meminfo(get_handle(os.getpid())) + return info['WorkingSetSize'] - since + + memory = win_memory def gc_histogram(): From f23642869624c7a748333cac742f46b8c7bc1975 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 2 Mar 2011 13:35:37 -0700 Subject: [PATCH 11/23] ... --- src/calibre/utils/mem.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/calibre/utils/mem.py b/src/calibre/utils/mem.py index 930870abd1..c68badc709 100644 --- a/src/calibre/utils/mem.py +++ b/src/calibre/utils/mem.py @@ -5,6 +5,14 @@ __license__ = 'GPL v3' __copyright__ = '2010, Kovid Goyal ' __docformat__ = 'restructuredtext en' +''' +Measure memory usage of the current process. + +The key function is memory() which returns the current memory usage in bytes. +You can pass a number to memory and it will be subtracted from the returned +value. +''' + import gc, os from calibre.constants import iswindows, islinux From 29ba47485dd17a821b587ea2bba1a1982189355a Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 2 Mar 2011 13:49:35 -0700 Subject: [PATCH 12/23] ... --- resources/recipes/buffalo_news.recipe | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/resources/recipes/buffalo_news.recipe b/resources/recipes/buffalo_news.recipe index 92c96757ae..51985a3c51 100644 --- a/resources/recipes/buffalo_news.recipe +++ b/resources/recipes/buffalo_news.recipe @@ -1,8 +1,8 @@ __license__ = 'GPL v3' __author__ = 'Todd Chapman' __copyright__ = 'Todd Chapman' -__version__ = 'v0.1' -__date__ = '26 February 2011' +__version__ = 'v0.2' +__date__ = '2 March 2011' ''' http://www.buffalonews.com/RSS/ @@ -12,12 +12,16 @@ from calibre.web.feeds.news import BasicNewsRecipe class AdvancedUserRecipe1298680852(BasicNewsRecipe): title = u'Buffalo News' - __author__ = 'ChappyOnIce' - language = 'en' oldest_article = 2 + language = 'en' + __author__ = 'ChappyOnIce' max_articles_per_feed = 20 encoding = 'utf-8' + masthead_url = 'http://www.buffalonews.com/buffalonews/skins/buffalonews/images/masthead/the_buffalo_news_logo.png' remove_javascript = True + extra_css = 'body {text-align: justify;}\n \ + p {text-indent: 20px;}' + keep_only_tags = [ dict(name='div', attrs={'class':['main-content-left']}) ] @@ -28,9 +32,7 @@ class AdvancedUserRecipe1298680852(BasicNewsRecipe): ] remove_tags_after = dict(name='div', attrs={'class':['body storyContent']}) - conversion_options = { - 'base_font_size' : 14, - } + feeds = [(u'City of Buffalo', u'http://www.buffalonews.com/city/communities/buffalo/?widget=rssfeed&view=feed&contentId=77944'), (u'Southern Erie County', u'http://www.buffalonews.com/city/communities/southern-erie/?widget=rssfeed&view=feed&contentId=77944'), (u'Eastern Erie County', u'http://www.buffalonews.com/city/communities/eastern-erie/?widget=rssfeed&view=feed&contentId=77944'), From 25ae86e2cf6405b2ceb66c36e893b26369a8dd7f Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 2 Mar 2011 14:23:17 -0700 Subject: [PATCH 13/23] Add a metadata_last_modified attribute to the Metadata object returned by get_metadata --- src/calibre/gui2/tag_view.py | 4 +++- src/calibre/library/database2.py | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/calibre/gui2/tag_view.py b/src/calibre/gui2/tag_view.py index bd7f6fbe70..92ed3bca67 100644 --- a/src/calibre/gui2/tag_view.py +++ b/src/calibre/gui2/tag_view.py @@ -574,8 +574,10 @@ class TagTreeItem(object): # {{{ def break_cycles(self): for x in self.children: - if hasattr(x, 'break_cycles'): + try: x.break_cycles() + except: + pass self.parent = self.icon_state_map = self.bold_font = self.tag = \ self.icon = self.children = None diff --git a/src/calibre/library/database2.py b/src/calibre/library/database2.py index ee7dcbe81a..bb46411fc9 100644 --- a/src/calibre/library/database2.py +++ b/src/calibre/library/database2.py @@ -833,6 +833,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns): mi.pubdate = row[fm['pubdate']] mi.uuid = row[fm['uuid']] mi.title_sort = row[fm['sort']] + mi.metadata_last_modified = row[fm['last_modified']] formats = row[fm['formats']] if not formats: formats = None From c44ad363650ee409536201924f8a4b1c4f59c06c Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 2 Mar 2011 15:30:42 -0700 Subject: [PATCH 14/23] Add an entry to the add books drop down menu to easily add formats to an existing book record --- src/calibre/gui2/actions/add.py | 75 +++++++++++++++++++++++++-------- src/calibre/manual/gui.rst | 2 + 2 files changed, 60 insertions(+), 17 deletions(-) diff --git a/src/calibre/gui2/actions/add.py b/src/calibre/gui2/actions/add.py index f99e48eb2b..0040acea28 100644 --- a/src/calibre/gui2/actions/add.py +++ b/src/calibre/gui2/actions/add.py @@ -20,9 +20,26 @@ from calibre.ebooks import BOOK_EXTENSIONS from calibre.utils.filenames import ascii_filename from calibre.constants import preferred_encoding, filesystem_encoding from calibre.gui2.actions import InterfaceAction -from calibre.gui2 import config +from calibre.gui2 import config, question_dialog from calibre.ebooks.metadata import MetaInformation +def get_filters(): + return [ + (_('Books'), BOOK_EXTENSIONS), + (_('EPUB Books'), ['epub']), + (_('LRF Books'), ['lrf']), + (_('HTML Books'), ['htm', 'html', 'xhtm', 'xhtml']), + (_('LIT Books'), ['lit']), + (_('MOBI Books'), ['mobi', 'prc', 'azw']), + (_('Topaz books'), ['tpz','azw1']), + (_('Text books'), ['txt', 'rtf']), + (_('PDF Books'), ['pdf']), + (_('SNB Books'), ['snb']), + (_('Comics'), ['cbz', 'cbr', 'cbc']), + (_('Archives'), ['zip', 'rar']), + ] + + class AddAction(InterfaceAction): name = 'Add Books' @@ -47,6 +64,10 @@ class AddAction(InterfaceAction): self.add_menu.addAction(_('Add Empty book. (Book entry with no ' 'formats)'), self.add_empty, _('Shift+Ctrl+E')) self.add_menu.addAction(_('Add from ISBN'), self.add_from_isbn) + self.add_menu.addSeparator() + self.add_menu.addAction(_('Add files to selected book records'), + self.add_formats, _('Shift+A')) + self.qaction.setMenu(self.add_menu) self.qaction.triggered.connect(self.add_books) @@ -55,6 +76,39 @@ class AddAction(InterfaceAction): for action in list(self.add_menu.actions())[1:]: action.setEnabled(enabled) + def add_formats(self, *args): + if self.gui.stack.currentIndex() != 0: + return + view = self.gui.library_view + rows = view.selectionModel().selectedRows() + if not rows: + return + ids = [view.model().id(r) for r in rows] + + if len(ids) > 1 and not question_dialog(self.gui, + _('Are you sure'), + _('Are you sure you want to add the same' + ' files to all %d books? If the format' + 'already exists for a book, it will be replaced.')%len(ids)): + return + + books = choose_files(self.gui, 'add formats dialog dir', + _('Select book files'), filters=get_filters()) + if not books: + return + + db = view.model().db + for id_ in ids: + for fpath in books: + fmt = os.path.splitext(fpath)[1][1:].upper() + if fmt: + db.add_format_with_hooks(id_, fmt, fpath, index_is_id=True, + notify=True) + current_idx = self.gui.library_view.currentIndex() + if current_idx.isValid(): + view.model().current_changed(current_idx, current_idx) + + def add_recursive(self, single): root = choose_dir(self.gui, 'recursive book import root dir dialog', 'Select root folder') @@ -207,27 +261,14 @@ class AddAction(InterfaceAction): ''' Add books from the local filesystem to either the library or the device. ''' - filters = [ - (_('Books'), BOOK_EXTENSIONS), - (_('EPUB Books'), ['epub']), - (_('LRF Books'), ['lrf']), - (_('HTML Books'), ['htm', 'html', 'xhtm', 'xhtml']), - (_('LIT Books'), ['lit']), - (_('MOBI Books'), ['mobi', 'prc', 'azw']), - (_('Topaz books'), ['tpz','azw1']), - (_('Text books'), ['txt', 'rtf']), - (_('PDF Books'), ['pdf']), - (_('SNB Books'), ['snb']), - (_('Comics'), ['cbz', 'cbr', 'cbc']), - (_('Archives'), ['zip', 'rar']), - ] + filters = get_filters() to_device = self.gui.stack.currentIndex() != 0 if to_device: fmts = self.gui.device_manager.device.settings().format_map filters = [(_('Supported books'), fmts)] - books = choose_files(self.gui, 'add books dialog dir', 'Select books', - filters=filters) + books = choose_files(self.gui, 'add books dialog dir', + _('Select books'), filters=filters) if not books: return self._add_books(books, to_device) diff --git a/src/calibre/manual/gui.rst b/src/calibre/manual/gui.rst index 8e224fead3..fff18a7333 100644 --- a/src/calibre/manual/gui.rst +++ b/src/calibre/manual/gui.rst @@ -497,6 +497,8 @@ Calibre has several keyboard shortcuts to save you time and mouse movement. Thes - Edit the metadata of the currently selected field in the book list. * - :kbd:`A` - Add Books + * - :kbd:`Shift+A` + - Add Formats to the selected books * - :kbd:`C` - Convert selected Books * - :kbd:`D` From dc5ccf1861b1d5a9882ce6685ec2c9e1d0bce63f Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 2 Mar 2011 16:11:37 -0700 Subject: [PATCH 15/23] Add quick create links to easily create custom columns of commonly used types to the add column dialog --- .../gui2/preferences/create_custom_column.py | 26 +++++++++++--- .../gui2/preferences/create_custom_column.ui | 34 ++++++++++++++++--- src/calibre/manual/faq.rst | 2 +- src/calibre/manual/template_lang.rst | 6 ++-- 4 files changed, 55 insertions(+), 13 deletions(-) diff --git a/src/calibre/gui2/preferences/create_custom_column.py b/src/calibre/gui2/preferences/create_custom_column.py index 9974de472f..e444bed104 100644 --- a/src/calibre/gui2/preferences/create_custom_column.py +++ b/src/calibre/gui2/preferences/create_custom_column.py @@ -6,8 +6,7 @@ __copyright__ = '2010, Kovid Goyal ' import re from functools import partial -from PyQt4.QtCore import SIGNAL -from PyQt4.Qt import QDialog, Qt, QListWidgetItem, QVariant +from PyQt4.Qt import QDialog, Qt, QListWidgetItem, QVariant, QIcon from calibre.gui2.preferences.create_custom_column_ui import Ui_QCreateCustomColumn from calibre.gui2 import error_dialog @@ -48,6 +47,7 @@ class CreateCustomColumn(QDialog, Ui_QCreateCustomColumn): QDialog.__init__(self, parent) Ui_QCreateCustomColumn.__init__(self) self.setupUi(self) + self.setWindowIcon(QIcon(I('column.png'))) # Remove help icon on title bar icon = self.windowIcon() self.setWindowFlags(self.windowFlags()&(~Qt.WindowContextHelpButtonHint)) @@ -55,8 +55,9 @@ class CreateCustomColumn(QDialog, Ui_QCreateCustomColumn): self.simple_error = partial(error_dialog, self, show=True, show_copy_button=False) - self.connect(self.button_box, SIGNAL("accepted()"), self.accept) - self.connect(self.button_box, SIGNAL("rejected()"), self.reject) + self.button_box.accepted.connect(self.accept) + self.button_box.rejected.connect(self.reject) + self.shortcuts.linkActivated.connect(self.shortcut_activated) self.parent = parent self.editing_col = editing self.standard_colheads = standard_colheads @@ -69,6 +70,7 @@ class CreateCustomColumn(QDialog, Ui_QCreateCustomColumn): self.datatype_changed() self.exec_() return + self.shortcuts.setVisible(False) idx = parent.opt_columns.currentRow() if idx < 0: self.simple_error(_('No column selected'), @@ -99,6 +101,22 @@ class CreateCustomColumn(QDialog, Ui_QCreateCustomColumn): self.datatype_changed() self.exec_() + def shortcut_activated(self, url): + which = unicode(url).split(':')[-1] + self.column_type_box.setCurrentIndex(10) + self.column_name_box.setText(which) + self.column_heading_box.setText({ + 'isbn':'ISBN', + 'formats':_('Formats'), + 'last_modified':_('Last Modified')}[which]) + self.composite_box.setText( + { + 'isbn': '{identifiers:select(isbn)}', + 'formats': '{formats}', + 'last_modified':'''{last_modified:'format_date($, "%d %m, %Y")'}''' + }[which]) + + def datatype_changed(self, *args): try: col_type = self.column_types[self.column_type_box.currentIndex()]['datatype'] diff --git a/src/calibre/gui2/preferences/create_custom_column.ui b/src/calibre/gui2/preferences/create_custom_column.ui index d4e85a24c9..141d05f9a0 100644 --- a/src/calibre/gui2/preferences/create_custom_column.ui +++ b/src/calibre/gui2/preferences/create_custom_column.ui @@ -9,8 +9,8 @@ 0 0 - 528 - 212 + 603 + 292 @@ -24,14 +24,14 @@ - + QLayout::SetDefaultConstraint 5 - + 0 @@ -238,7 +238,7 @@ four values, the first of them being the empty value. - + Qt::Horizontal @@ -264,6 +264,30 @@ four values, the first of them being the empty value. + + + + Quick create: <a href="col:isbn" title="Show the books' ISBN in the column">ISBN</a>, <a href="col:formats" title="Show the books' formats in the column">Formats</a>, <a href="col:last_modified" title="Show the date the books' metadata was last modified in the column">Last Modified</a> + + + true + + + + + + + Qt::Vertical + + + + + + + Qt::Vertical + + + diff --git a/src/calibre/manual/faq.rst b/src/calibre/manual/faq.rst index 8a78815751..84f99414a8 100644 --- a/src/calibre/manual/faq.rst +++ b/src/calibre/manual/faq.rst @@ -350,7 +350,7 @@ Why doesn't |app| have a column for foo? |app| is designed to have columns for the most frequently and widely used fields. In addition, you can add any columns you like. Columns can be added via :guilabel:`Preferences->Interface->Add your own columns`. Watch the tutorial `UI Power tips `_ to learn how to create your own columns. -You can also create "virtual columns" that contain combinations of the metadata from other columns. In the add column dialog choose the option "Column from other columns" and in the template enter the other column names. For example to create a virtual column containing formats or ISBN, enter ``{formats}`` for formats or ``{isbn}`` for ISBN. For more details, see :ref:`templatelangcalibre`. +You can also create "virtual columns" that contain combinations of the metadata from other columns. In the add column dialog use the :guilabel:`Quick create` links to easily create columns to show the book ISBN, formats or the time the book was last modified. For more details, see :ref:`templatelangcalibre`. Can I have a column showing the formats or the ISBN? diff --git a/src/calibre/manual/template_lang.rst b/src/calibre/manual/template_lang.rst index cf20b20ad8..3438f266b5 100644 --- a/src/calibre/manual/template_lang.rst +++ b/src/calibre/manual/template_lang.rst @@ -30,7 +30,7 @@ You can use all the various metadata fields available in calibre in a template, In addition to the column based fields, you also can use:: {formats} - A list of formats available in the calibre library for a book - {isbn} - The ISBN number of the book + {identifiers:select(isbn)} - The ISBN number of the book If a particular book does not have a particular piece of metadata, the field in the template is automatically removed for that book. Consider, for example:: @@ -95,7 +95,7 @@ Advanced features Using templates in custom columns ---------------------------------- -There are sometimes cases where you want to display metadata that |app| does not normally display, or to display data in a way different from how |app| normally does. For example, you might want to display the ISBN, a field that |app| does not display. You can use custom columns for this by creating a column with the type 'column built from other columns' (hereafter called composite columns), and entering a template. Result: |app| will display a column showing the result of evaluating that template. To display the ISBN, create the column and enter ``{isbn}`` into the template box. To display a column containing the values of two series custom columns separated by a comma, use ``{#series1:||,}{#series2}``. +There are sometimes cases where you want to display metadata that |app| does not normally display, or to display data in a way different from how |app| normally does. For example, you might want to display the ISBN, a field that |app| does not display. You can use custom columns for this by creating a column with the type 'column built from other columns' (hereafter called composite columns), and entering a template. Result: |app| will display a column showing the result of evaluating that template. To display the ISBN, create the column and enter ``{identifiers:select(isbn)}`` into the template box. To display a column containing the values of two series custom columns separated by a comma, use ``{#series1:||,}{#series2}``. Composite columns can use any template option, including formatting. @@ -122,10 +122,10 @@ The functions available are: * ``count(separator)`` -- interprets the value as a list of items separated by `separator`, returning the number of items in the list. Most lists use a comma as the separator, but authors uses an ampersand. Examples: `{tags:count(,)}`, `{authors:count(&)}` * ``ifempty(text)`` -- if the field is not empty, return the value of the field. Otherwise return `text`. * ``list_item(index, separator)`` -- interpret the value as a list of items separated by `separator`, returning the `index`th item. The first item is number zero. The last item can be returned using `list_item(-1,separator)`. If the item is not in the list, then the empty value is returned. The separator has the same meaning as in the `count` function. - * ``lookup(pattern, field, pattern, field, ..., else_field)`` -- like switch, except the arguments are field (metadata) names, not text. The value of the appropriate field will be fetched and used. Note that because composite columns are fields, you can use this function in one composite field to use the value of some other composite field. This is extremely useful when constructing variable save paths (more later). * ``re(pattern, replacement)`` -- return the field after applying the regular expression. All instances of `pattern` are replaced with `replacement`. As in all of |app|, these are python-compatible regular expressions. * ``shorten(left chars, middle text, right chars)`` -- Return a shortened version of the field, consisting of `left chars` characters from the beginning of the field, followed by `middle text`, followed by `right chars` characters from the end of the string. `Left chars` and `right chars` must be integers. For example, assume the title of the book is `Ancient English Laws in the Times of Ivanhoe`, and you want it to fit in a space of at most 15 characters. If you use ``{title:shorten(9,-,5)}``, the result will be `Ancient E-nhoe`. If the field's length is less than ``left chars`` + ``right chars`` + the length of ``middle text``, then the field will be used intact. For example, the title `The Dome` would not be changed. * ``switch(pattern, value, pattern, value, ..., else_value)`` -- for each ``pattern, value`` pair, checks if the field matches the regular expression ``pattern`` and if so, returns that ``value``. If no ``pattern`` matches, then ``else_value`` is returned. You can have as many ``pattern, value`` pairs as you want. + * ``lookup(pattern, field, pattern, field, ..., else_field)`` -- like switch, except the arguments are field (metadata) names, not text. The value of the appropriate field will be fetched and used. Note that because composite columns are fields, you can use this function in one composite field to use the value of some other composite field. This is extremely useful when constructing variable save paths (more later). * ``select(key)`` -- interpret the field as a comma-separated list of items, with the items being of the form "id:value". Find the pair with the id equal to key, and return the corresponding value. This function is particularly useful for extracting a value such as an isbn from the set of identifiers for a book. * ``test(text if not empty, text if empty)`` -- return `text if not empty` if the field is not empty, otherwise return `text if empty`. From 4ca767b9fc54c98930ea0078b91c9b0faa9681fa Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 2 Mar 2011 16:18:35 -0700 Subject: [PATCH 16/23] ... --- src/calibre/gui2/preferences/create_custom_column.py | 12 ++++++++++-- src/calibre/gui2/preferences/create_custom_column.ui | 2 +- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/calibre/gui2/preferences/create_custom_column.py b/src/calibre/gui2/preferences/create_custom_column.py index e444bed104..bf6b162bde 100644 --- a/src/calibre/gui2/preferences/create_custom_column.py +++ b/src/calibre/gui2/preferences/create_custom_column.py @@ -103,13 +103,21 @@ class CreateCustomColumn(QDialog, Ui_QCreateCustomColumn): def shortcut_activated(self, url): which = unicode(url).split(':')[-1] - self.column_type_box.setCurrentIndex(10) + self.column_type_box.setCurrentIndex({ + 'yesno': 9, + 'tags' : 1, + 'series': 3, + }.get(which, 10)) self.column_name_box.setText(which) self.column_heading_box.setText({ 'isbn':'ISBN', 'formats':_('Formats'), + 'yesno':_('Yes/No'), + 'tags': _('My Tags'), + 'series': _('My Series'), 'last_modified':_('Last Modified')}[which]) - self.composite_box.setText( + if self.composite_box.isVisible(): + self.composite_box.setText( { 'isbn': '{identifiers:select(isbn)}', 'formats': '{formats}', diff --git a/src/calibre/gui2/preferences/create_custom_column.ui b/src/calibre/gui2/preferences/create_custom_column.ui index 141d05f9a0..8ed54b6af6 100644 --- a/src/calibre/gui2/preferences/create_custom_column.ui +++ b/src/calibre/gui2/preferences/create_custom_column.ui @@ -267,7 +267,7 @@ four values, the first of them being the empty value. - Quick create: <a href="col:isbn" title="Show the books' ISBN in the column">ISBN</a>, <a href="col:formats" title="Show the books' formats in the column">Formats</a>, <a href="col:last_modified" title="Show the date the books' metadata was last modified in the column">Last Modified</a> + Quick create: <a href="col:isbn" title="Show the books' ISBN in the column">ISBN</a>, <a href="col:formats" title="Show the books' formats in the column">Formats</a>, <a href="col:last_modified" title="Show the date the books' metadata was last modified in the column">Last Modified</a>, <a href="col:yesno">Yes/No</a>, <a href="col:tags">Tags</a>, <a href="col:series">Series</a> true From 9fe3d1a44b147c7fe7e6e04f0edf1355227c0c52 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 2 Mar 2011 16:21:08 -0700 Subject: [PATCH 17/23] ... --- src/calibre/gui2/preferences/create_custom_column.py | 2 ++ src/calibre/gui2/preferences/create_custom_column.ui | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/calibre/gui2/preferences/create_custom_column.py b/src/calibre/gui2/preferences/create_custom_column.py index bf6b162bde..6a81abf499 100644 --- a/src/calibre/gui2/preferences/create_custom_column.py +++ b/src/calibre/gui2/preferences/create_custom_column.py @@ -107,6 +107,7 @@ class CreateCustomColumn(QDialog, Ui_QCreateCustomColumn): 'yesno': 9, 'tags' : 1, 'series': 3, + 'rating': 8, }.get(which, 10)) self.column_name_box.setText(which) self.column_heading_box.setText({ @@ -115,6 +116,7 @@ class CreateCustomColumn(QDialog, Ui_QCreateCustomColumn): 'yesno':_('Yes/No'), 'tags': _('My Tags'), 'series': _('My Series'), + 'rating': _('My Rating'), 'last_modified':_('Last Modified')}[which]) if self.composite_box.isVisible(): self.composite_box.setText( diff --git a/src/calibre/gui2/preferences/create_custom_column.ui b/src/calibre/gui2/preferences/create_custom_column.ui index 8ed54b6af6..683bfe6eb5 100644 --- a/src/calibre/gui2/preferences/create_custom_column.ui +++ b/src/calibre/gui2/preferences/create_custom_column.ui @@ -10,7 +10,7 @@ 0 0 603 - 292 + 344 @@ -267,7 +267,7 @@ four values, the first of them being the empty value. - Quick create: <a href="col:isbn" title="Show the books' ISBN in the column">ISBN</a>, <a href="col:formats" title="Show the books' formats in the column">Formats</a>, <a href="col:last_modified" title="Show the date the books' metadata was last modified in the column">Last Modified</a>, <a href="col:yesno">Yes/No</a>, <a href="col:tags">Tags</a>, <a href="col:series">Series</a> + Quick create: <a href="col:isbn" title="Show the books' ISBN in the column">ISBN</a>, <a href="col:formats" title="Show the books' formats in the column">Formats</a>, <a href="col:last_modified" title="Show the date the books' metadata was last modified in the column">Last Modified</a>, <a href="col:yesno">Yes/No</a>, <a href="col:tags">Tags</a>, <a href="col:series">Series</a>, <a href="col:rating">Rating</a> true From 546995553a794a5973044f7b5c1b1cc02418e2dc Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 2 Mar 2011 16:28:52 -0700 Subject: [PATCH 18/23] ... --- src/calibre/gui2/preferences/create_custom_column.py | 11 ++++++++++- src/calibre/gui2/preferences/create_custom_column.ui | 2 +- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/calibre/gui2/preferences/create_custom_column.py b/src/calibre/gui2/preferences/create_custom_column.py index 6a81abf499..daf94a6a58 100644 --- a/src/calibre/gui2/preferences/create_custom_column.py +++ b/src/calibre/gui2/preferences/create_custom_column.py @@ -58,6 +58,15 @@ class CreateCustomColumn(QDialog, Ui_QCreateCustomColumn): self.button_box.accepted.connect(self.accept) self.button_box.rejected.connect(self.reject) self.shortcuts.linkActivated.connect(self.shortcut_activated) + text = '

'+_('Quick create:') + ' ' + for col, name in [('isbn', _('ISBN')), ('formats', _('Formats')), + ('last_modified', _('Modified Date')), ('yesno', _('Yes/No')), + ('tags', _('Tags')), ('series', _('Series')), ('rating', + _('Rating'))]: + text += ' %s,'%(col, name) + text = text[:-1] + self.shortcuts.setText(text) + self.parent = parent self.editing_col = editing self.standard_colheads = standard_colheads @@ -117,7 +126,7 @@ class CreateCustomColumn(QDialog, Ui_QCreateCustomColumn): 'tags': _('My Tags'), 'series': _('My Series'), 'rating': _('My Rating'), - 'last_modified':_('Last Modified')}[which]) + 'last_modified':_('Modified Date')}[which]) if self.composite_box.isVisible(): self.composite_box.setText( { diff --git a/src/calibre/gui2/preferences/create_custom_column.ui b/src/calibre/gui2/preferences/create_custom_column.ui index 683bfe6eb5..18130730fe 100644 --- a/src/calibre/gui2/preferences/create_custom_column.ui +++ b/src/calibre/gui2/preferences/create_custom_column.ui @@ -267,7 +267,7 @@ four values, the first of them being the empty value. - Quick create: <a href="col:isbn" title="Show the books' ISBN in the column">ISBN</a>, <a href="col:formats" title="Show the books' formats in the column">Formats</a>, <a href="col:last_modified" title="Show the date the books' metadata was last modified in the column">Last Modified</a>, <a href="col:yesno">Yes/No</a>, <a href="col:tags">Tags</a>, <a href="col:series">Series</a>, <a href="col:rating">Rating</a> + true From 88c185aa67a4e50f11f73092ff4f4f04055cb06e Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 2 Mar 2011 16:37:47 -0700 Subject: [PATCH 19/23] ... --- .../gui2/preferences/create_custom_column.py | 7 +++++-- .../gui2/preferences/create_custom_column.ui | 13 ++++++++----- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/calibre/gui2/preferences/create_custom_column.py b/src/calibre/gui2/preferences/create_custom_column.py index daf94a6a58..88e29f78af 100644 --- a/src/calibre/gui2/preferences/create_custom_column.py +++ b/src/calibre/gui2/preferences/create_custom_column.py @@ -6,7 +6,7 @@ __copyright__ = '2010, Kovid Goyal ' import re from functools import partial -from PyQt4.Qt import QDialog, Qt, QListWidgetItem, QVariant, QIcon +from PyQt4.Qt import QDialog, Qt, QListWidgetItem, QVariant from calibre.gui2.preferences.create_custom_column_ui import Ui_QCreateCustomColumn from calibre.gui2 import error_dialog @@ -47,7 +47,8 @@ class CreateCustomColumn(QDialog, Ui_QCreateCustomColumn): QDialog.__init__(self, parent) Ui_QCreateCustomColumn.__init__(self) self.setupUi(self) - self.setWindowIcon(QIcon(I('column.png'))) + self.setWindowTitle(_('Create a custom column')) + self.heading_label.setText(_('Create a custom column')) # Remove help icon on title bar icon = self.windowIcon() self.setWindowFlags(self.windowFlags()&(~Qt.WindowContextHelpButtonHint)) @@ -79,6 +80,8 @@ class CreateCustomColumn(QDialog, Ui_QCreateCustomColumn): self.datatype_changed() self.exec_() return + self.setWindowTitle(_('Edit a custom column')) + self.heading_label.setText(_('Edit a custom column')) self.shortcuts.setVisible(False) idx = parent.opt_columns.currentRow() if idx < 0: diff --git a/src/calibre/gui2/preferences/create_custom_column.ui b/src/calibre/gui2/preferences/create_custom_column.ui index 18130730fe..9df7107d9b 100644 --- a/src/calibre/gui2/preferences/create_custom_column.ui +++ b/src/calibre/gui2/preferences/create_custom_column.ui @@ -19,8 +19,9 @@ 0 - - Create or edit custom columns + + + :/images/column.png:/images/column.png @@ -252,7 +253,7 @@ four values, the first of them being the empty value. - + 75 @@ -260,7 +261,7 @@ four values, the first of them being the empty value. - Create or edit custom columns + @@ -300,6 +301,8 @@ four values, the first of them being the empty value. composite_box button_box - + + + From 5a1d5af0350ee13a85d77b1f02a0b0d7e9eb58e7 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 2 Mar 2011 16:49:29 -0700 Subject: [PATCH 20/23] ... --- src/calibre/gui2/preferences/columns.ui | 36 +++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/calibre/gui2/preferences/columns.ui b/src/calibre/gui2/preferences/columns.ui index b5dc9b8c90..a9d82530ec 100644 --- a/src/calibre/gui2/preferences/columns.ui +++ b/src/calibre/gui2/preferences/columns.ui @@ -38,6 +38,9 @@ + + Move column up + ... @@ -45,6 +48,12 @@ :/images/arrow-up.png:/images/arrow-up.png + + + 32 + 32 + + @@ -72,6 +81,12 @@ :/images/minus.png:/images/minus.png + + + 32 + 32 + + @@ -99,6 +114,12 @@ :/images/plus.png:/images/plus.png + + + 32 + 32 + + @@ -126,6 +147,12 @@ :/images/edit_input.png:/images/edit_input.png + + + 32 + 32 + + @@ -143,6 +170,9 @@ + + Move column down + ... @@ -150,6 +180,12 @@ :/images/arrow-down.png:/images/arrow-down.png + + + 32 + 32 + + From b7bed6576be3535a9bad7ef729c493ec3a068595 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 2 Mar 2011 16:53:59 -0700 Subject: [PATCH 21/23] ... --- src/calibre/gui2/preferences/create_custom_column.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/calibre/gui2/preferences/create_custom_column.py b/src/calibre/gui2/preferences/create_custom_column.py index 88e29f78af..d390763ab0 100644 --- a/src/calibre/gui2/preferences/create_custom_column.py +++ b/src/calibre/gui2/preferences/create_custom_column.py @@ -59,7 +59,7 @@ class CreateCustomColumn(QDialog, Ui_QCreateCustomColumn): self.button_box.accepted.connect(self.accept) self.button_box.rejected.connect(self.reject) self.shortcuts.linkActivated.connect(self.shortcut_activated) - text = '

'+_('Quick create:') + ' ' + text = '

'+_('Quick create:') for col, name in [('isbn', _('ISBN')), ('formats', _('Formats')), ('last_modified', _('Modified Date')), ('yesno', _('Yes/No')), ('tags', _('Tags')), ('series', _('Series')), ('rating', From f525e451c8a2032371d82b599299991bc2356489 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 2 Mar 2011 20:35:47 -0700 Subject: [PATCH 22/23] Fix #9239 (Thai Post Daily Newspaper recipe) --- resources/recipes/thai_post_daily.recipe | 35 ++++++++++++------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/resources/recipes/thai_post_daily.recipe b/resources/recipes/thai_post_daily.recipe index 9cd943e593..2be17cc37f 100644 --- a/resources/recipes/thai_post_daily.recipe +++ b/resources/recipes/thai_post_daily.recipe @@ -1,18 +1,17 @@ -from calibre.web.feeds.news import BasicNewsRecipe - -class AdvancedUserRecipe1299054026(BasicNewsRecipe): - title = u'Thai Post Daily' - __author__ = 'Chotechai P.' - language = 'th' - oldest_article = 7 - max_articles_per_feed = 100 - - feeds = [(u'\u0e02\u0e48\u0e32\u0e27\u0e2b\u0e19\u0e49\u0e32\u0e2b\u0e19\u0e36\u0e48\u0e07', u'http://thaipost.net/taxonomy/term/1/all/feed'), (u'\u0e1a\u0e17\u0e1a\u0e23\u0e23\u0e13\u0e32\u0e18\u0e34\u0e01\u0e32\u0e23', u'http://thaipost.net/taxonomy/term/11/all/feed'), (u'\u0e40\u0e1b\u0e25\u0e27 \u0e2a\u0e35\u0e40\u0e07\u0e34\u0e19', u'http://thaipost.net/taxonomy/term/2/all/feed'), (u'\u0e2a\u0e20\u0e32\u0e1b\u0e23\u0e30\u0e0a\u0e32\u0e0a\u0e19', u'http://thaipost.net/taxonomy/term/3/all/feed'), (u'\u0e16\u0e39\u0e01\u0e17\u0e38\u0e01\u0e02\u0e49\u0e2d', u'http://thaipost.net/taxonomy/term/4/all/feed'), (u'\u0e01\u0e32\u0e23\u0e40\u0e21\u0e37\u0e2d\u0e07', u'http://thaipost.net/taxonomy/term/5/all/feed'), (u'\u0e17\u0e48\u0e32\u0e19\u0e02\u0e38\u0e19\u0e19\u0e49\u0e2d\u0e22', u'http://thaipost.net/taxonomy/term/12/all/feed'), (u'\u0e1a\u0e17\u0e04\u0e27\u0e32\u0e21\u0e1e\u0e34\u0e40\u0e28\u0e29', u'http://thaipost.net/taxonomy/term/66/all/feed'), (u'\u0e23\u0e32\u0e22\u0e07\u0e32\u0e19\u0e1e\u0e34\u0e40\u0e28\u0e29', u'http://thaipost.net/taxonomy/term/67/all/feed'), (u'\u0e1a\u0e31\u0e19\u0e17\u0e36\u0e01\u0e2b\u0e19\u0e49\u0e32 4', u'http://thaipost.net/taxonomy/term/13/all/feed'), (u'\u0e40\u0e2a\u0e35\u0e22\u0e1a\u0e0b\u0e36\u0e48\u0e07\u0e2b\u0e19\u0e49\u0e32', u'http://thaipost.net/taxonomy/term/64/all/feed'), (u'\u0e04\u0e31\u0e19\u0e1b\u0e32\u0e01\u0e2d\u0e22\u0e32\u0e01\u0e40\u0e25\u0e48\u0e32', u'http://thaipost.net/taxonomy/term/65/all/feed'), (u'\u0e40\u0e28\u0e23\u0e29\u0e10\u0e01\u0e34\u0e08', u'http://thaipost.net/taxonomy/term/6/all/feed'), (u'\u0e01\u0e23\u0e30\u0e08\u0e01\u0e44\u0e23\u0e49\u0e40\u0e07\u0e32', u'http://thaipost.net/taxonomy/term/14/all/feed'), (u'\u0e01\u0e23\u0e30\u0e08\u0e01\u0e2b\u0e31\u0e01\u0e21\u0e38\u0e21', u'http://thaipost.net/taxonomy/term/71/all/feed'), (u'\u0e04\u0e34\u0e14\u0e40\u0e2b\u0e19\u0e37\u0e2d\u0e01\u0e23\u0e30\u0e41\u0e2a', u'http://thaipost.net/taxonomy/term/69/all/feed'), (u'\u0e23\u0e32\u0e22\u0e07\u0e32\u0e19', u'http://thaipost.net/taxonomy/term/68/all/feed'), (u'\u0e2d\u0e34\u0e42\u0e04\u0e42\u0e1f\u0e01\u0e31\u0e2a', u'http://thaipost.net/taxonomy/term/10/all/feed'), (u'\u0e01\u0e32\u0e23\u0e28\u0e36\u0e01\u0e29\u0e32-\u0e2a\u0e32\u0e18\u0e32\u0e23\u0e13\u0e2a\u0e38\u0e02', u'http://thaipost.net/taxonomy/term/7/all/feed'), (u'\u0e15\u0e48\u0e32\u0e07\u0e1b\u0e23\u0e30\u0e40\u0e17\u0e28', u'http://thaipost.net/taxonomy/term/8/all/feed'), (u'\u0e01\u0e35\u0e2c\u0e32', u'http://thaipost.net/taxonomy/term/9/all/feed')] - - def print_version(self, url): - return url.replace(url, 'http://www.thaipost.net/print/' + url [32:]) - - remove_tags = [] - remove_tags.append(dict(name = 'div', attrs = {'class' : 'print-logo'})) - remove_tags.append(dict(name = 'div', attrs = {'class' : 'print-site_name'})) - remove_tags.append(dict(name = 'div', attrs = {'class' : 'print-breadcrumb'})) +from calibre.web.feeds.news import BasicNewsRecipe + +class AdvancedUserRecipe1299054026(BasicNewsRecipe): + title = u'Thai Post Daily' + __author__ = 'Chotechai P.' + oldest_article = 7 + max_articles_per_feed = 100 + cover_url = 'http://upload.wikimedia.org/wikipedia/th/1/10/ThaiPost_Logo.png' + feeds = [(u'\u0e02\u0e48\u0e32\u0e27\u0e2b\u0e19\u0e49\u0e32\u0e2b\u0e19\u0e36\u0e48\u0e07', u'http://thaipost.net/taxonomy/term/1/all/feed'), (u'\u0e1a\u0e17\u0e1a\u0e23\u0e23\u0e13\u0e32\u0e18\u0e34\u0e01\u0e32\u0e23', u'http://thaipost.net/taxonomy/term/11/all/feed'), (u'\u0e40\u0e1b\u0e25\u0e27 \u0e2a\u0e35\u0e40\u0e07\u0e34\u0e19', u'http://thaipost.net/taxonomy/term/2/all/feed'), (u'\u0e2a\u0e20\u0e32\u0e1b\u0e23\u0e30\u0e0a\u0e32\u0e0a\u0e19', u'http://thaipost.net/taxonomy/term/3/all/feed'), (u'\u0e16\u0e39\u0e01\u0e17\u0e38\u0e01\u0e02\u0e49\u0e2d', u'http://thaipost.net/taxonomy/term/4/all/feed'), (u'\u0e01\u0e32\u0e23\u0e40\u0e21\u0e37\u0e2d\u0e07', u'http://thaipost.net/taxonomy/term/5/all/feed'), (u'\u0e17\u0e48\u0e32\u0e19\u0e02\u0e38\u0e19\u0e19\u0e49\u0e2d\u0e22', u'http://thaipost.net/taxonomy/term/12/all/feed'), (u'\u0e1a\u0e17\u0e04\u0e27\u0e32\u0e21\u0e1e\u0e34\u0e40\u0e28\u0e29', u'http://thaipost.net/taxonomy/term/66/all/feed'), (u'\u0e23\u0e32\u0e22\u0e07\u0e32\u0e19\u0e1e\u0e34\u0e40\u0e28\u0e29', u'http://thaipost.net/taxonomy/term/67/all/feed'), (u'\u0e1a\u0e31\u0e19\u0e17\u0e36\u0e01\u0e2b\u0e19\u0e49\u0e32 4', u'http://thaipost.net/taxonomy/term/13/all/feed'), (u'\u0e40\u0e2a\u0e35\u0e22\u0e1a\u0e0b\u0e36\u0e48\u0e07\u0e2b\u0e19\u0e49\u0e32', u'http://thaipost.net/taxonomy/term/64/all/feed'), (u'\u0e04\u0e31\u0e19\u0e1b\u0e32\u0e01\u0e2d\u0e22\u0e32\u0e01\u0e40\u0e25\u0e48\u0e32', u'http://thaipost.net/taxonomy/term/65/all/feed'), (u'\u0e40\u0e28\u0e23\u0e29\u0e10\u0e01\u0e34\u0e08', u'http://thaipost.net/taxonomy/term/6/all/feed'), (u'\u0e01\u0e23\u0e30\u0e08\u0e01\u0e44\u0e23\u0e49\u0e40\u0e07\u0e32', u'http://thaipost.net/taxonomy/term/14/all/feed'), (u'\u0e01\u0e23\u0e30\u0e08\u0e01\u0e2b\u0e31\u0e01\u0e21\u0e38\u0e21', u'http://thaipost.net/taxonomy/term/71/all/feed'), (u'\u0e04\u0e34\u0e14\u0e40\u0e2b\u0e19\u0e37\u0e2d\u0e01\u0e23\u0e30\u0e41\u0e2a', u'http://thaipost.net/taxonomy/term/69/all/feed'), (u'\u0e23\u0e32\u0e22\u0e07\u0e32\u0e19', u'http://thaipost.net/taxonomy/term/68/all/feed'), (u'\u0e2d\u0e34\u0e42\u0e04\u0e42\u0e1f\u0e01\u0e31\u0e2a', u'http://thaipost.net/taxonomy/term/10/all/feed'), (u'\u0e01\u0e32\u0e23\u0e28\u0e36\u0e01\u0e29\u0e32-\u0e2a\u0e32\u0e18\u0e32\u0e23\u0e13\u0e2a\u0e38\u0e02', u'http://thaipost.net/taxonomy/term/7/all/feed'), (u'\u0e15\u0e48\u0e32\u0e07\u0e1b\u0e23\u0e30\u0e40\u0e17\u0e28', u'http://thaipost.net/taxonomy/term/8/all/feed'), (u'\u0e01\u0e35\u0e2c\u0e32', u'http://thaipost.net/taxonomy/term/9/all/feed')] + + def print_version(self, url): + return url.replace(url, 'http://www.thaipost.net/print/' + url [32:]) + + remove_tags = [] + remove_tags.append(dict(name = 'div', attrs = {'class' : 'print-logo'})) + remove_tags.append(dict(name = 'div', attrs = {'class' : 'print-site_name'})) + remove_tags.append(dict(name = 'div', attrs = {'class' : 'print-breadcrumb'})) From 6e116969622129a7724e3b00a6904afabac4cc8d Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 2 Mar 2011 20:40:22 -0700 Subject: [PATCH 23/23] Fix #9240 (Post Today newspaper recipe) --- resources/recipes/post_today.recipe | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/recipes/post_today.recipe b/resources/recipes/post_today.recipe index dc86e68191..a86e154b84 100644 --- a/resources/recipes/post_today.recipe +++ b/resources/recipes/post_today.recipe @@ -3,7 +3,7 @@ from calibre.web.feeds.news import BasicNewsRecipe class AdvancedUserRecipe1299061355(BasicNewsRecipe): title = u'Post Today' language = 'th' - __author__ = "Chotechai" + __author__ = "Chotechai P." oldest_article = 7 max_articles_per_feed = 100 cover_url = 'http://upload.wikimedia.org/wikipedia/th/2/2e/Posttoday_Logo.png'