KG updates

This commit is contained in:
GRiker 2011-06-09 09:40:33 -06:00
commit 60045bb9c9
21 changed files with 779 additions and 338 deletions

View File

@ -11,8 +11,8 @@ import mechanize, re
class GoComics(BasicNewsRecipe): class GoComics(BasicNewsRecipe):
title = 'GoComics' title = 'GoComics'
__author__ = 'Starson17' __author__ = 'Starson17'
__version__ = '1.05' __version__ = '1.06'
__date__ = '19 may 2011' __date__ = '07 June 2011'
description = u'200+ Comics - Customize for more days/comics: Defaults to 7 days, 25 comics - 20 general, 5 editorial.' description = u'200+ Comics - Customize for more days/comics: Defaults to 7 days, 25 comics - 20 general, 5 editorial.'
category = 'news, comics' category = 'news, comics'
language = 'en' language = 'en'
@ -56,225 +56,318 @@ class GoComics(BasicNewsRecipe):
def parse_index(self): def parse_index(self):
feeds = [] feeds = []
for title, url in [ for title, url in [
######## COMICS - GENERAL ######## (u"2 Cows and a Chicken", u"http://www.gocomics.com/2cowsandachicken"),
(u"2 Cows and a Chicken", u"http://www.gocomics.com/2cowsandachicken"), #(u"9 Chickweed Lane", u"http://www.gocomics.com/9chickweedlane"),
# (u"9 to 5", u"http://www.gocomics.com/9to5"), (u"9 to 5", u"http://www.gocomics.com/9to5"),
# (u"The Academia Waltz", u"http://www.gocomics.com/academiawaltz"), #(u"Adam At Home", u"http://www.gocomics.com/adamathome"),
# (u"Adam@Home", u"http://www.gocomics.com/adamathome"), (u"Agnes", u"http://www.gocomics.com/agnes"),
# (u"Agnes", u"http://www.gocomics.com/agnes"), #(u"Alley Oop", u"http://www.gocomics.com/alleyoop"),
# (u"Andy Capp", u"http://www.gocomics.com/andycapp"), #(u"Andy Capp", u"http://www.gocomics.com/andycapp"),
# (u"Animal Crackers", u"http://www.gocomics.com/animalcrackers"), #(u"Animal Crackers", u"http://www.gocomics.com/animalcrackers"),
# (u"Annie", u"http://www.gocomics.com/annie"), #(u"Annie", u"http://www.gocomics.com/annie"),
(u"The Argyle Sweater", u"http://www.gocomics.com/theargylesweater"), #(u"Arlo & Janis", u"http://www.gocomics.com/arloandjanis"),
# (u"Ask Shagg", u"http://www.gocomics.com/askshagg"), #(u"Ask Shagg", u"http://www.gocomics.com/askshagg"),
(u"B.C.", u"http://www.gocomics.com/bc"), (u"B.C.", u"http://www.gocomics.com/bc"),
# (u"Back in the Day", u"http://www.gocomics.com/backintheday"), #(u"Back in the Day", u"http://www.gocomics.com/backintheday"),
# (u"Bad Reporter", u"http://www.gocomics.com/badreporter"), #(u"Bad Reporter", u"http://www.gocomics.com/badreporter"),
# (u"Baldo", u"http://www.gocomics.com/baldo"), #(u"Baldo", u"http://www.gocomics.com/baldo"),
# (u"Ballard Street", u"http://www.gocomics.com/ballardstreet"), #(u"Ballard Street", u"http://www.gocomics.com/ballardstreet"),
# (u"Barkeater Lake", u"http://www.gocomics.com/barkeaterlake"), #(u"Barkeater Lake", u"http://www.gocomics.com/barkeaterlake"),
# (u"The Barn", u"http://www.gocomics.com/thebarn"), #(u"Basic Instructions", u"http://www.gocomics.com/basicinstructions"),
# (u"Basic Instructions", u"http://www.gocomics.com/basicinstructions"), #(u"Ben", u"http://www.gocomics.com/ben"),
# (u"Bewley", u"http://www.gocomics.com/bewley"), #(u"Betty", u"http://www.gocomics.com/betty"),
# (u"Big Top", u"http://www.gocomics.com/bigtop"), #(u"Bewley", u"http://www.gocomics.com/bewley"),
# (u"Biographic", u"http://www.gocomics.com/biographic"), #(u"Big Nate", u"http://www.gocomics.com/bignate"),
(u"Birdbrains", u"http://www.gocomics.com/birdbrains"), #(u"Big Top", u"http://www.gocomics.com/bigtop"),
# (u"Bleeker: The Rechargeable Dog", u"http://www.gocomics.com/bleeker"), #(u"Biographic", u"http://www.gocomics.com/biographic"),
# (u"Bliss", u"http://www.gocomics.com/bliss"), #(u"Birdbrains", u"http://www.gocomics.com/birdbrains"),
(u"Bloom County", u"http://www.gocomics.com/bloomcounty"), #(u"Bleeker: The Rechargeable Dog", u"http://www.gocomics.com/bleeker"),
# (u"Bo Nanas", u"http://www.gocomics.com/bonanas"), #(u"Bliss", u"http://www.gocomics.com/bliss"),
# (u"Bob the Squirrel", u"http://www.gocomics.com/bobthesquirrel"), (u"Bloom County", u"http://www.gocomics.com/bloomcounty"),
# (u"The Boiling Point", u"http://www.gocomics.com/theboilingpoint"), #(u"Bo Nanas", u"http://www.gocomics.com/bonanas"),
# (u"Boomerangs", u"http://www.gocomics.com/boomerangs"), #(u"Bob the Squirrel", u"http://www.gocomics.com/bobthesquirrel"),
# (u"The Boondocks", u"http://www.gocomics.com/boondocks"), #(u"Boomerangs", u"http://www.gocomics.com/boomerangs"),
# (u"Bottomliners", u"http://www.gocomics.com/bottomliners"), #(u"Bottomliners", u"http://www.gocomics.com/bottomliners"),
# (u"Bound and Gagged", u"http://www.gocomics.com/boundandgagged"), #(u"Bound and Gagged", u"http://www.gocomics.com/boundandgagged"),
# (u"Brainwaves", u"http://www.gocomics.com/brainwaves"), #(u"Brainwaves", u"http://www.gocomics.com/brainwaves"),
# (u"Brenda Starr", u"http://www.gocomics.com/brendastarr"), #(u"Brenda Starr", u"http://www.gocomics.com/brendastarr"),
# (u"Brewster Rockit", u"http://www.gocomics.com/brewsterrockit"), #(u"Brevity", u"http://www.gocomics.com/brevity"),
# (u"Broom Hilda", u"http://www.gocomics.com/broomhilda"), #(u"Brewster Rockit", u"http://www.gocomics.com/brewsterrockit"),
(u"Calvin and Hobbes", u"http://www.gocomics.com/calvinandhobbes"), #(u"Broom Hilda", u"http://www.gocomics.com/broomhilda"),
# (u"Candorville", u"http://www.gocomics.com/candorville"), (u"Calvin and Hobbes", u"http://www.gocomics.com/calvinandhobbes"),
# (u"Cathy", u"http://www.gocomics.com/cathy"), #(u"Candorville", u"http://www.gocomics.com/candorville"),
# (u"C'est la Vie", u"http://www.gocomics.com/cestlavie"), #(u"Cathy", u"http://www.gocomics.com/cathy"),
# (u"Chuckle Bros", u"http://www.gocomics.com/chucklebros"), #(u"C'est la Vie", u"http://www.gocomics.com/cestlavie"),
# (u"Citizen Dog", u"http://www.gocomics.com/citizendog"), #(u"Cheap Thrills", u"http://www.gocomics.com/cheapthrills"),
# (u"The City", u"http://www.gocomics.com/thecity"), #(u"Chuckle Bros", u"http://www.gocomics.com/chucklebros"),
# (u"Cleats", u"http://www.gocomics.com/cleats"), #(u"Citizen Dog", u"http://www.gocomics.com/citizendog"),
# (u"Close to Home", u"http://www.gocomics.com/closetohome"), #(u"Cleats", u"http://www.gocomics.com/cleats"),
# (u"Compu-toon", u"http://www.gocomics.com/compu-toon"), #(u"Close to Home", u"http://www.gocomics.com/closetohome"),
# (u"Cornered", u"http://www.gocomics.com/cornered"), #(u"Committed", u"http://www.gocomics.com/committed"),
(u"Cul de Sac", u"http://www.gocomics.com/culdesac"), #(u"Compu-toon", u"http://www.gocomics.com/compu-toon"),
# (u"Daddy's Home", u"http://www.gocomics.com/daddyshome"), #(u"Cornered", u"http://www.gocomics.com/cornered"),
# (u"Deep Cover", u"http://www.gocomics.com/deepcover"), #(u"Cow & Boy", u"http://www.gocomics.com/cow&boy"),
# (u"Dick Tracy", u"http://www.gocomics.com/dicktracy"), #(u"Cul de Sac", u"http://www.gocomics.com/culdesac"),
# (u"The Dinette Set", u"http://www.gocomics.com/dinetteset"), #(u"Daddy's Home", u"http://www.gocomics.com/daddyshome"),
# (u"Dog Eat Doug", u"http://www.gocomics.com/dogeatdoug"), #(u"Deep Cover", u"http://www.gocomics.com/deepcover"),
# (u"Domestic Abuse", u"http://www.gocomics.com/domesticabuse"), #(u"Dick Tracy", u"http://www.gocomics.com/dicktracy"),
# (u"Doodles", u"http://www.gocomics.com/doodles"), (u"Dog Eat Doug", u"http://www.gocomics.com/dogeatdoug"),
(u"Doonesbury", u"http://www.gocomics.com/doonesbury"), #(u"Domestic Abuse", u"http://www.gocomics.com/domesticabuse"),
# (u"The Doozies", u"http://www.gocomics.com/thedoozies"), (u"Doodles", u"http://www.gocomics.com/doodles"),
# (u"The Duplex", u"http://www.gocomics.com/duplex"), (u"Doonesbury", u"http://www.gocomics.com/doonesbury"),
# (u"Eek!", u"http://www.gocomics.com/eek"), #(u"Drabble", u"http://www.gocomics.com/drabble"),
# (u"The Elderberries", u"http://www.gocomics.com/theelderberries"), #(u"Eek!", u"http://www.gocomics.com/eek"),
# (u"Flight Deck", u"http://www.gocomics.com/flightdeck"), #(u"F Minus", u"http://www.gocomics.com/fminus"),
# (u"Flo and Friends", u"http://www.gocomics.com/floandfriends"), #(u"Family Tree", u"http://www.gocomics.com/familytree"),
# (u"The Flying McCoys", u"http://www.gocomics.com/theflyingmccoys"), #(u"Farcus", u"http://www.gocomics.com/farcus"),
(u"For Better or For Worse", u"http://www.gocomics.com/forbetterorforworse"), (u"Fat Cats Classics", u"http://www.gocomics.com/fatcatsclassics"),
# (u"For Heaven's Sake", u"http://www.gocomics.com/forheavenssake"), #(u"Ferd'nand", u"http://www.gocomics.com/ferdnand"),
# (u"Fort Knox", u"http://www.gocomics.com/fortknox"), #(u"Flight Deck", u"http://www.gocomics.com/flightdeck"),
# (u"FoxTrot", u"http://www.gocomics.com/foxtrot"), (u"Flo and Friends", u"http://www.gocomics.com/floandfriends"),
(u"FoxTrot Classics", u"http://www.gocomics.com/foxtrotclassics"), #(u"For Better or For Worse", u"http://www.gocomics.com/forbetterorforworse"),
# (u"Frank & Ernest", u"http://www.gocomics.com/frankandernest"), #(u"For Heaven's Sake", u"http://www.gocomics.com/forheavenssake"),
# (u"Fred Basset", u"http://www.gocomics.com/fredbasset"), #(u"Fort Knox", u"http://www.gocomics.com/fortknox"),
# (u"Free Range", u"http://www.gocomics.com/freerange"), #(u"FoxTrot Classics", u"http://www.gocomics.com/foxtrotclassics"),
# (u"Frog Applause", u"http://www.gocomics.com/frogapplause"), (u"FoxTrot", u"http://www.gocomics.com/foxtrot"),
# (u"The Fusco Brothers", u"http://www.gocomics.com/thefuscobrothers"), #(u"Frank & Ernest", u"http://www.gocomics.com/frankandernest"),
(u"Garfield", u"http://www.gocomics.com/garfield"), #(u"Frazz", u"http://www.gocomics.com/frazz"),
# (u"Garfield Minus Garfield", u"http://www.gocomics.com/garfieldminusgarfield"), #(u"Fred Basset", u"http://www.gocomics.com/fredbasset"),
# (u"Gasoline Alley", u"http://www.gocomics.com/gasolinealley"), #(u"Free Range", u"http://www.gocomics.com/freerange"),
# (u"Gil Thorp", u"http://www.gocomics.com/gilthorp"), #(u"Frog Applause", u"http://www.gocomics.com/frogapplause"),
# (u"Ginger Meggs", u"http://www.gocomics.com/gingermeggs"), #(u"Garfield Minus Garfield", u"http://www.gocomics.com/garfieldminusgarfield"),
# (u"Girls & Sports", u"http://www.gocomics.com/girlsandsports"), (u"Garfield", u"http://www.gocomics.com/garfield"),
# (u"Haiku Ewe", u"http://www.gocomics.com/haikuewe"), #(u"Gasoline Alley", u"http://www.gocomics.com/gasolinealley"),
# (u"Heart of the City", u"http://www.gocomics.com/heartofthecity"), #(u"Geech Classics", u"http://www.gocomics.com/geechclassics"),
# (u"Heathcliff", u"http://www.gocomics.com/heathcliff"), #(u"Get Fuzzy", u"http://www.gocomics.com/getfuzzy"),
# (u"Herb and Jamaal", u"http://www.gocomics.com/herbandjamaal"), #(u"Gil Thorp", u"http://www.gocomics.com/gilthorp"),
# (u"Home and Away", u"http://www.gocomics.com/homeandaway"), #(u"Ginger Meggs", u"http://www.gocomics.com/gingermeggs"),
# (u"Housebroken", u"http://www.gocomics.com/housebroken"), #(u"Girls & Sports", u"http://www.gocomics.com/girlsandsports"),
# (u"Hubert and Abby", u"http://www.gocomics.com/hubertandabby"), #(u"Graffiti", u"http://www.gocomics.com/graffiti"),
# (u"Imagine This", u"http://www.gocomics.com/imaginethis"), #(u"Grand Avenue", u"http://www.gocomics.com/grandavenue"),
# (u"In the Bleachers", u"http://www.gocomics.com/inthebleachers"), #(u"Haiku Ewe", u"http://www.gocomics.com/haikuewe"),
# (u"In the Sticks", u"http://www.gocomics.com/inthesticks"), #(u"Heart of the City", u"http://www.gocomics.com/heartofthecity"),
# (u"Ink Pen", u"http://www.gocomics.com/inkpen"), (u"Heathcliff", u"http://www.gocomics.com/heathcliff"),
# (u"It's All About You", u"http://www.gocomics.com/itsallaboutyou"), #(u"Herb and Jamaal", u"http://www.gocomics.com/herbandjamaal"),
# (u"Joe Vanilla", u"http://www.gocomics.com/joevanilla"), #(u"Herman", u"http://www.gocomics.com/herman"),
# (u"La Cucaracha", u"http://www.gocomics.com/lacucaracha"), #(u"Home and Away", u"http://www.gocomics.com/homeandaway"),
# (u"Last Kiss", u"http://www.gocomics.com/lastkiss"), #(u"Housebroken", u"http://www.gocomics.com/housebroken"),
# (u"Legend of Bill", u"http://www.gocomics.com/legendofbill"), #(u"Hubert and Abby", u"http://www.gocomics.com/hubertandabby"),
# (u"Liberty Meadows", u"http://www.gocomics.com/libertymeadows"), #(u"Imagine This", u"http://www.gocomics.com/imaginethis"),
(u"Lio", u"http://www.gocomics.com/lio"), #(u"In the Bleachers", u"http://www.gocomics.com/inthebleachers"),
# (u"Little Dog Lost", u"http://www.gocomics.com/littledoglost"), #(u"In the Sticks", u"http://www.gocomics.com/inthesticks"),
# (u"Little Otto", u"http://www.gocomics.com/littleotto"), #(u"Ink Pen", u"http://www.gocomics.com/inkpen"),
# (u"Loose Parts", u"http://www.gocomics.com/looseparts"), #(u"It's All About You", u"http://www.gocomics.com/itsallaboutyou"),
# (u"Love Is...", u"http://www.gocomics.com/loveis"), #(u"Jane's World", u"http://www.gocomics.com/janesworld"),
# (u"Maintaining", u"http://www.gocomics.com/maintaining"), #(u"Joe Vanilla", u"http://www.gocomics.com/joevanilla"),
# (u"The Meaning of Lila", u"http://www.gocomics.com/meaningoflila"), #(u"Jump Start", u"http://www.gocomics.com/jumpstart"),
# (u"Middle-Aged White Guy", u"http://www.gocomics.com/middleagedwhiteguy"), #(u"Kit 'N' Carlyle", u"http://www.gocomics.com/kitandcarlyle"),
# (u"The Middletons", u"http://www.gocomics.com/themiddletons"), #(u"La Cucaracha", u"http://www.gocomics.com/lacucaracha"),
# (u"Momma", u"http://www.gocomics.com/momma"), #(u"Last Kiss", u"http://www.gocomics.com/lastkiss"),
# (u"Mutt & Jeff", u"http://www.gocomics.com/muttandjeff"), #(u"Legend of Bill", u"http://www.gocomics.com/legendofbill"),
# (u"Mythtickle", u"http://www.gocomics.com/mythtickle"), #(u"Liberty Meadows", u"http://www.gocomics.com/libertymeadows"),
# (u"Nest Heads", u"http://www.gocomics.com/nestheads"), #(u"Li'l Abner Classics", u"http://www.gocomics.com/lilabnerclassics"),
# (u"NEUROTICA", u"http://www.gocomics.com/neurotica"), #(u"Lio", u"http://www.gocomics.com/lio"),
(u"New Adventures of Queen Victoria", u"http://www.gocomics.com/thenewadventuresofqueenvictoria"), #(u"Little Dog Lost", u"http://www.gocomics.com/littledoglost"),
(u"Non Sequitur", u"http://www.gocomics.com/nonsequitur"), #(u"Little Otto", u"http://www.gocomics.com/littleotto"),
# (u"The Norm", u"http://www.gocomics.com/thenorm"), #(u"Lola", u"http://www.gocomics.com/lola"),
# (u"On A Claire Day", u"http://www.gocomics.com/onaclaireday"), #(u"Loose Parts", u"http://www.gocomics.com/looseparts"),
# (u"One Big Happy", u"http://www.gocomics.com/onebighappy"), #(u"Love Is...", u"http://www.gocomics.com/loveis"),
# (u"The Other Coast", u"http://www.gocomics.com/theothercoast"), #(u"Luann", u"http://www.gocomics.com/luann"),
# (u"Out of the Gene Pool Re-Runs", u"http://www.gocomics.com/outofthegenepool"), #(u"Maintaining", u"http://www.gocomics.com/maintaining"),
# (u"Overboard", u"http://www.gocomics.com/overboard"), (u"Marmaduke", u"http://www.gocomics.com/marmaduke"),
# (u"Pibgorn", u"http://www.gocomics.com/pibgorn"), #(u"Meg! Classics", u"http://www.gocomics.com/megclassics"),
# (u"Pibgorn Sketches", u"http://www.gocomics.com/pibgornsketches"), #(u"Middle-Aged White Guy", u"http://www.gocomics.com/middleagedwhiteguy"),
(u"Pickles", u"http://www.gocomics.com/pickles"), #(u"Minimum Security", u"http://www.gocomics.com/minimumsecurity"),
# (u"Pinkerton", u"http://www.gocomics.com/pinkerton"), #(u"Moderately Confused", u"http://www.gocomics.com/moderatelyconfused"),
# (u"Pluggers", u"http://www.gocomics.com/pluggers"), (u"Momma", u"http://www.gocomics.com/momma"),
(u"Pooch Cafe", u"http://www.gocomics.com/poochcafe"), #(u"Monty", u"http://www.gocomics.com/monty"),
# (u"PreTeena", u"http://www.gocomics.com/preteena"), #(u"Motley Classics", u"http://www.gocomics.com/motleyclassics"),
# (u"The Quigmans", u"http://www.gocomics.com/thequigmans"), (u"Mutt & Jeff", u"http://www.gocomics.com/muttandjeff"),
# (u"Rabbits Against Magic", u"http://www.gocomics.com/rabbitsagainstmagic"), #(u"Mythtickle", u"http://www.gocomics.com/mythtickle"),
(u"Real Life Adventures", u"http://www.gocomics.com/reallifeadventures"), #(u"Nancy", u"http://www.gocomics.com/nancy"),
# (u"Red and Rover", u"http://www.gocomics.com/redandrover"), #(u"Natural Selection", u"http://www.gocomics.com/naturalselection"),
# (u"Red Meat", u"http://www.gocomics.com/redmeat"), #(u"Nest Heads", u"http://www.gocomics.com/nestheads"),
# (u"Reynolds Unwrapped", u"http://www.gocomics.com/reynoldsunwrapped"), #(u"NEUROTICA", u"http://www.gocomics.com/neurotica"),
# (u"Ronaldinho Gaucho", u"http://www.gocomics.com/ronaldinhogaucho"), #(u"New Adventures of Queen Victoria", u"http://www.gocomics.com/thenewadventuresofqueenvictoria"),
# (u"Rubes", u"http://www.gocomics.com/rubes"), #(u"Non Sequitur", u"http://www.gocomics.com/nonsequitur"),
# (u"Scary Gary", u"http://www.gocomics.com/scarygary"), #(u"Off The Mark", u"http://www.gocomics.com/offthemark"),
(u"Shoe", u"http://www.gocomics.com/shoe"), #(u"On A Claire Day", u"http://www.gocomics.com/onaclaireday"),
# (u"Shoecabbage", u"http://www.gocomics.com/shoecabbage"), #(u"One Big Happy Classics", u"http://www.gocomics.com/onebighappyclassics"),
# (u"Skin Horse", u"http://www.gocomics.com/skinhorse"), #(u"One Big Happy", u"http://www.gocomics.com/onebighappy"),
# (u"Slowpoke", u"http://www.gocomics.com/slowpoke"), #(u"Out of the Gene Pool Re-Runs", u"http://www.gocomics.com/outofthegenepool"),
# (u"Speed Bump", u"http://www.gocomics.com/speedbump"), #(u"Over the Hedge", u"http://www.gocomics.com/overthehedge"),
# (u"State of the Union", u"http://www.gocomics.com/stateoftheunion"), #(u"Overboard", u"http://www.gocomics.com/overboard"),
(u"Stone Soup", u"http://www.gocomics.com/stonesoup"), #(u"PC and Pixel", u"http://www.gocomics.com/pcandpixel"),
# (u"Strange Brew", u"http://www.gocomics.com/strangebrew"), (u"Peanuts", u"http://www.gocomics.com/peanuts"),
# (u"Sylvia", u"http://www.gocomics.com/sylvia"), #(u"Pearls Before Swine", u"http://www.gocomics.com/pearlsbeforeswine"),
# (u"Tank McNamara", u"http://www.gocomics.com/tankmcnamara"), #(u"Pibgorn Sketches", u"http://www.gocomics.com/pibgornsketches"),
# (u"Tiny Sepuku", u"http://www.gocomics.com/tinysepuku"), #(u"Pibgorn", u"http://www.gocomics.com/pibgorn"),
# (u"TOBY", u"http://www.gocomics.com/toby"), (u"Pickles", u"http://www.gocomics.com/pickles"),
# (u"Tom the Dancing Bug", u"http://www.gocomics.com/tomthedancingbug"), #(u"Pinkerton", u"http://www.gocomics.com/pinkerton"),
# (u"Too Much Coffee Man", u"http://www.gocomics.com/toomuchcoffeeman"), #(u"Pluggers", u"http://www.gocomics.com/pluggers"),
# (u"W.T. Duck", u"http://www.gocomics.com/wtduck"), #(u"Pooch Cafe", u"http://www.gocomics.com/poochcafe"),
# (u"Watch Your Head", u"http://www.gocomics.com/watchyourhead"), #(u"PreTeena", u"http://www.gocomics.com/preteena"),
# (u"Wee Pals", u"http://www.gocomics.com/weepals"), #(u"Prickly City", u"http://www.gocomics.com/pricklycity"),
# (u"Winnie the Pooh", u"http://www.gocomics.com/winniethepooh"), #(u"Rabbits Against Magic", u"http://www.gocomics.com/rabbitsagainstmagic"),
(u"Wizard of Id", u"http://www.gocomics.com/wizardofid"), #(u"Raising Duncan Classics", u"http://www.gocomics.com/raisingduncanclassics"),
# (u"Working It Out", u"http://www.gocomics.com/workingitout"), #(u"Real Life Adventures", u"http://www.gocomics.com/reallifeadventures"),
# (u"Yenny", u"http://www.gocomics.com/yenny"), #(u"Reality Check", u"http://www.gocomics.com/realitycheck"),
# (u"Zack Hill", u"http://www.gocomics.com/zackhill"), #(u"Red and Rover", u"http://www.gocomics.com/redandrover"),
(u"Ziggy", u"http://www.gocomics.com/ziggy"), #(u"Red Meat", u"http://www.gocomics.com/redmeat"),
######## COMICS - EDITORIAL ######## #(u"Reynolds Unwrapped", u"http://www.gocomics.com/reynoldsunwrapped"),
("Lalo Alcaraz","http://www.gocomics.com/laloalcaraz"), #(u"Rip Haywire", u"http://www.gocomics.com/riphaywire"),
("Nick Anderson","http://www.gocomics.com/nickanderson"), #(u"Ripley's Believe It or Not!", u"http://www.gocomics.com/ripleysbelieveitornot"),
("Chuck Asay","http://www.gocomics.com/chuckasay"), #(u"Ronaldinho Gaucho", u"http://www.gocomics.com/ronaldinhogaucho"),
("Tony Auth","http://www.gocomics.com/tonyauth"), #(u"Rose Is Rose", u"http://www.gocomics.com/roseisrose"),
("Donna Barstow","http://www.gocomics.com/donnabarstow"), #(u"Rubes", u"http://www.gocomics.com/rubes"),
# ("Bruce Beattie","http://www.gocomics.com/brucebeattie"), #(u"Rudy Park", u"http://www.gocomics.com/rudypark"),
# ("Clay Bennett","http://www.gocomics.com/claybennett"), #(u"Scary Gary", u"http://www.gocomics.com/scarygary"),
# ("Lisa Benson","http://www.gocomics.com/lisabenson"), #(u"Shirley and Son Classics", u"http://www.gocomics.com/shirleyandsonclassics"),
# ("Steve Benson","http://www.gocomics.com/stevebenson"), #(u"Shoe", u"http://www.gocomics.com/shoe"),
# ("Chip Bok","http://www.gocomics.com/chipbok"), #(u"Shoecabbage", u"http://www.gocomics.com/shoecabbage"),
# ("Steve Breen","http://www.gocomics.com/stevebreen"), #(u"Skin Horse", u"http://www.gocomics.com/skinhorse"),
# ("Chris Britt","http://www.gocomics.com/chrisbritt"), #(u"Slowpoke", u"http://www.gocomics.com/slowpoke"),
# ("Stuart Carlson","http://www.gocomics.com/stuartcarlson"), #(u"Soup To Nutz", u"http://www.gocomics.com/souptonutz"),
# ("Ken Catalino","http://www.gocomics.com/kencatalino"), #(u"Speed Bump", u"http://www.gocomics.com/speedbump"),
# ("Paul Conrad","http://www.gocomics.com/paulconrad"), #(u"Spot The Frog", u"http://www.gocomics.com/spotthefrog"),
# ("Jeff Danziger","http://www.gocomics.com/jeffdanziger"), #(u"State of the Union", u"http://www.gocomics.com/stateoftheunion"),
# ("Matt Davies","http://www.gocomics.com/mattdavies"), #(u"Stone Soup", u"http://www.gocomics.com/stonesoup"),
# ("John Deering","http://www.gocomics.com/johndeering"), #(u"Strange Brew", u"http://www.gocomics.com/strangebrew"),
# ("Bob Gorrell","http://www.gocomics.com/bobgorrell"), #(u"Sylvia", u"http://www.gocomics.com/sylvia"),
# ("Walt Handelsman","http://www.gocomics.com/walthandelsman"), #(u"Tank McNamara", u"http://www.gocomics.com/tankmcnamara"),
# ("Clay Jones","http://www.gocomics.com/clayjones"), #(u"Tarzan Classics", u"http://www.gocomics.com/tarzanclassics"),
# ("Kevin Kallaugher","http://www.gocomics.com/kevinkallaugher"), #(u"That's Life", u"http://www.gocomics.com/thatslife"),
# ("Steve Kelley","http://www.gocomics.com/stevekelley"), #(u"The Academia Waltz", u"http://www.gocomics.com/academiawaltz"),
# ("Dick Locher","http://www.gocomics.com/dicklocher"), #(u"The Argyle Sweater", u"http://www.gocomics.com/theargylesweater"),
# ("Chan Lowe","http://www.gocomics.com/chanlowe"), #(u"The Barn", u"http://www.gocomics.com/thebarn"),
# ("Mike Luckovich","http://www.gocomics.com/mikeluckovich"), #(u"The Boiling Point", u"http://www.gocomics.com/theboilingpoint"),
# ("Gary Markstein","http://www.gocomics.com/garymarkstein"), #(u"The Boondocks", u"http://www.gocomics.com/boondocks"),
# ("Glenn McCoy","http://www.gocomics.com/glennmccoy"), #(u"The Born Loser", u"http://www.gocomics.com/thebornloser"),
# ("Jim Morin","http://www.gocomics.com/jimmorin"), #(u"The Buckets", u"http://www.gocomics.com/thebuckets"),
# ("Jack Ohman","http://www.gocomics.com/jackohman"), #(u"The City", u"http://www.gocomics.com/thecity"),
# ("Pat Oliphant","http://www.gocomics.com/patoliphant"), #(u"The Dinette Set", u"http://www.gocomics.com/dinetteset"),
# ("Joel Pett","http://www.gocomics.com/joelpett"), #(u"The Doozies", u"http://www.gocomics.com/thedoozies"),
# ("Ted Rall","http://www.gocomics.com/tedrall"), #(u"The Duplex", u"http://www.gocomics.com/duplex"),
# ("Michael Ramirez","http://www.gocomics.com/michaelramirez"), #(u"The Elderberries", u"http://www.gocomics.com/theelderberries"),
# ("Marshall Ramsey","http://www.gocomics.com/marshallramsey"), #(u"The Flying McCoys", u"http://www.gocomics.com/theflyingmccoys"),
# ("Steve Sack","http://www.gocomics.com/stevesack"), #(u"The Fusco Brothers", u"http://www.gocomics.com/thefuscobrothers"),
# ("Ben Sargent","http://www.gocomics.com/bensargent"), #(u"The Grizzwells", u"http://www.gocomics.com/thegrizzwells"),
# ("Drew Sheneman","http://www.gocomics.com/drewsheneman"), #(u"The Humble Stumble", u"http://www.gocomics.com/thehumblestumble"),
# ("John Sherffius","http://www.gocomics.com/johnsherffius"), #(u"The Knight Life", u"http://www.gocomics.com/theknightlife"),
# ("Small World","http://www.gocomics.com/smallworld"), #(u"The Meaning of Lila", u"http://www.gocomics.com/meaningoflila"),
# ("Scott Stantis","http://www.gocomics.com/scottstantis"), #(u"The Middletons", u"http://www.gocomics.com/themiddletons"),
# ("Wayne Stayskal","http://www.gocomics.com/waynestayskal"), #(u"The Norm", u"http://www.gocomics.com/thenorm"),
# ("Dana Summers","http://www.gocomics.com/danasummers"), #(u"The Other Coast", u"http://www.gocomics.com/theothercoast"),
# ("Paul Szep","http://www.gocomics.com/paulszep"), #(u"The Quigmans", u"http://www.gocomics.com/thequigmans"),
# ("Mike Thompson","http://www.gocomics.com/mikethompson"), #(u"The Sunshine Club", u"http://www.gocomics.com/thesunshineclub"),
# ("Tom Toles","http://www.gocomics.com/tomtoles"), #(u"Tiny Sepuk", u"http://www.gocomics.com/tinysepuk"),
# ("Gary Varvel","http://www.gocomics.com/garyvarvel"), #(u"TOBY", u"http://www.gocomics.com/toby"),
# ("ViewsAfrica","http://www.gocomics.com/viewsafrica"), #(u"Tom the Dancing Bug", u"http://www.gocomics.com/tomthedancingbug"),
# ("ViewsAmerica","http://www.gocomics.com/viewsamerica"), #(u"Too Much Coffee Man", u"http://www.gocomics.com/toomuchcoffeeman"),
# ("ViewsAsia","http://www.gocomics.com/viewsasia"), #(u"Unstrange Phenomena", u"http://www.gocomics.com/unstrangephenomena"),
# ("ViewsBusiness","http://www.gocomics.com/viewsbusiness"), #(u"W.T. Duck", u"http://www.gocomics.com/wtduck"),
# ("ViewsEurope","http://www.gocomics.com/viewseurope"), #(u"Watch Your Head", u"http://www.gocomics.com/watchyourhead"),
# ("ViewsLatinAmerica","http://www.gocomics.com/viewslatinamerica"), #(u"Wee Pals", u"http://www.gocomics.com/weepals"),
# ("ViewsMidEast","http://www.gocomics.com/viewsmideast"), #(u"Winnie the Pooh", u"http://www.gocomics.com/winniethepooh"),
# ("Views of the World","http://www.gocomics.com/viewsoftheworld"), #(u"Wizard of Id", u"http://www.gocomics.com/wizardofid"),
# ("Kerry Waghorn","http://www.gocomics.com/facesinthenews"), #(u"Working Daze", u"http://www.gocomics.com/workingdaze"),
# ("Dan Wasserman","http://www.gocomics.com/danwasserman"), #(u"Working It Out", u"http://www.gocomics.com/workingitout"),
# ("Signe Wilkinson","http://www.gocomics.com/signewilkinson"), #(u"Yenny", u"http://www.gocomics.com/yenny"),
# ("Wit of the World","http://www.gocomics.com/witoftheworld"), #(u"Zack Hill", u"http://www.gocomics.com/zackhill"),
# ("Don Wright","http://www.gocomics.com/donwright"), (u"Ziggy", u"http://www.gocomics.com/ziggy"),
#
######## EDITORIAL CARTOONS #####################
(u"Adam Zyglis", u"http://www.gocomics.com/adamzyglis"),
#(u"Andy Singer", u"http://www.gocomics.com/andysinger"),
#(u"Ben Sargent",u"http://www.gocomics.com/bensargent"),
#(u"Bill Day", u"http://www.gocomics.com/billday"),
#(u"Bill Schorr", u"http://www.gocomics.com/billschorr"),
#(u"Bob Englehart", u"http://www.gocomics.com/bobenglehart"),
(u"Bob Gorrell",u"http://www.gocomics.com/bobgorrell"),
#(u"Brian Fairrington", u"http://www.gocomics.com/brianfairrington"),
#(u"Bruce Beattie", u"http://www.gocomics.com/brucebeattie"),
#(u"Cam Cardow", u"http://www.gocomics.com/camcardow"),
#(u"Chan Lowe",u"http://www.gocomics.com/chanlowe"),
#(u"Chip Bok",u"http://www.gocomics.com/chipbok"),
#(u"Chris Britt",u"http://www.gocomics.com/chrisbritt"),
#(u"Chuck Asay",u"http://www.gocomics.com/chuckasay"),
#(u"Clay Bennett",u"http://www.gocomics.com/claybennett"),
#(u"Clay Jones",u"http://www.gocomics.com/clayjones"),
#(u"Dan Wasserman",u"http://www.gocomics.com/danwasserman"),
#(u"Dana Summers",u"http://www.gocomics.com/danasummers"),
#(u"Daryl Cagle", u"http://www.gocomics.com/darylcagle"),
#(u"David Fitzsimmons", u"http://www.gocomics.com/davidfitzsimmons"),
(u"Dick Locher",u"http://www.gocomics.com/dicklocher"),
#(u"Don Wright",u"http://www.gocomics.com/donwright"),
#(u"Donna Barstow",u"http://www.gocomics.com/donnabarstow"),
#(u"Drew Litton", u"http://www.gocomics.com/drewlitton"),
#(u"Drew Sheneman",u"http://www.gocomics.com/drewsheneman"),
#(u"Ed Stein", u"http://www.gocomics.com/edstein"),
#(u"Eric Allie", u"http://www.gocomics.com/ericallie"),
#(u"Gary Markstein", u"http://www.gocomics.com/garymarkstein"),
#(u"Gary McCoy", u"http://www.gocomics.com/garymccoy"),
#(u"Gary Varvel", u"http://www.gocomics.com/garyvarvel"),
#(u"Glenn McCoy",u"http://www.gocomics.com/glennmccoy"),
#(u"Henry Payne", u"http://www.gocomics.com/henrypayne"),
#(u"Jack Ohman",u"http://www.gocomics.com/jackohman"),
#(u"JD Crowe", u"http://www.gocomics.com/jdcrowe"),
#(u"Jeff Danziger",u"http://www.gocomics.com/jeffdanziger"),
#(u"Jeff Parker", u"http://www.gocomics.com/jeffparker"),
#(u"Jeff Stahler", u"http://www.gocomics.com/jeffstahler"),
#(u"Jerry Holbert", u"http://www.gocomics.com/jerryholbert"),
#(u"Jim Morin",u"http://www.gocomics.com/jimmorin"),
#(u"Joel Pett",u"http://www.gocomics.com/joelpett"),
#(u"John Cole", u"http://www.gocomics.com/johncole"),
#(u"John Darkow", u"http://www.gocomics.com/johndarkow"),
#(u"John Deering",u"http://www.gocomics.com/johndeering"),
#(u"John Sherffius", u"http://www.gocomics.com/johnsherffius"),
#(u"Ken Catalino",u"http://www.gocomics.com/kencatalino"),
#(u"Kerry Waghorn",u"http://www.gocomics.com/facesinthenews"),
#(u"Kevin Kallaugher",u"http://www.gocomics.com/kevinkallaugher"),
#(u"Lalo Alcaraz",u"http://www.gocomics.com/laloalcaraz"),
#(u"Larry Wright", u"http://www.gocomics.com/larrywright"),
#(u"Lisa Benson", u"http://www.gocomics.com/lisabenson"),
#(u"Marshall Ramsey", u"http://www.gocomics.com/marshallramsey"),
#(u"Matt Bors", u"http://www.gocomics.com/mattbors"),
#(u"Matt Davies",u"http://www.gocomics.com/mattdavies"),
#(u"Michael Ramirez", u"http://www.gocomics.com/michaelramirez"),
#(u"Mike Keefe", u"http://www.gocomics.com/mikekeefe"),
#(u"Mike Luckovich", u"http://www.gocomics.com/mikeluckovich"),
#(u"MIke Thompson", u"http://www.gocomics.com/mikethompson"),
#(u"Monte Wolverton", u"http://www.gocomics.com/montewolverton"),
#(u"Mr. Fish", u"http://www.gocomics.com/mrfish"),
#(u"Nate Beeler", u"http://www.gocomics.com/natebeeler"),
#(u"Nick Anderson", u"http://www.gocomics.com/nickanderson"),
#(u"Pat Bagley", u"http://www.gocomics.com/patbagley"),
#(u"Pat Oliphant",u"http://www.gocomics.com/patoliphant"),
#(u"Paul Conrad",u"http://www.gocomics.com/paulconrad"),
#(u"Paul Szep", u"http://www.gocomics.com/paulszep"),
#(u"RJ Matson", u"http://www.gocomics.com/rjmatson"),
#(u"Rob Rogers", u"http://www.gocomics.com/robrogers"),
#(u"Robert Ariail", u"http://www.gocomics.com/robertariail"),
#(u"Scott Stantis", u"http://www.gocomics.com/scottstantis"),
#(u"Signe Wilkinson", u"http://www.gocomics.com/signewilkinson"),
#(u"Small World",u"http://www.gocomics.com/smallworld"),
#(u"Steve Benson", u"http://www.gocomics.com/stevebenson"),
#(u"Steve Breen", u"http://www.gocomics.com/stevebreen"),
#(u"Steve Kelley", u"http://www.gocomics.com/stevekelley"),
#(u"Steve Sack", u"http://www.gocomics.com/stevesack"),
#(u"Stuart Carlson",u"http://www.gocomics.com/stuartcarlson"),
#(u"Ted Rall",u"http://www.gocomics.com/tedrall"),
#(u"(Th)ink", u"http://www.gocomics.com/think"),
#(u"Tom Toles",u"http://www.gocomics.com/tomtoles"),
(u"Tony Auth",u"http://www.gocomics.com/tonyauth"),
#(u"Views of the World",u"http://www.gocomics.com/viewsoftheworld"),
#(u"ViewsAfrica",u"http://www.gocomics.com/viewsafrica"),
#(u"ViewsAmerica",u"http://www.gocomics.com/viewsamerica"),
#(u"ViewsAsia",u"http://www.gocomics.com/viewsasia"),
#(u"ViewsBusiness",u"http://www.gocomics.com/viewsbusiness"),
#(u"ViewsEurope",u"http://www.gocomics.com/viewseurope"),
#(u"ViewsLatinAmerica",u"http://www.gocomics.com/viewslatinamerica"),
#(u"ViewsMidEast",u"http://www.gocomics.com/viewsmideast"),
(u"Walt Handelsman",u"http://www.gocomics.com/walthandelsman"),
#(u"Wayne Stayskal",u"http://www.gocomics.com/waynestayskal"),
#(u"Wit of the World",u"http://www.gocomics.com/witoftheworld"),
]: ]:
print 'Working on: ', title print 'Working on: ', title
articles = self.make_links(url) articles = self.make_links(url)
@ -352,3 +445,4 @@ class GoComics(BasicNewsRecipe):
p{font-family:Arial,Helvetica,sans-serif;font-size:small;} p{font-family:Arial,Helvetica,sans-serif;font-size:small;}
body{font-family:Helvetica,Arial,sans-serif;font-size:small;} body{font-family:Helvetica,Arial,sans-serif;font-size:small;}
''' '''

View File

@ -1,5 +1,5 @@
__license__ = 'GPL v3' __license__ = 'GPL v3'
__copyright__ = '2008-2010, Darko Miletic <darko.miletic at gmail.com>' __copyright__ = '2008-2011, Darko Miletic <darko.miletic at gmail.com>'
''' '''
mondediplo.com mondediplo.com
''' '''
@ -11,7 +11,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
class LeMondeDiplomatiqueEn(BasicNewsRecipe): class LeMondeDiplomatiqueEn(BasicNewsRecipe):
title = 'Le Monde diplomatique - English edition' title = 'Le Monde diplomatique - English edition'
__author__ = 'Darko Miletic' __author__ = 'Darko Miletic'
description = 'Real journalism making sense of the world around us' description = "Le Monde diplomatique is the place you go when you want to know what's really happening. This is a major international paper that is truly independent, that sees the world in fresh ways, that focuses on places no other publications reach. We offer a clear, considered view of the conflicting interests and complexities of a modern global world. LMD in English is a concise version of the Paris-based parent edition, publishing all the major stories each month, expertly translated, and with some London-based commissions too. We offer a taster of LMD quality on our website where a selection of articles are available each month."
publisher = 'Le Monde diplomatique' publisher = 'Le Monde diplomatique'
category = 'news, politics, world' category = 'news, politics, world'
no_stylesheets = True no_stylesheets = True
@ -26,13 +26,19 @@ class LeMondeDiplomatiqueEn(BasicNewsRecipe):
INDEX = PREFIX + strftime('%Y/%m/') INDEX = PREFIX + strftime('%Y/%m/')
use_embedded_content = False use_embedded_content = False
language = 'en' language = 'en'
extra_css = ' body{font-family: "Luxi sans","Lucida sans","Lucida Grande",Lucida,"Lucida Sans Unicode",sans-serif} .surtitre{font-size: 1.2em; font-variant: small-caps; margin-bottom: 0.5em} .chapo{font-size: 1.2em; font-weight: bold; margin: 1em 0 0.5em} .texte{font-family: Georgia,"Times New Roman",serif} h1{color: #990000} .notes{border-top: 1px solid #CCCCCC; font-size: 0.9em; line-height: 1.4em} ' extra_css = """
body{font-family: "Luxi sans","Lucida sans","Lucida Grande",Lucida,"Lucida Sans Unicode",sans-serif}
.surtitre{font-size: 1.2em; font-variant: small-caps; margin-bottom: 0.5em}
.chapo{font-size: 1.2em; font-weight: bold; margin: 1em 0 0.5em}
.texte{font-family: Georgia,"Times New Roman",serif} h1{color: #990000}
.notes{border-top: 1px solid #CCCCCC; font-size: 0.9em; line-height: 1.4em}
"""
conversion_options = { conversion_options = {
'comment' : description 'comment' : description
, 'tags' : category , 'tags' : category
, 'publisher' : publisher , 'publisher' : publisher
, 'language' : language , 'language' : language
} }
def get_browser(self): def get_browser(self):
@ -46,12 +52,12 @@ class LeMondeDiplomatiqueEn(BasicNewsRecipe):
br.open(self.LOGIN,data) br.open(self.LOGIN,data)
return br return br
keep_only_tags =[ keep_only_tags =[
dict(name='div', attrs={'id':'contenu'}) dict(name='div', attrs={'id':'contenu'})
, dict(name='div',attrs={'class':'notes surlignable'}) , dict(name='div',attrs={'class':'notes surlignable'})
] ]
remove_tags = [dict(name=['object','link','script','iframe','base'])] remove_tags = [dict(name=['object','link','script','iframe','base'])]
remove_attributes = ['height','width'] remove_attributes = ['height','width','name','lang']
def parse_index(self): def parse_index(self):
articles = [] articles = []
@ -75,3 +81,24 @@ class LeMondeDiplomatiqueEn(BasicNewsRecipe):
}) })
return [(self.title, articles)] return [(self.title, articles)]
def get_cover_url(self):
cover_url = None
soup = self.index_to_soup(self.INDEX)
cover_item = soup.find('div',attrs={'class':'current'})
if cover_item:
ap = cover_item.find('img',attrs={'class':'spip_logos'})
if ap:
cover_url = self.INDEX + ap['src']
return cover_url
def preprocess_html(self, soup):
for item in soup.findAll(style=True):
del item['style']
for item in soup.findAll('a'):
if item.string is not None:
str = item.string
item.replaceWith(str)
else:
str = self.tag_to_string(item)
item.replaceWith(str)
return soup

View File

@ -0,0 +1,45 @@
from calibre.web.feeds.news import BasicNewsRecipe
class AdvancedUserRecipe1306097511(BasicNewsRecipe):
title = u'Metro Nieuws NL'
oldest_article = 2
max_articles_per_feed = 100
__author__ = u'DrMerry'
description = u'Metro Nederland'
language = u'nl'
simultaneous_downloads = 5
delay = 1
# timefmt = ' [%A, %d %B, %Y]'
timefmt = ''
no_stylesheets = True
remove_javascript = True
remove_empty_feeds = True
cover_url = 'http://www.readmetro.com/img/en/metroholland/last/1/small.jpg'
remove_empty_feeds = True
publication_type = 'newspaper'
remove_tags_before = dict(name='div', attrs={'id':'date'})
remove_tags_after = dict(name='div', attrs={'id':'column-1-3'})
encoding = 'utf-8'
extra_css = '#date {font-size: 10px} .article-image-caption {font-size: 8px}'
remove_tags = [dict(name='div', attrs={'class':[ 'metroCommentFormWrap',
'commentForm', 'metroCommentInnerWrap', 'article-slideshow-counter-container', 'article-slideshow-control', 'ad', 'header-links',
'art-rgt','pluck-app pluck-comm', 'share-and-byline', 'article-tools-below-title', 'col-179 ', 'related-links', 'clear padding-top-15', 'share-tools', 'article-page-auto-pushes', 'footer-edit']}),
dict(name='div', attrs={'id':['article-2', 'article-4', 'article-1', 'navigation', 'footer', 'header', 'comments', 'sidebar']}),
dict(name='iframe')]
feeds = [
(u'Binnenland', u'http://www.metronieuws.nl/rss.xml?c=1277377288-3'),
(u'Economie', u'http://www.metronieuws.nl/rss.xml?c=1278070988-0'),
(u'Den Haag', u'http://www.metronieuws.nl/rss.xml?c=1289013337-3'),
(u'Rotterdam', u'http://www.metronieuws.nl/rss.xml?c=1289013337-2'),
(u'Amsterdam', u'http://www.metronieuws.nl/rss.xml?c=1289013337-1'),
(u'Columns', u'http://www.metronieuws.nl/rss.xml?c=1277377288-17'),
(u'Entertainment', u'http://www.metronieuws.nl/rss.xml?c=1277377288-2'),
(u'Dot', u'http://www.metronieuws.nl/rss.xml?c=1283166782-12'),
(u'Familie', u'http://www.metronieuws.nl/rss.xml?c=1283166782-9'),
(u'Blogs', u'http://www.metronieuws.nl/rss.xml?c=1295586825-6'),
(u'Reizen', u'http://www.metronieuws.nl/rss.xml?c=1277377288-13'),
(u'Carrière', u'http://www.metronieuws.nl/rss.xml?c=1278070988-1'),
(u'Sport', u'http://www.metronieuws.nl/rss.xml?c=1277377288-12')
]

View File

@ -8,7 +8,7 @@ __docformat__ = 'restructuredtext en'
import os, shutil, subprocess import os, shutil, subprocess
from setup import Command, __appname__ from setup import Command, __appname__, __version__
from setup.installer import VMInstaller from setup.installer import VMInstaller
class Win(Command): class Win(Command):
@ -43,4 +43,11 @@ class Win32(VMInstaller):
self.warn('Failed to freeze') self.warn('Failed to freeze')
raise SystemExit(1) raise SystemExit(1)
installer = 'dist/%s-portable-%s.zip'%(__appname__, __version__)
subprocess.check_call(('scp',
'xp_build:build/%s/%s'%(__appname__, installer), 'dist'))
if not os.path.exists(installer):
self.warn('Failed to get portable installer')
raise SystemExit(1)

View File

@ -50,7 +50,7 @@ def walk(dir):
class Win32Freeze(Command, WixMixIn): class Win32Freeze(Command, WixMixIn):
description = 'Free windows calibre installation' description = 'Freeze windows calibre installation'
def add_options(self, parser): def add_options(self, parser):
parser.add_option('--no-ice', default=False, action='store_true', parser.add_option('--no-ice', default=False, action='store_true',
@ -74,6 +74,8 @@ class Win32Freeze(Command, WixMixIn):
self.pylib = self.j(self.base, 'pylib.zip') self.pylib = self.j(self.base, 'pylib.zip')
self.dll_dir = self.j(self.base, 'DLLs') self.dll_dir = self.j(self.base, 'DLLs')
self.plugins_dir = os.path.join(self.base, 'plugins2') self.plugins_dir = os.path.join(self.base, 'plugins2')
self.portable_base = self.j(self.d(self.base), 'Calibre Portable')
self.obj_dir = self.j(self.src_root, 'build', 'launcher')
self.initbase() self.initbase()
self.build_launchers() self.build_launchers()
@ -84,6 +86,7 @@ class Win32Freeze(Command, WixMixIn):
self.archive_lib_dir() self.archive_lib_dir()
self.remove_CRT_from_manifests() self.remove_CRT_from_manifests()
self.create_installer() self.create_installer()
self.build_portable()
def remove_CRT_from_manifests(self): def remove_CRT_from_manifests(self):
''' '''
@ -287,7 +290,7 @@ class Win32Freeze(Command, WixMixIn):
def embed_resources(self, module, desc=None): def embed_resources(self, module, desc=None):
icon_base = self.j(self.src_root, 'icons') icon_base = self.j(self.src_root, 'icons')
icon_map = {'calibre':'library', 'ebook-viewer':'viewer', icon_map = {'calibre':'library', 'ebook-viewer':'viewer',
'lrfviewer':'viewer'} 'lrfviewer':'viewer', 'calibre-portable':'library'}
file_type = 'DLL' if module.endswith('.dll') else 'APP' file_type = 'DLL' if module.endswith('.dll') else 'APP'
template = open(self.rc_template, 'rb').read() template = open(self.rc_template, 'rb').read()
bname = self.b(module) bname = self.b(module)
@ -344,8 +347,62 @@ class Win32Freeze(Command, WixMixIn):
self.info(p.stderr.read()) self.info(p.stderr.read())
sys.exit(1) sys.exit(1)
def build_portable(self):
base = self.portable_base
if os.path.exists(base):
shutil.rmtree(base)
os.makedirs(base)
src = self.j(self.src_root, 'setup', 'installer', 'windows',
'portable.c')
obj = self.j(self.obj_dir, self.b(src)+'.obj')
cflags = '/c /EHsc /MT /W3 /Ox /nologo /D_UNICODE'.split()
if self.newer(obj, [src]):
self.info('Compiling', obj)
cmd = [msvc.cc] + cflags + ['/Fo'+obj, '/Tc'+src]
self.run_builder(cmd)
exe = self.j(base, 'calibre-portable.exe')
if self.newer(exe, [obj]):
self.info('Linking', exe)
cmd = [msvc.linker] + ['/INCREMENTAL:NO', '/MACHINE:X86',
'/LIBPATH:'+self.obj_dir, '/SUBSYSTEM:WINDOWS',
'/RELEASE',
'/OUT:'+exe, self.embed_resources(exe),
obj, 'User32.lib']
self.run_builder(cmd)
self.info('Creating portable installer')
shutil.copytree(self.base, self.j(base, 'Calibre'))
os.mkdir(self.j(base, 'Calibre Library'))
os.mkdir(self.j(base, 'Calibre Settings'))
name = '%s-portable-%s.zip'%(__appname__, __version__)
with zipfile.ZipFile(self.j('dist', name), 'w', zipfile.ZIP_DEFLATED) as zf:
self.add_dir_to_zip(zf, base, 'Calibre Portable')
def add_dir_to_zip(self, zf, path, prefix=''):
'''
Add a directory recursively to the zip file with an optional prefix.
'''
if prefix:
zi = zipfile.ZipInfo(prefix+'/')
zi.external_attr = 16
zf.writestr(zi, '')
cwd = os.path.abspath(os.getcwd())
try:
os.chdir(path)
fp = (prefix + ('/' if prefix else '')).replace('//', '/')
for f in os.listdir('.'):
arcname = fp + f
if os.path.isdir(f):
self.add_dir_to_zip(zf, f, prefix=arcname)
else:
zf.write(f, arcname)
finally:
os.chdir(cwd)
def build_launchers(self): def build_launchers(self):
self.obj_dir = self.j(self.src_root, 'build', 'launcher')
if not os.path.exists(self.obj_dir): if not os.path.exists(self.obj_dir):
os.makedirs(self.obj_dir) os.makedirs(self.obj_dir)
base = self.j(self.src_root, 'setup', 'installer', 'windows') base = self.j(self.src_root, 'setup', 'installer', 'windows')

View File

@ -0,0 +1,146 @@
#ifndef UNICODE
#define UNICODE
#endif
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#define BUFSIZE 4096
void show_error(LPCTSTR msg) {
MessageBeep(MB_ICONERROR);
MessageBox(NULL, msg, TEXT("Error"), MB_OK|MB_ICONERROR);
}
void show_detailed_error(LPCTSTR preamble, LPCTSTR msg, int code) {
LPTSTR buf;
buf = (LPTSTR)LocalAlloc(LMEM_ZEROINIT, sizeof(TCHAR)*
(_tcslen(msg) + _tcslen(preamble) + 80));
_sntprintf_s(buf,
LocalSize(buf) / sizeof(TCHAR), _TRUNCATE,
TEXT("%s\r\n %s (Error Code: %d)\r\n"),
preamble, msg, code);
show_error(buf);
LocalFree(buf);
}
void show_last_error_crt(LPCTSTR preamble) {
TCHAR buf[BUFSIZE];
int err = 0;
_get_errno(&err);
_wcserror_s(buf, BUFSIZE, err);
show_detailed_error(preamble, buf, err);
}
void show_last_error(LPCTSTR preamble) {
TCHAR *msg = NULL;
DWORD dw = GetLastError();
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
&msg,
0, NULL );
show_detailed_error(preamble, msg, (int)dw);
}
LPTSTR get_app_dir() {
LPTSTR buf, buf2, buf3;
DWORD sz;
TCHAR drive[4] = TEXT("\0\0\0");
errno_t err;
buf = (LPTSTR)calloc(BUFSIZE, sizeof(TCHAR));
buf2 = (LPTSTR)calloc(BUFSIZE, sizeof(TCHAR));
buf3 = (LPTSTR)calloc(BUFSIZE, sizeof(TCHAR));
sz = GetModuleFileName(NULL, buf, BUFSIZE);
if (sz == 0 || sz > BUFSIZE-1) {
show_error(TEXT("Failed to get path to calibre-portable.exe"));
ExitProcess(1);
}
err = _tsplitpath_s(buf, drive, 4, buf2, BUFSIZE, NULL, 0, NULL, 0);
if (err != 0) {
show_last_error_crt(TEXT("Failed to split path to calibre-portable.exe"));
ExitProcess(1);
}
_sntprintf_s(buf3, BUFSIZE-1, _TRUNCATE, TEXT("%s%s"), drive, buf2);
free(buf); free(buf2);
return buf3;
}
void launch_calibre(LPCTSTR exe, LPCTSTR config_dir, LPCTSTR library_dir) {
DWORD dwFlags=0;
STARTUPINFO si;
PROCESS_INFORMATION pi;
BOOL fSuccess;
TCHAR cmdline[BUFSIZE];
if (! SetEnvironmentVariable(TEXT("CALIBRE_CONFIG_DIRECTORY"), config_dir)) {
show_last_error(TEXT("Failed to set environment variables"));
ExitProcess(1);
}
dwFlags = CREATE_UNICODE_ENVIRONMENT | CREATE_NEW_PROCESS_GROUP;
_sntprintf_s(cmdline, BUFSIZE, _TRUNCATE, TEXT(" \"--with-library=%s\""), library_dir);
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) );
fSuccess = CreateProcess(exe, cmdline,
NULL, // Process handle not inheritable
NULL, // Thread handle not inheritable
FALSE, // Set handle inheritance to FALSE
dwFlags, // Creation flags http://msdn.microsoft.com/en-us/library/ms684863(v=vs.85).aspx
NULL, // Use parent's environment block
NULL, // Use parent's starting directory
&si, // Pointer to STARTUPINFO structure
&pi // Pointer to PROCESS_INFORMATION structure
);
if (fSuccess == 0) {
show_last_error(TEXT("Failed to launch the calibre program"));
}
// Close process and thread handles.
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
}
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
{
LPTSTR app_dir, config_dir, exe, library_dir;
app_dir = get_app_dir();
config_dir = (LPTSTR)calloc(BUFSIZE, sizeof(TCHAR));
library_dir = (LPTSTR)calloc(BUFSIZE, sizeof(TCHAR));
exe = (LPTSTR)calloc(BUFSIZE, sizeof(TCHAR));
_sntprintf_s(config_dir, BUFSIZE, _TRUNCATE, TEXT("%sCalibre Settings"), app_dir);
_sntprintf_s(exe, BUFSIZE, _TRUNCATE, TEXT("%sCalibre\\calibre.exe"), app_dir);
_sntprintf_s(library_dir, BUFSIZE, _TRUNCATE, TEXT("%sCalibre Library"), app_dir);
launch_calibre(exe, config_dir, library_dir);
free(app_dir); free(config_dir); free(exe); free(library_dir);
return 0;
}

View File

@ -26,6 +26,7 @@ def installers():
installers = list(map(installer_name, ('dmg', 'msi', 'tar.bz2'))) installers = list(map(installer_name, ('dmg', 'msi', 'tar.bz2')))
installers.append(installer_name('tar.bz2', is64bit=True)) installers.append(installer_name('tar.bz2', is64bit=True))
installers.insert(0, 'dist/%s-%s.tar.gz'%(__appname__, __version__)) installers.insert(0, 'dist/%s-%s.tar.gz'%(__appname__, __version__))
installers.append('dist/%s-portable-%s.zip'%(__appname__, __version__))
return installers return installers
def installer_description(fname): def installer_description(fname):
@ -38,6 +39,8 @@ def installer_description(fname):
return 'Windows installer' return 'Windows installer'
if fname.endswith('.dmg'): if fname.endswith('.dmg'):
return 'OS X dmg' return 'OS X dmg'
if fname.endswith('.zip'):
return 'Calibre Portable'
return 'Unknown file' return 'Unknown file'
class ReUpload(Command): # {{{ class ReUpload(Command): # {{{
@ -90,9 +93,11 @@ class UploadToGoogleCode(Command): # {{{
def upload_one(self, fname): def upload_one(self, fname):
self.info('Uploading', fname) self.info('Uploading', fname)
typ = 'Type-Source' if fname.endswith('.gz') else 'Type-Installer' typ = 'Type-' + ('Source' if fname.endswith('.gz') else 'Archive' if
fname.endswith('.zip') else 'Installer')
ext = os.path.splitext(fname)[1][1:] ext = os.path.splitext(fname)[1][1:]
op = 'OpSys-'+{'msi':'Windows','dmg':'OSX','bz2':'Linux','gz':'All'}[ext] op = 'OpSys-'+{'msi':'Windows','zip':'Windows',
'dmg':'OSX','bz2':'Linux','gz':'All'}[ext]
desc = installer_description(fname) desc = installer_description(fname)
start = time.time() start = time.time()
path = self.upload(os.path.abspath(fname), desc, path = self.upload(os.path.abspath(fname), desc,

View File

@ -52,6 +52,7 @@ class ANDROID(USBMS):
0x04e8 : { 0x681d : [0x0222, 0x0223, 0x0224, 0x0400], 0x04e8 : { 0x681d : [0x0222, 0x0223, 0x0224, 0x0400],
0x681c : [0x0222, 0x0224, 0x0400], 0x681c : [0x0222, 0x0224, 0x0400],
0x6640 : [0x0100], 0x6640 : [0x0100],
0x685b : [0x0400],
0x685e : [0x0400], 0x685e : [0x0400],
0x6860 : [0x0400], 0x6860 : [0x0400],
0x6877 : [0x0400], 0x6877 : [0x0400],
@ -93,6 +94,9 @@ class ANDROID(USBMS):
# CREEL?? Also Nextbook # CREEL?? Also Nextbook
0x5e3 : { 0x726 : [0x222] }, 0x5e3 : { 0x726 : [0x222] },
# ZTE
0x19d2 : { 0x1353 : [0x226] },
} }
EBOOK_DIR_MAIN = ['eBooks/import', 'wordplayer/calibretransfer', 'Books'] EBOOK_DIR_MAIN = ['eBooks/import', 'wordplayer/calibretransfer', 'Books']
EXTRA_CUSTOMIZATION_MESSAGE = _('Comma separated list of directories to ' EXTRA_CUSTOMIZATION_MESSAGE = _('Comma separated list of directories to '
@ -103,7 +107,7 @@ class ANDROID(USBMS):
VENDOR_NAME = ['HTC', 'MOTOROLA', 'GOOGLE_', 'ANDROID', 'ACER', VENDOR_NAME = ['HTC', 'MOTOROLA', 'GOOGLE_', 'ANDROID', 'ACER',
'GT-I5700', 'SAMSUNG', 'DELL', 'LINUX', 'GOOGLE', 'ARCHOS', 'GT-I5700', 'SAMSUNG', 'DELL', 'LINUX', 'GOOGLE', 'ARCHOS',
'TELECHIP', 'HUAWEI', 'T-MOBILE', 'SEMC', 'LGE', 'NVIDIA', 'TELECHIP', 'HUAWEI', 'T-MOBILE', 'SEMC', 'LGE', 'NVIDIA',
'GENERIC-'] 'GENERIC-', 'ZTE']
WINDOWS_MAIN_MEM = ['ANDROID_PHONE', 'A855', 'A853', 'INC.NEXUS_ONE', WINDOWS_MAIN_MEM = ['ANDROID_PHONE', 'A855', 'A853', 'INC.NEXUS_ONE',
'__UMS_COMPOSITE', '_MB200', 'MASS_STORAGE', '_-_CARD', 'SGH-I897', '__UMS_COMPOSITE', '_MB200', 'MASS_STORAGE', '_-_CARD', 'SGH-I897',
'GT-I9000', 'FILE-STOR_GADGET', 'SGH-T959', 'SAMSUNG_ANDROID', 'GT-I9000', 'FILE-STOR_GADGET', 'SGH-T959', 'SAMSUNG_ANDROID',

View File

@ -11,10 +11,11 @@ from functools import partial
from PyQt4.Qt import QMenu, Qt, QInputDialog, QToolButton from PyQt4.Qt import QMenu, Qt, QInputDialog, QToolButton
from calibre import isbytestring from calibre import isbytestring
from calibre.constants import filesystem_encoding from calibre.constants import filesystem_encoding, iswindows
from calibre.utils.config import prefs from calibre.utils.config import prefs
from calibre.gui2 import gprefs, warning_dialog, Dispatcher, error_dialog, \ from calibre.gui2 import (gprefs, warning_dialog, Dispatcher, error_dialog,
question_dialog, info_dialog question_dialog, info_dialog)
from calibre.library.database2 import LibraryDatabase2
from calibre.gui2.actions import InterfaceAction from calibre.gui2.actions import InterfaceAction
class LibraryUsageStats(object): # {{{ class LibraryUsageStats(object): # {{{
@ -229,6 +230,12 @@ class ChooseLibraryAction(InterfaceAction):
return error_dialog(self.gui, _('Already exists'), return error_dialog(self.gui, _('Already exists'),
_('The folder %s already exists. Delete it first.') % _('The folder %s already exists. Delete it first.') %
newloc, show=True) newloc, show=True)
if (iswindows and len(newloc) >
LibraryDatabase2.WINDOWS_LIBRARY_PATH_LIMIT):
return error_dialog(self.gui, _('Too long'),
_('Path to library too long. Must be less than'
' %d characters.')%LibraryDatabase2.WINDOWS_LIBRARY_PATH_LIMIT,
show=True)
try: try:
os.rename(loc, newloc) os.rename(loc, newloc)
except: except:

View File

@ -33,7 +33,6 @@ class SaveMenu(QMenu): # {{{
# }}} # }}}
class SaveToDiskAction(InterfaceAction): class SaveToDiskAction(InterfaceAction):
name = "Save To Disk" name = "Save To Disk"

View File

@ -58,7 +58,7 @@
<string> KB</string> <string> KB</string>
</property> </property>
<property name="minimum"> <property name="minimum">
<number>100</number> <number>25</number>
</property> </property>
<property name="maximum"> <property name="maximum">
<number>1000000</number> <number>1000000</number>

View File

@ -11,10 +11,11 @@ from PyQt4.Qt import QDialog
from calibre.gui2.dialogs.choose_library_ui import Ui_Dialog from calibre.gui2.dialogs.choose_library_ui import Ui_Dialog
from calibre.gui2 import error_dialog, choose_dir from calibre.gui2 import error_dialog, choose_dir
from calibre.constants import filesystem_encoding from calibre.constants import filesystem_encoding, iswindows
from calibre import isbytestring, patheq from calibre import isbytestring, patheq
from calibre.utils.config import prefs from calibre.utils.config import prefs
from calibre.gui2.wizard import move_library from calibre.gui2.wizard import move_library
from calibre.library.database2 import LibraryDatabase2
class ChooseLibrary(QDialog, Ui_Dialog): class ChooseLibrary(QDialog, Ui_Dialog):
@ -57,12 +58,20 @@ class ChooseLibrary(QDialog, Ui_Dialog):
_('There is no existing calibre library at %s')%loc, _('There is no existing calibre library at %s')%loc,
show=True) show=True)
return False return False
if ac in ('new', 'move') and not empty: if ac in ('new', 'move'):
error_dialog(self, _('Not empty'), if not empty:
error_dialog(self, _('Not empty'),
_('The folder %s is not empty. Please choose an empty' _('The folder %s is not empty. Please choose an empty'
' folder')%loc, ' folder')%loc,
show=True) show=True)
return False return False
if (iswindows and len(loc) >
LibraryDatabase2.WINDOWS_LIBRARY_PATH_LIMIT):
error_dialog(self, _('Too long'),
_('Path to library too long. Must be less than'
' %d characters.')%LibraryDatabase2.WINDOWS_LIBRARY_PATH_LIMIT,
show=True)
return False
return True return True

View File

@ -148,7 +148,6 @@ class ViewLog(QDialog): # {{{
QApplication.clipboard().setText(txt) QApplication.clipboard().setText(txt)
# }}} # }}}
_proceed_memory = [] _proceed_memory = []
class ProceedNotification(MessageBox): # {{{ class ProceedNotification(MessageBox): # {{{
@ -206,6 +205,46 @@ class ProceedNotification(MessageBox): # {{{
_proceed_memory.remove(self) _proceed_memory.remove(self)
# }}} # }}}
class ErrorNotification(MessageBox): # {{{
def __init__(self, html_log, log_viewer_title, title, msg,
det_msg='', show_copy_button=False, parent=None):
'''
A non modal popup that notifies the user that a background task has
errored.
:param html_log: An HTML or plain text log
:param log_viewer_title: The title for the log viewer window
:param title: The title for this popup
:param msg: The msg to display
:param det_msg: Detailed message
'''
MessageBox.__init__(self, MessageBox.ERROR, title, msg,
det_msg=det_msg, show_copy_button=show_copy_button,
parent=parent)
self.html_log = html_log
self.log_viewer_title = log_viewer_title
self.finished.connect(self.do_close, type=Qt.QueuedConnection)
self.vlb = self.bb.addButton(_('View log'), self.bb.ActionRole)
self.vlb.setIcon(QIcon(I('debug.png')))
self.vlb.clicked.connect(self.show_log)
self.det_msg_toggle.setVisible(bool(det_msg))
self.setModal(False)
_proceed_memory.append(self)
def show_log(self):
self.log_viewer = ViewLog(self.log_viewer_title, self.html_log,
parent=self)
def do_close(self, result):
# Ensure this notification is garbage collected
self.setParent(None)
self.finished.disconnect()
self.vlb.clicked.disconnect()
_proceed_memory.remove(self)
# }}}
if __name__ == '__main__': if __name__ == '__main__':
app = QApplication([]) app = QApplication([])
from calibre.gui2 import question_dialog from calibre.gui2 import question_dialog

View File

@ -11,8 +11,8 @@ import textwrap, re, os
from PyQt4.Qt import (Qt, QDateEdit, QDate, pyqtSignal, QMessageBox, from PyQt4.Qt import (Qt, QDateEdit, QDate, pyqtSignal, QMessageBox,
QIcon, QToolButton, QWidget, QLabel, QGridLayout, QApplication, QIcon, QToolButton, QWidget, QLabel, QGridLayout, QApplication,
QDoubleSpinBox, QListWidgetItem, QSize, QPixmap, QDoubleSpinBox, QListWidgetItem, QSize, QPixmap, QDialog,
QPushButton, QSpinBox, QLineEdit, QSizePolicy) QPushButton, QSpinBox, QLineEdit, QSizePolicy, QDialogButtonBox)
from calibre.gui2.widgets import EnLineEdit, FormatList, ImageView from calibre.gui2.widgets import EnLineEdit, FormatList, ImageView
from calibre.gui2.complete import MultiCompleteLineEdit, MultiCompleteComboBox from calibre.gui2.complete import MultiCompleteLineEdit, MultiCompleteComboBox
@ -1061,10 +1061,68 @@ class IdentifiersEdit(QLineEdit): # {{{
def paste_isbn(self): def paste_isbn(self):
text = unicode(QApplication.clipboard().text()).strip() text = unicode(QApplication.clipboard().text()).strip()
if text: if not text or not check_isbn(text):
vals = self.current_val d = ISBNDialog(self, text)
vals['isbn'] = text if not d.exec_():
self.current_val = vals return
text = d.text()
if not text:
return
vals = self.current_val
vals['isbn'] = text
self.current_val = vals
# }}}
class ISBNDialog(QDialog) : # {{{
def __init__(self, parent, txt):
QDialog.__init__(self, parent)
l = QGridLayout()
self.setLayout(l)
self.setWindowTitle(_('Invalid ISBN'))
w = QLabel(_('Enter an ISBN'))
l.addWidget(w, 0, 0, 1, 2)
w = QLabel(_('ISBN:'))
l.addWidget(w, 1, 0, 1, 1)
self.line_edit = w = QLineEdit();
w.setText(txt)
w.selectAll()
w.textChanged.connect(self.checkText)
l.addWidget(w, 1, 1, 1, 1)
w = QDialogButtonBox(QDialogButtonBox.Ok|QDialogButtonBox.Cancel)
l.addWidget(w, 2, 0, 1, 2)
w.accepted.connect(self.accept)
w.rejected.connect(self.reject)
self.checkText(self.text())
sz = self.sizeHint()
sz.setWidth(sz.width()+50)
self.resize(sz)
def accept(self):
isbn = unicode(self.line_edit.text())
if not check_isbn(isbn):
return error_dialog(self, _('Invalid ISBN'),
_('The ISBN you entered is not valid. Try again.'),
show=True)
QDialog.accept(self)
def checkText(self, txt):
isbn = unicode(txt)
if not isbn:
col = 'none'
extra = ''
elif check_isbn(isbn) is not None:
col = 'rgba(0,255,0,20%)'
extra = _('This ISBN number is valid')
else:
col = 'rgba(255,0,0,20%)'
extra = _('This ISBN number is invalid')
self.line_edit.setToolTip(extra)
self.line_edit.setStyleSheet('QLineEdit { background-color: %s }'%col)
def text(self):
return unicode(self.line_edit.text())
# }}} # }}}

View File

@ -16,7 +16,7 @@ from PyQt4.Qt import QWizard, QWizardPage, QPixmap, Qt, QAbstractListModel, \
from calibre import __appname__, patheq from calibre import __appname__, patheq
from calibre.library.database2 import LibraryDatabase2 from calibre.library.database2 import LibraryDatabase2
from calibre.library.move import MoveLibrary from calibre.library.move import MoveLibrary
from calibre.constants import filesystem_encoding from calibre.constants import filesystem_encoding, iswindows
from calibre.gui2.wizard.send_email import smtp_prefs from calibre.gui2.wizard.send_email import smtp_prefs
from calibre.gui2.wizard.device_ui import Ui_WizardPage as DeviceUI from calibre.gui2.wizard.device_ui import Ui_WizardPage as DeviceUI
from calibre.gui2.wizard.library_ui import Ui_WizardPage as LibraryUI from calibre.gui2.wizard.library_ui import Ui_WizardPage as LibraryUI
@ -656,6 +656,13 @@ class LibraryPage(QWizardPage, LibraryUI):
x = choose_dir(self, 'database location dialog', x = choose_dir(self, 'database location dialog',
_('Select location for books')) _('Select location for books'))
if x: if x:
if (iswindows and len(x) >
LibraryDatabase2.WINDOWS_LIBRARY_PATH_LIMIT):
return error_dialog(self, _('Too long'),
_('Path to library too long. Must be less than'
' %d characters.')%LibraryDatabase2.WINDOWS_LIBRARY_PATH_LIMIT,
show=True)
if self.is_library_dir_suitable(x): if self.is_library_dir_suitable(x):
self.location.setText(x) self.location.setText(x)
else: else:

View File

@ -82,6 +82,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
An ebook metadata database that stores references to ebook files on disk. An ebook metadata database that stores references to ebook files on disk.
''' '''
PATH_LIMIT = 40 if 'win32' in sys.platform else 100 PATH_LIMIT = 40 if 'win32' in sys.platform else 100
WINDOWS_LIBRARY_PATH_LIMIT = 75
@dynamic_property @dynamic_property
def user_version(self): def user_version(self):
@ -122,9 +123,20 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
return property(doc=doc, fget=fget, fset=fset) return property(doc=doc, fget=fget, fset=fset)
def connect(self): def connect(self):
if 'win32' in sys.platform and len(self.library_path) + 4*self.PATH_LIMIT + 10 > 259: if iswindows and len(self.library_path) + 4*self.PATH_LIMIT + 10 > 259:
raise ValueError('Path to library too long. Must be less than %d characters.'%(259-4*self.PATH_LIMIT-10)) raise ValueError(_(
'Path to library too long. Must be less than'
' %d characters.')%(259-4*self.PATH_LIMIT-10))
exists = os.path.exists(self.dbpath) exists = os.path.exists(self.dbpath)
if not exists:
# Be more strict when creating new libraries as the old calculation
# allowed for max path lengths of 265 chars.
if (iswindows and len(self.library_path) >
self.WINDOWS_LIBRARY_PATH_LIMIT):
raise ValueError(_(
'Path to library too long. Must be less than'
' %d characters.')%self.WINDOWS_LIBRARY_PATH_LIMIT)
self.conn = connect(self.dbpath, self.row_factory) self.conn = connect(self.dbpath, self.row_factory)
if exists and self.user_version == 0: if exists and self.user_version == 0:
self.conn.close() self.conn.close()

View File

@ -579,7 +579,7 @@ How is |app| licensed?
How do I run calibre from my USB stick? How do I run calibre from my USB stick?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
A portable version of calibre is available at: `portableapps.com <http://portableapps.com/node/20518>`_. However, this is usually out of date. You can also setup your own portable calibre install by following :ref:`these instructions <portablecalibre>`. A portable version of calibre is available `here <http://calibre-ebook.com/download_portable>`_.
How do I run parts of |app| like news download and the content server on my own linux server? How do I run parts of |app| like news download and the content server on my own linux server?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -326,8 +326,9 @@ Two other kinds of searches are available: equality search and search using regu
Equality searches are indicated by prefixing the search string with an equals sign (=). For example, the query Equality searches are indicated by prefixing the search string with an equals sign (=). For example, the query
``tag:"=science"`` will match "science", but not "science fiction" or "hard science". Regular expression searches are ``tag:"=science"`` will match "science", but not "science fiction" or "hard science". Regular expression searches are
indicated by prefixing the search string with a tilde (~). Any python-compatible regular expression can indicated by prefixing the search string with a tilde (~). Any python-compatible regular expression can
be used. Regular expression searches are contains searches unless the expression contains anchors. be used. Note that backslashes use to escape special characters in reqular expressions must be doubled, because single backslashes will be removed during query parsing. For example, to match a literal parenthesis, you must enter ``\\(``. Regular expression searches are contains searches unless the expression contains anchors.
Should you need to search for a string with a leading equals or tilde, prefix the string with a backslash.
Should you need to search for a string with a leading equals or tilde, prefix the string with a backslash.
Enclose search strings with quotes (") if the string contains parenthesis or spaces. For example, to search Enclose search strings with quotes (") if the string contains parenthesis or spaces. For example, to search
for the tag ``Science Fiction``, you would need to search for ``tag:"=science fiction"``. If you search for for the tag ``Science Fiction``, you would need to search for ``tag:"=science fiction"``. If you search for

View File

@ -1,77 +0,0 @@
.. include:: global.rst
.. _portablecalibre:
Creating your own portable/customized calibre install
=======================================================
You can "install" calibre onto a USB stick that you can take with you and use on any computer. The magic is in a .bat file called calibre-portable.bat found in the resources folder in your calibre install. Typical uses of this files are:
* Run a Mobile Calibre installation with both the Calibre binaries and your ebook library resident on a USB disk or other portable media. In particular it is not necessary to have Calibre installed on the Windows PC that is to run Calibre. This batch file also does not care what drive letter is assigned when you plug in the USB device. It also will not affect any settings on the host machine being a completely self-contained Calibre installation.
* Run a networked Calibre installation optimised for performance when the ebook files are located on a networked share.
If you find setting up the bat file too challenging, there is a third party portable calibre build available at `portableapps.com <http://portableapps.com>`_.
This calibre-portable.bat file is intended for use on Windows based systems, but the principles are easily adapted for use on Linux or OS X based systems. Note that calibre requires the Microsoft Visual C++ 2008 runtimes to run. Most windows computers have them installed already, but it may be a good idea to have the installer for installing them on your USB stick. The installer is available from `Microsoft <http://www.microsoft.com/downloads/details.aspx?FamilyID=9b2da534-3e03-4391-8a4d-074b9f2bc1bf&displaylang=en>`_.
Assumptions
------------
The calibre-portable.bat file makes the following assumptions about the folder layout that is being used::
Calibre_Root_Folder
calibre-portable.bat The batch file used to start Calibre
Calibre2 The Calibre binaries
CalibreLibrary The Calibre Library
CalibreConfig The Calibre user preferences
CalibreSource The calibre source (optional) if running a development environment.
If you want to use a different folder layout then the calibre-portable.bat file will need editing appropriately. This file can be edited using any appropriate text editor.
Preparation
------------
The steps required to prepare the USB stick are as follows:
* Decide what folder will be used to hold all the Calibre related files. If the portable media is to be dedicated to Calibre use then this can be the root folder, but if not is suggested that a folder called Calibre should be created this will then be the Calibre_Root_Folder mentioned above and in the following steps.
* Copy the calibre-portable.bat file into the Calibre_Root_Folder.
* Create the Calibre2 folder inside the Calibre_Root_Folder to hold the Calibre binaries. There are 2 ways of populating the contents of this folder:
* The easiest is to simply copy an existing Calibre installation. Typically this would involve copying the contents of the C:\Program Files\Calibre2 folder
* Run the Calibre Windows installer:
* Tick the box to accept the GNU GPL license
* Select the Advanced option
* Change the install location to be the Calibre2 folder on the USB drive
* Deselect the options for creating Menu shortcuts; creating a calibre shortcut on the desktop; and adding Calibre to the path
* Create the CalibreLibrary folder inside the Calibre_Root_Folder. If you have an existing Calibre library copy it and all its contents to the CalibreLibrary folder. If you do not already have a library do not worry as a new one will be created at this location when Calibre is started.
* Create the CalibreConfig folder inside the Calibre_Root_Folder. This will hold your personal Calibre configuration settings. If you have an existing Calibre installation and want to copy the current settings then copy the contents of your current configuration folder to the CalibreConfig folder. You can find the location of your current configuration folder by going to :guilabel:`Preferences->Advanced->Miscellaneous` and clicking the “Open calibre configuration Directory” button.
* When you have started Calibre, go into :guilabel:`Preferences->Interface->Behavior` and check that you have set the Job Priority to Low. This setting keeps single-processor Windows systems responsive without affecting Calibre performance to any noticeable degree. On multi-processor or multi-core systems this setting does not matter as much, but setting it will do no harm.
Using calibre-portable.bat
---------------------------
Once you have got the USB stick set up then the steps to use Calibre are:
* Plug the USB stick into the host machine
* Use Windows Explorer to navigate to the location of the calibre-portable.bat file on the USB stick
* Start Calibre by double-clicking the calibre-portable.bat file
* A Command Window will be opened showing the settings that are about to be used. If you are not happy with these setting use CTRL-C to abandon the batch file without starting Calibre. If you are happy then press any other key to launch Calibre with the specified settings. Once you are happy with your setup you may wish to edit the calibre-portable.bat file to eliminate this pause (add REM to the start of the line) but it a useful check that you are running with the expected settings.
Networked Installations
--------------------------
The performance of Calibre can be severely degraded if running with the Calibre library on a network share. This is primarily due to the fact that the access to the metadata.db file is slow across a network. The calibre-portable.bat file is designed to help in such scenarios. To use the calibre-portable.bat file in such a scenario the following deviations from those detailed above for the Mobile Calibre installation are needed:
* Edit the calibre-portable.bat file to specify the location of your Calibre library on the network.
* Create a CalibreMetadata folder in the Calibre_Root_Folder location. If you have an existing Calibre library then copy the metadata.db files from there to the CalibreMetadata folder.
* You can now run Calibre using the calibre-portable.bat file as specified in the previous section. One thing you should remember is to periodically copy the metadata.db file from the CalibreMetadatqa folder back to your Calibre library located on the network share.
Precautions
--------------
Portable media can occasionally fail so you should make periodic backups of you Calibre library. This can be done by making a copy of the CalibreLibrary folder and all its contents. There are many freely available tools around that can optimise such back processes, well known ones being RoboCopy and RichCopy. However you can simply use a Windows copy facility if you cannot be bothered to use a specialised tools.
Using the environment variable CALIBRE_OVERRIDE_DATABASE_PATH disables multiple-library support in |app|. Avoid setting this variable in calibre-portable.bat unless you really need it.

View File

@ -16,7 +16,6 @@ Here you will find tutorials to get you started using |app|'s more advanced feat
xpath xpath
template_lang template_lang
regexp regexp
portable
server server
creating_plugins creating_plugins

View File

@ -1297,7 +1297,9 @@ class ZipFile:
Add a directory recursively to the zip file with an optional prefix. Add a directory recursively to the zip file with an optional prefix.
''' '''
if prefix: if prefix:
self.writestr(prefix+'/', '', 0700) zi = ZipInfo(prefix+'/')
zi.external_attr = 16
self.writestr(zi, '')
cwd = os.path.abspath(os.getcwd()) cwd = os.path.abspath(os.getcwd())
try: try:
os.chdir(path) os.chdir(path)