mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
merge from trunk
This commit is contained in:
commit
93e82f5169
@ -19,6 +19,67 @@
|
|||||||
# new recipes:
|
# new recipes:
|
||||||
# - title:
|
# - title:
|
||||||
|
|
||||||
|
- version: 0.8.5
|
||||||
|
date: 2011-06-10
|
||||||
|
|
||||||
|
new features:
|
||||||
|
- title: "A new 'portable' calibre build, useful if you like to carry around calibre and its library on a USB key"
|
||||||
|
type: major
|
||||||
|
description: "For details, see: http://calibre-ebook.com/download_portable"
|
||||||
|
|
||||||
|
- title: "E-book viewer: Remember the last used font size multiplier."
|
||||||
|
tickets: [774343]
|
||||||
|
|
||||||
|
- title: "Preliminary support for the Kobo Touch. Drivers for the ZTE v9 tablet, Samsung S2, Notion Ink Adam and PocketBook 360+"
|
||||||
|
|
||||||
|
- title: "When downloading metadata merge rather than replace tags"
|
||||||
|
|
||||||
|
- title: "Edit metadata dialog: When pasting in an ISBN, if not valid ISBN if present on the clipboard popup a box for the user to enter the ISBN"
|
||||||
|
|
||||||
|
- title: "Windows build: Add code to load .pyd python extensions from a zip file. This allows many more files in the calibre installation to be zipped up, speeding up the installer."
|
||||||
|
- title: "Add an action to remove all formats from the selected books to the remove books button"
|
||||||
|
|
||||||
|
|
||||||
|
bug fixes:
|
||||||
|
- title: "Various minor bug fixes to the column coloring code"
|
||||||
|
|
||||||
|
- title: "Fix the not() template function"
|
||||||
|
|
||||||
|
- title: "Nook Color/TSR: When sending books to the storage card place them in the My Files/Books subdirectory. Also do not upload cover thumbnails as users report that the NC/TSR don't use them."
|
||||||
|
tickets: [792842]
|
||||||
|
|
||||||
|
- title: "Get Books: Update plugins for Amazon and B&N stores to handle website changes. Enable some stores by default on first run. Add Zixo store"
|
||||||
|
tickets: [792762]
|
||||||
|
|
||||||
|
- title: "Comic Input: Replace the # character in filenames as it can cause problem with conversion/vieweing."
|
||||||
|
tickets: [792723]
|
||||||
|
|
||||||
|
- title: "When writing files to zipfile, reset timestamp if it doesn't fit in 1980's vintage storage structures"
|
||||||
|
|
||||||
|
- title: "Amazon metadata plugin: Fix parsing of published date from amazon.de when it has februar in it"
|
||||||
|
|
||||||
|
improved recipes:
|
||||||
|
- Ambito
|
||||||
|
- GoComics
|
||||||
|
- Le Monde Diplomatique
|
||||||
|
- Max Planck
|
||||||
|
- express.de
|
||||||
|
|
||||||
|
new recipes:
|
||||||
|
- title: Ambito Financiero
|
||||||
|
author: Darko Miletic
|
||||||
|
|
||||||
|
- title: Stiin Tas Technica
|
||||||
|
author: Silviu Cotoara
|
||||||
|
|
||||||
|
- title: "Metro News NL"
|
||||||
|
author: DrMerry
|
||||||
|
|
||||||
|
- title: "Brigitte.de, Polizeipresse DE and Heise Online"
|
||||||
|
author: schuster
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
- version: 0.8.4
|
- version: 0.8.4
|
||||||
date: 2011-06-03
|
date: 2011-06-03
|
||||||
|
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
|
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2008-2009, Darko Miletic <darko.miletic at gmail.com>'
|
__copyright__ = '2008-2011, Darko Miletic <darko.miletic at gmail.com>'
|
||||||
'''
|
'''
|
||||||
ambito.com
|
ambito.com
|
||||||
'''
|
'''
|
||||||
@ -11,51 +9,56 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
class Ambito(BasicNewsRecipe):
|
class Ambito(BasicNewsRecipe):
|
||||||
title = 'Ambito.com'
|
title = 'Ambito.com'
|
||||||
__author__ = 'Darko Miletic'
|
__author__ = 'Darko Miletic'
|
||||||
description = 'Informacion Libre las 24 horas'
|
description = 'Ambito.com con noticias del Diario Ambito Financiero de Buenos Aires'
|
||||||
publisher = 'Ambito.com'
|
publisher = 'Editorial Nefir S.A.'
|
||||||
category = 'news, politics, Argentina'
|
category = 'news, politics, economy, finances, Argentina'
|
||||||
oldest_article = 2
|
oldest_article = 2
|
||||||
max_articles_per_feed = 100
|
|
||||||
no_stylesheets = True
|
no_stylesheets = True
|
||||||
encoding = 'iso-8859-1'
|
encoding = 'cp1252'
|
||||||
cover_url = 'http://www.ambito.com/img/logo_.jpg'
|
masthead_url = 'http://www.ambito.com/img/logo_.jpg'
|
||||||
remove_javascript = True
|
|
||||||
use_embedded_content = False
|
use_embedded_content = False
|
||||||
|
language = 'es_AR'
|
||||||
|
publication_type = 'newsportal'
|
||||||
|
extra_css = """
|
||||||
|
body{font-family: "Trebuchet MS",Verdana,sans-serif}
|
||||||
|
.volanta{font-size: small}
|
||||||
|
.t2_portada{font-size: xx-large; font-family: Georgia,serif; color: #026698}
|
||||||
|
"""
|
||||||
|
|
||||||
html2lrf_options = [
|
|
||||||
'--comment', description
|
|
||||||
, '--category', category
|
|
||||||
, '--publisher', publisher
|
|
||||||
]
|
|
||||||
|
|
||||||
html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"'
|
conversion_options = {
|
||||||
|
'comment' : description
|
||||||
|
, 'tags' : category
|
||||||
|
, 'publisher' : publisher
|
||||||
|
, 'language' : language
|
||||||
|
}
|
||||||
|
|
||||||
keep_only_tags = [dict(name='div', attrs={'align':'justify'})]
|
keep_only_tags = [dict(name='div', attrs={'align':'justify'})]
|
||||||
|
remove_tags = [dict(name=['object','link','embed','iframe','meta','link','table','img'])]
|
||||||
remove_tags = [dict(name=['object','link'])]
|
remove_attributes = ['align']
|
||||||
|
|
||||||
feeds = [
|
feeds = [
|
||||||
(u'Principales Noticias', u'http://www.ambito.com/rss/noticiasp.asp' )
|
(u'Principales Noticias', u'http://www.ambito.com/rss/noticiasp.asp' )
|
||||||
,(u'Economia' , u'http://www.ambito.com/rss/noticias.asp?S=Econom%EDa' )
|
,(u'Economia' , u'http://www.ambito.com/rss/noticias.asp?S=Econom%EDa' )
|
||||||
,(u'Politica' , u'http://www.ambito.com/rss/noticias.asp?S=Pol%EDtica' )
|
,(u'Politica' , u'http://www.ambito.com/rss/noticias.asp?S=Pol%EDtica' )
|
||||||
,(u'Informacion General' , u'http://www.ambito.com/rss/noticias.asp?S=Informaci%F3n%20General')
|
,(u'Informacion General' , u'http://www.ambito.com/rss/noticias.asp?S=Informaci%F3n%20General')
|
||||||
,(u'Agro' , u'http://www.ambito.com/rss/noticias.asp?S=Agro' )
|
,(u'Campo' , u'http://www.ambito.com/rss/noticias.asp?S=Agro' )
|
||||||
,(u'Internacionales' , u'http://www.ambito.com/rss/noticias.asp?S=Internacionales' )
|
,(u'Internacionales' , u'http://www.ambito.com/rss/noticias.asp?S=Internacionales' )
|
||||||
,(u'Deportes' , u'http://www.ambito.com/rss/noticias.asp?S=Deportes' )
|
,(u'Deportes' , u'http://www.ambito.com/rss/noticias.asp?S=Deportes' )
|
||||||
,(u'Espectaculos' , u'http://www.ambito.com/rss/noticias.asp?S=Espect%E1culos' )
|
,(u'Espectaculos' , u'http://www.ambito.com/rss/noticias.asp?S=Espect%E1culos' )
|
||||||
,(u'Tecnologia' , u'http://www.ambito.com/rss/noticias.asp?S=Tecnologia' )
|
,(u'Tecnologia' , u'http://www.ambito.com/rss/noticias.asp?S=Tecnolog%EDa' )
|
||||||
,(u'Salud' , u'http://www.ambito.com/rss/noticias.asp?S=Salud' )
|
|
||||||
,(u'Ambito Nacional' , u'http://www.ambito.com/rss/noticias.asp?S=Ambito%20Nacional' )
|
,(u'Ambito Nacional' , u'http://www.ambito.com/rss/noticias.asp?S=Ambito%20Nacional' )
|
||||||
]
|
]
|
||||||
|
|
||||||
def print_version(self, url):
|
def print_version(self, url):
|
||||||
return url.replace('http://www.ambito.com/noticia.asp?','http://www.ambito.com/noticias/imprimir.asp?')
|
return url.replace('/noticia.asp?','/noticias/imprimir.asp?')
|
||||||
|
|
||||||
def preprocess_html(self, soup):
|
def preprocess_html(self, soup):
|
||||||
mtag = '<meta http-equiv="Content-Language" content="es-AR"/>'
|
|
||||||
soup.head.insert(0,mtag)
|
|
||||||
for item in soup.findAll(style=True):
|
for item in soup.findAll(style=True):
|
||||||
del item['style']
|
del item['style']
|
||||||
|
for item in soup.findAll('a'):
|
||||||
|
str = item.string
|
||||||
|
if str is None:
|
||||||
|
str = self.tag_to_string(item)
|
||||||
|
item.replaceWith(str)
|
||||||
return soup
|
return soup
|
||||||
|
|
||||||
language = 'es_AR'
|
|
||||||
|
87
recipes/ambito_financiero.recipe
Normal file
87
recipes/ambito_financiero.recipe
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
__license__ = 'GPL v3'
|
||||||
|
__copyright__ = '2011, Darko Miletic <darko.miletic at gmail.com>'
|
||||||
|
'''
|
||||||
|
ambito.com/diario
|
||||||
|
'''
|
||||||
|
|
||||||
|
import time
|
||||||
|
from calibre import strftime
|
||||||
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
|
class Ambito_Financiero(BasicNewsRecipe):
|
||||||
|
title = 'Ambito Financiero'
|
||||||
|
__author__ = 'Darko Miletic'
|
||||||
|
description = 'Informacion Libre las 24 horas'
|
||||||
|
publisher = 'Editorial Nefir S.A.'
|
||||||
|
category = 'news, politics, economy, Argentina'
|
||||||
|
no_stylesheets = True
|
||||||
|
encoding = 'cp1252'
|
||||||
|
masthead_url = 'http://www.ambito.com/diario/img/logo_af.gif'
|
||||||
|
publication_type = 'newspaper'
|
||||||
|
needs_subscription = 'optional'
|
||||||
|
use_embedded_content = False
|
||||||
|
language = 'es_AR'
|
||||||
|
PREFIX = 'http://www.ambito.com'
|
||||||
|
INDEX = PREFIX + '/diario/index.asp'
|
||||||
|
LOGIN = PREFIX + '/diario/login/entrada.asp'
|
||||||
|
extra_css = """
|
||||||
|
body{font-family: "Trebuchet MS",Verdana,sans-serif}
|
||||||
|
.volanta{font-size: small}
|
||||||
|
.t2_portada{font-size: xx-large; font-family: Georgia,serif; color: #026698}
|
||||||
|
"""
|
||||||
|
|
||||||
|
conversion_options = {
|
||||||
|
'comment' : description
|
||||||
|
, 'tags' : category
|
||||||
|
, 'publisher' : publisher
|
||||||
|
, 'language' : language
|
||||||
|
}
|
||||||
|
|
||||||
|
keep_only_tags = [dict(name='div', attrs={'align':'justify'})]
|
||||||
|
remove_tags = [dict(name=['object','link','embed','iframe','meta','link','table','img'])]
|
||||||
|
remove_attributes = ['align']
|
||||||
|
|
||||||
|
def get_browser(self):
|
||||||
|
br = BasicNewsRecipe.get_browser()
|
||||||
|
br.open(self.INDEX)
|
||||||
|
if self.username is not None and self.password is not None:
|
||||||
|
br.open(self.LOGIN)
|
||||||
|
br.select_form(name='frmlogin')
|
||||||
|
br['USER_NAME'] = self.username
|
||||||
|
br['USER_PASS'] = self.password
|
||||||
|
br.submit()
|
||||||
|
return br
|
||||||
|
|
||||||
|
def print_version(self, url):
|
||||||
|
return url.replace('/diario/noticia.asp?','/noticias/imprimir.asp?')
|
||||||
|
|
||||||
|
def preprocess_html(self, soup):
|
||||||
|
for item in soup.findAll(style=True):
|
||||||
|
del item['style']
|
||||||
|
for item in soup.findAll('a'):
|
||||||
|
str = item.string
|
||||||
|
if str is None:
|
||||||
|
str = self.tag_to_string(item)
|
||||||
|
item.replaceWith(str)
|
||||||
|
return soup
|
||||||
|
|
||||||
|
def parse_index(self):
|
||||||
|
soup = self.index_to_soup(self.INDEX)
|
||||||
|
cover_item = soup.find('img',attrs={'class':'fotodespliegue'})
|
||||||
|
if cover_item:
|
||||||
|
self.cover_url = self.PREFIX + cover_item['src']
|
||||||
|
articles = []
|
||||||
|
checker = []
|
||||||
|
for feed_link in soup.findAll('a', attrs={'class':['t0_portada','t2_portada','bajada']}):
|
||||||
|
url = self.PREFIX + feed_link['href']
|
||||||
|
title = self.tag_to_string(feed_link)
|
||||||
|
date = strftime("%a, %d %b %Y %H:%M:%S +0000",time.gmtime())
|
||||||
|
if url not in checker:
|
||||||
|
checker.append(url)
|
||||||
|
articles.append({
|
||||||
|
'title' :title
|
||||||
|
,'date' :date
|
||||||
|
,'url' :url
|
||||||
|
,'description':u''
|
||||||
|
})
|
||||||
|
return [(self.title, articles)]
|
@ -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 to 5", u"http://www.gocomics.com/9to5"),
|
#(u"9 Chickweed Lane", u"http://www.gocomics.com/9chickweedlane"),
|
||||||
# (u"The Academia Waltz", u"http://www.gocomics.com/academiawaltz"),
|
(u"9 to 5", u"http://www.gocomics.com/9to5"),
|
||||||
# (u"Adam@Home", u"http://www.gocomics.com/adamathome"),
|
#(u"Adam At Home", u"http://www.gocomics.com/adamathome"),
|
||||||
# (u"Agnes", u"http://www.gocomics.com/agnes"),
|
(u"Agnes", u"http://www.gocomics.com/agnes"),
|
||||||
# (u"Andy Capp", u"http://www.gocomics.com/andycapp"),
|
#(u"Alley Oop", u"http://www.gocomics.com/alleyoop"),
|
||||||
# (u"Animal Crackers", u"http://www.gocomics.com/animalcrackers"),
|
#(u"Andy Capp", u"http://www.gocomics.com/andycapp"),
|
||||||
# (u"Annie", u"http://www.gocomics.com/annie"),
|
#(u"Animal Crackers", u"http://www.gocomics.com/animalcrackers"),
|
||||||
(u"The Argyle Sweater", u"http://www.gocomics.com/theargylesweater"),
|
#(u"Annie", u"http://www.gocomics.com/annie"),
|
||||||
# (u"Ask Shagg", u"http://www.gocomics.com/askshagg"),
|
#(u"Arlo & Janis", u"http://www.gocomics.com/arloandjanis"),
|
||||||
|
#(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"Bleeker: The Rechargeable Dog", u"http://www.gocomics.com/bleeker"),
|
||||||
|
#(u"Bliss", u"http://www.gocomics.com/bliss"),
|
||||||
(u"Bloom County", u"http://www.gocomics.com/bloomcounty"),
|
(u"Bloom County", u"http://www.gocomics.com/bloomcounty"),
|
||||||
# (u"Bo Nanas", u"http://www.gocomics.com/bonanas"),
|
#(u"Bo Nanas", u"http://www.gocomics.com/bonanas"),
|
||||||
# (u"Bob the Squirrel", u"http://www.gocomics.com/bobthesquirrel"),
|
#(u"Bob the Squirrel", u"http://www.gocomics.com/bobthesquirrel"),
|
||||||
# (u"The Boiling Point", u"http://www.gocomics.com/theboilingpoint"),
|
#(u"Boomerangs", u"http://www.gocomics.com/boomerangs"),
|
||||||
# (u"Boomerangs", u"http://www.gocomics.com/boomerangs"),
|
#(u"Bottomliners", u"http://www.gocomics.com/bottomliners"),
|
||||||
# (u"The Boondocks", u"http://www.gocomics.com/boondocks"),
|
#(u"Bound and Gagged", u"http://www.gocomics.com/boundandgagged"),
|
||||||
# (u"Bottomliners", u"http://www.gocomics.com/bottomliners"),
|
#(u"Brainwaves", u"http://www.gocomics.com/brainwaves"),
|
||||||
# (u"Bound and Gagged", u"http://www.gocomics.com/boundandgagged"),
|
#(u"Brenda Starr", u"http://www.gocomics.com/brendastarr"),
|
||||||
# (u"Brainwaves", u"http://www.gocomics.com/brainwaves"),
|
#(u"Brevity", u"http://www.gocomics.com/brevity"),
|
||||||
# (u"Brenda Starr", u"http://www.gocomics.com/brendastarr"),
|
#(u"Brewster Rockit", u"http://www.gocomics.com/brewsterrockit"),
|
||||||
# (u"Brewster Rockit", u"http://www.gocomics.com/brewsterrockit"),
|
#(u"Broom Hilda", u"http://www.gocomics.com/broomhilda"),
|
||||||
# (u"Broom Hilda", u"http://www.gocomics.com/broomhilda"),
|
|
||||||
(u"Calvin and Hobbes", u"http://www.gocomics.com/calvinandhobbes"),
|
(u"Calvin and Hobbes", u"http://www.gocomics.com/calvinandhobbes"),
|
||||||
# (u"Candorville", u"http://www.gocomics.com/candorville"),
|
#(u"Candorville", u"http://www.gocomics.com/candorville"),
|
||||||
# (u"Cathy", u"http://www.gocomics.com/cathy"),
|
#(u"Cathy", u"http://www.gocomics.com/cathy"),
|
||||||
# (u"C'est la Vie", u"http://www.gocomics.com/cestlavie"),
|
#(u"C'est la Vie", u"http://www.gocomics.com/cestlavie"),
|
||||||
# (u"Chuckle Bros", u"http://www.gocomics.com/chucklebros"),
|
#(u"Cheap Thrills", u"http://www.gocomics.com/cheapthrills"),
|
||||||
# (u"Citizen Dog", u"http://www.gocomics.com/citizendog"),
|
#(u"Chuckle Bros", u"http://www.gocomics.com/chucklebros"),
|
||||||
# (u"The City", u"http://www.gocomics.com/thecity"),
|
#(u"Citizen Dog", u"http://www.gocomics.com/citizendog"),
|
||||||
# (u"Cleats", u"http://www.gocomics.com/cleats"),
|
#(u"Cleats", u"http://www.gocomics.com/cleats"),
|
||||||
# (u"Close to Home", u"http://www.gocomics.com/closetohome"),
|
#(u"Close to Home", u"http://www.gocomics.com/closetohome"),
|
||||||
# (u"Compu-toon", u"http://www.gocomics.com/compu-toon"),
|
#(u"Committed", u"http://www.gocomics.com/committed"),
|
||||||
# (u"Cornered", u"http://www.gocomics.com/cornered"),
|
#(u"Compu-toon", u"http://www.gocomics.com/compu-toon"),
|
||||||
(u"Cul de Sac", u"http://www.gocomics.com/culdesac"),
|
#(u"Cornered", u"http://www.gocomics.com/cornered"),
|
||||||
# (u"Daddy's Home", u"http://www.gocomics.com/daddyshome"),
|
#(u"Cow & Boy", u"http://www.gocomics.com/cow&boy"),
|
||||||
# (u"Deep Cover", u"http://www.gocomics.com/deepcover"),
|
#(u"Cul de Sac", u"http://www.gocomics.com/culdesac"),
|
||||||
# (u"Dick Tracy", u"http://www.gocomics.com/dicktracy"),
|
#(u"Daddy's Home", u"http://www.gocomics.com/daddyshome"),
|
||||||
# (u"The Dinette Set", u"http://www.gocomics.com/dinetteset"),
|
#(u"Deep Cover", u"http://www.gocomics.com/deepcover"),
|
||||||
# (u"Dog Eat Doug", u"http://www.gocomics.com/dogeatdoug"),
|
#(u"Dick Tracy", u"http://www.gocomics.com/dicktracy"),
|
||||||
# (u"Domestic Abuse", u"http://www.gocomics.com/domesticabuse"),
|
(u"Dog Eat Doug", u"http://www.gocomics.com/dogeatdoug"),
|
||||||
# (u"Doodles", u"http://www.gocomics.com/doodles"),
|
#(u"Domestic Abuse", u"http://www.gocomics.com/domesticabuse"),
|
||||||
|
(u"Doodles", u"http://www.gocomics.com/doodles"),
|
||||||
(u"Doonesbury", u"http://www.gocomics.com/doonesbury"),
|
(u"Doonesbury", u"http://www.gocomics.com/doonesbury"),
|
||||||
# (u"The Doozies", u"http://www.gocomics.com/thedoozies"),
|
#(u"Drabble", u"http://www.gocomics.com/drabble"),
|
||||||
# (u"The Duplex", u"http://www.gocomics.com/duplex"),
|
#(u"Eek!", u"http://www.gocomics.com/eek"),
|
||||||
# (u"Eek!", u"http://www.gocomics.com/eek"),
|
#(u"F Minus", u"http://www.gocomics.com/fminus"),
|
||||||
# (u"The Elderberries", u"http://www.gocomics.com/theelderberries"),
|
#(u"Family Tree", u"http://www.gocomics.com/familytree"),
|
||||||
# (u"Flight Deck", u"http://www.gocomics.com/flightdeck"),
|
#(u"Farcus", u"http://www.gocomics.com/farcus"),
|
||||||
# (u"Flo and Friends", u"http://www.gocomics.com/floandfriends"),
|
(u"Fat Cats Classics", u"http://www.gocomics.com/fatcatsclassics"),
|
||||||
# (u"The Flying McCoys", u"http://www.gocomics.com/theflyingmccoys"),
|
#(u"Ferd'nand", u"http://www.gocomics.com/ferdnand"),
|
||||||
(u"For Better or For Worse", u"http://www.gocomics.com/forbetterorforworse"),
|
#(u"Flight Deck", u"http://www.gocomics.com/flightdeck"),
|
||||||
# (u"For Heaven's Sake", u"http://www.gocomics.com/forheavenssake"),
|
(u"Flo and Friends", u"http://www.gocomics.com/floandfriends"),
|
||||||
# (u"Fort Knox", u"http://www.gocomics.com/fortknox"),
|
#(u"For Better or For Worse", u"http://www.gocomics.com/forbetterorforworse"),
|
||||||
# (u"FoxTrot", u"http://www.gocomics.com/foxtrot"),
|
#(u"For Heaven's Sake", u"http://www.gocomics.com/forheavenssake"),
|
||||||
(u"FoxTrot Classics", u"http://www.gocomics.com/foxtrotclassics"),
|
#(u"Fort Knox", u"http://www.gocomics.com/fortknox"),
|
||||||
# (u"Frank & Ernest", u"http://www.gocomics.com/frankandernest"),
|
#(u"FoxTrot Classics", u"http://www.gocomics.com/foxtrotclassics"),
|
||||||
# (u"Fred Basset", u"http://www.gocomics.com/fredbasset"),
|
(u"FoxTrot", u"http://www.gocomics.com/foxtrot"),
|
||||||
# (u"Free Range", u"http://www.gocomics.com/freerange"),
|
#(u"Frank & Ernest", u"http://www.gocomics.com/frankandernest"),
|
||||||
# (u"Frog Applause", u"http://www.gocomics.com/frogapplause"),
|
#(u"Frazz", u"http://www.gocomics.com/frazz"),
|
||||||
# (u"The Fusco Brothers", u"http://www.gocomics.com/thefuscobrothers"),
|
#(u"Fred Basset", u"http://www.gocomics.com/fredbasset"),
|
||||||
|
#(u"Free Range", u"http://www.gocomics.com/freerange"),
|
||||||
|
#(u"Frog Applause", u"http://www.gocomics.com/frogapplause"),
|
||||||
|
#(u"Garfield Minus Garfield", u"http://www.gocomics.com/garfieldminusgarfield"),
|
||||||
(u"Garfield", u"http://www.gocomics.com/garfield"),
|
(u"Garfield", u"http://www.gocomics.com/garfield"),
|
||||||
# (u"Garfield Minus Garfield", u"http://www.gocomics.com/garfieldminusgarfield"),
|
#(u"Gasoline Alley", u"http://www.gocomics.com/gasolinealley"),
|
||||||
# (u"Gasoline Alley", u"http://www.gocomics.com/gasolinealley"),
|
#(u"Geech Classics", u"http://www.gocomics.com/geechclassics"),
|
||||||
# (u"Gil Thorp", u"http://www.gocomics.com/gilthorp"),
|
#(u"Get Fuzzy", u"http://www.gocomics.com/getfuzzy"),
|
||||||
# (u"Ginger Meggs", u"http://www.gocomics.com/gingermeggs"),
|
#(u"Gil Thorp", u"http://www.gocomics.com/gilthorp"),
|
||||||
# (u"Girls & Sports", u"http://www.gocomics.com/girlsandsports"),
|
#(u"Ginger Meggs", u"http://www.gocomics.com/gingermeggs"),
|
||||||
# (u"Haiku Ewe", u"http://www.gocomics.com/haikuewe"),
|
#(u"Girls & Sports", u"http://www.gocomics.com/girlsandsports"),
|
||||||
# (u"Heart of the City", u"http://www.gocomics.com/heartofthecity"),
|
#(u"Graffiti", u"http://www.gocomics.com/graffiti"),
|
||||||
# (u"Heathcliff", u"http://www.gocomics.com/heathcliff"),
|
#(u"Grand Avenue", u"http://www.gocomics.com/grandavenue"),
|
||||||
# (u"Herb and Jamaal", u"http://www.gocomics.com/herbandjamaal"),
|
#(u"Haiku Ewe", u"http://www.gocomics.com/haikuewe"),
|
||||||
# (u"Home and Away", u"http://www.gocomics.com/homeandaway"),
|
#(u"Heart of the City", u"http://www.gocomics.com/heartofthecity"),
|
||||||
# (u"Housebroken", u"http://www.gocomics.com/housebroken"),
|
(u"Heathcliff", u"http://www.gocomics.com/heathcliff"),
|
||||||
# (u"Hubert and Abby", u"http://www.gocomics.com/hubertandabby"),
|
#(u"Herb and Jamaal", u"http://www.gocomics.com/herbandjamaal"),
|
||||||
# (u"Imagine This", u"http://www.gocomics.com/imaginethis"),
|
#(u"Herman", u"http://www.gocomics.com/herman"),
|
||||||
# (u"In the Bleachers", u"http://www.gocomics.com/inthebleachers"),
|
#(u"Home and Away", u"http://www.gocomics.com/homeandaway"),
|
||||||
# (u"In the Sticks", u"http://www.gocomics.com/inthesticks"),
|
#(u"Housebroken", u"http://www.gocomics.com/housebroken"),
|
||||||
# (u"Ink Pen", u"http://www.gocomics.com/inkpen"),
|
#(u"Hubert and Abby", u"http://www.gocomics.com/hubertandabby"),
|
||||||
# (u"It's All About You", u"http://www.gocomics.com/itsallaboutyou"),
|
#(u"Imagine This", u"http://www.gocomics.com/imaginethis"),
|
||||||
# (u"Joe Vanilla", u"http://www.gocomics.com/joevanilla"),
|
#(u"In the Bleachers", u"http://www.gocomics.com/inthebleachers"),
|
||||||
# (u"La Cucaracha", u"http://www.gocomics.com/lacucaracha"),
|
#(u"In the Sticks", u"http://www.gocomics.com/inthesticks"),
|
||||||
# (u"Last Kiss", u"http://www.gocomics.com/lastkiss"),
|
#(u"Ink Pen", u"http://www.gocomics.com/inkpen"),
|
||||||
# (u"Legend of Bill", u"http://www.gocomics.com/legendofbill"),
|
#(u"It's All About You", u"http://www.gocomics.com/itsallaboutyou"),
|
||||||
# (u"Liberty Meadows", u"http://www.gocomics.com/libertymeadows"),
|
#(u"Jane's World", u"http://www.gocomics.com/janesworld"),
|
||||||
(u"Lio", u"http://www.gocomics.com/lio"),
|
#(u"Joe Vanilla", u"http://www.gocomics.com/joevanilla"),
|
||||||
# (u"Little Dog Lost", u"http://www.gocomics.com/littledoglost"),
|
#(u"Jump Start", u"http://www.gocomics.com/jumpstart"),
|
||||||
# (u"Little Otto", u"http://www.gocomics.com/littleotto"),
|
#(u"Kit 'N' Carlyle", u"http://www.gocomics.com/kitandcarlyle"),
|
||||||
# (u"Loose Parts", u"http://www.gocomics.com/looseparts"),
|
#(u"La Cucaracha", u"http://www.gocomics.com/lacucaracha"),
|
||||||
# (u"Love Is...", u"http://www.gocomics.com/loveis"),
|
#(u"Last Kiss", u"http://www.gocomics.com/lastkiss"),
|
||||||
# (u"Maintaining", u"http://www.gocomics.com/maintaining"),
|
#(u"Legend of Bill", u"http://www.gocomics.com/legendofbill"),
|
||||||
# (u"The Meaning of Lila", u"http://www.gocomics.com/meaningoflila"),
|
#(u"Liberty Meadows", u"http://www.gocomics.com/libertymeadows"),
|
||||||
# (u"Middle-Aged White Guy", u"http://www.gocomics.com/middleagedwhiteguy"),
|
#(u"Li'l Abner Classics", u"http://www.gocomics.com/lilabnerclassics"),
|
||||||
# (u"The Middletons", u"http://www.gocomics.com/themiddletons"),
|
#(u"Lio", u"http://www.gocomics.com/lio"),
|
||||||
# (u"Momma", u"http://www.gocomics.com/momma"),
|
#(u"Little Dog Lost", u"http://www.gocomics.com/littledoglost"),
|
||||||
# (u"Mutt & Jeff", u"http://www.gocomics.com/muttandjeff"),
|
#(u"Little Otto", u"http://www.gocomics.com/littleotto"),
|
||||||
# (u"Mythtickle", u"http://www.gocomics.com/mythtickle"),
|
#(u"Lola", u"http://www.gocomics.com/lola"),
|
||||||
# (u"Nest Heads", u"http://www.gocomics.com/nestheads"),
|
#(u"Loose Parts", u"http://www.gocomics.com/looseparts"),
|
||||||
# (u"NEUROTICA", u"http://www.gocomics.com/neurotica"),
|
#(u"Love Is...", u"http://www.gocomics.com/loveis"),
|
||||||
(u"New Adventures of Queen Victoria", u"http://www.gocomics.com/thenewadventuresofqueenvictoria"),
|
#(u"Luann", u"http://www.gocomics.com/luann"),
|
||||||
(u"Non Sequitur", u"http://www.gocomics.com/nonsequitur"),
|
#(u"Maintaining", u"http://www.gocomics.com/maintaining"),
|
||||||
# (u"The Norm", u"http://www.gocomics.com/thenorm"),
|
(u"Marmaduke", u"http://www.gocomics.com/marmaduke"),
|
||||||
# (u"On A Claire Day", u"http://www.gocomics.com/onaclaireday"),
|
#(u"Meg! Classics", u"http://www.gocomics.com/megclassics"),
|
||||||
# (u"One Big Happy", u"http://www.gocomics.com/onebighappy"),
|
#(u"Middle-Aged White Guy", u"http://www.gocomics.com/middleagedwhiteguy"),
|
||||||
# (u"The Other Coast", u"http://www.gocomics.com/theothercoast"),
|
#(u"Minimum Security", u"http://www.gocomics.com/minimumsecurity"),
|
||||||
# (u"Out of the Gene Pool Re-Runs", u"http://www.gocomics.com/outofthegenepool"),
|
#(u"Moderately Confused", u"http://www.gocomics.com/moderatelyconfused"),
|
||||||
# (u"Overboard", u"http://www.gocomics.com/overboard"),
|
(u"Momma", u"http://www.gocomics.com/momma"),
|
||||||
# (u"Pibgorn", u"http://www.gocomics.com/pibgorn"),
|
#(u"Monty", u"http://www.gocomics.com/monty"),
|
||||||
# (u"Pibgorn Sketches", u"http://www.gocomics.com/pibgornsketches"),
|
#(u"Motley Classics", u"http://www.gocomics.com/motleyclassics"),
|
||||||
|
(u"Mutt & Jeff", u"http://www.gocomics.com/muttandjeff"),
|
||||||
|
#(u"Mythtickle", u"http://www.gocomics.com/mythtickle"),
|
||||||
|
#(u"Nancy", u"http://www.gocomics.com/nancy"),
|
||||||
|
#(u"Natural Selection", u"http://www.gocomics.com/naturalselection"),
|
||||||
|
#(u"Nest Heads", u"http://www.gocomics.com/nestheads"),
|
||||||
|
#(u"NEUROTICA", u"http://www.gocomics.com/neurotica"),
|
||||||
|
#(u"New Adventures of Queen Victoria", u"http://www.gocomics.com/thenewadventuresofqueenvictoria"),
|
||||||
|
#(u"Non Sequitur", u"http://www.gocomics.com/nonsequitur"),
|
||||||
|
#(u"Off The Mark", u"http://www.gocomics.com/offthemark"),
|
||||||
|
#(u"On A Claire Day", u"http://www.gocomics.com/onaclaireday"),
|
||||||
|
#(u"One Big Happy Classics", u"http://www.gocomics.com/onebighappyclassics"),
|
||||||
|
#(u"One Big Happy", u"http://www.gocomics.com/onebighappy"),
|
||||||
|
#(u"Out of the Gene Pool Re-Runs", u"http://www.gocomics.com/outofthegenepool"),
|
||||||
|
#(u"Over the Hedge", u"http://www.gocomics.com/overthehedge"),
|
||||||
|
#(u"Overboard", u"http://www.gocomics.com/overboard"),
|
||||||
|
#(u"PC and Pixel", u"http://www.gocomics.com/pcandpixel"),
|
||||||
|
(u"Peanuts", u"http://www.gocomics.com/peanuts"),
|
||||||
|
#(u"Pearls Before Swine", u"http://www.gocomics.com/pearlsbeforeswine"),
|
||||||
|
#(u"Pibgorn Sketches", u"http://www.gocomics.com/pibgornsketches"),
|
||||||
|
#(u"Pibgorn", u"http://www.gocomics.com/pibgorn"),
|
||||||
(u"Pickles", u"http://www.gocomics.com/pickles"),
|
(u"Pickles", u"http://www.gocomics.com/pickles"),
|
||||||
# (u"Pinkerton", u"http://www.gocomics.com/pinkerton"),
|
#(u"Pinkerton", u"http://www.gocomics.com/pinkerton"),
|
||||||
# (u"Pluggers", u"http://www.gocomics.com/pluggers"),
|
#(u"Pluggers", u"http://www.gocomics.com/pluggers"),
|
||||||
(u"Pooch Cafe", u"http://www.gocomics.com/poochcafe"),
|
#(u"Pooch Cafe", u"http://www.gocomics.com/poochcafe"),
|
||||||
# (u"PreTeena", u"http://www.gocomics.com/preteena"),
|
#(u"PreTeena", u"http://www.gocomics.com/preteena"),
|
||||||
# (u"The Quigmans", u"http://www.gocomics.com/thequigmans"),
|
#(u"Prickly City", u"http://www.gocomics.com/pricklycity"),
|
||||||
# (u"Rabbits Against Magic", u"http://www.gocomics.com/rabbitsagainstmagic"),
|
#(u"Rabbits Against Magic", u"http://www.gocomics.com/rabbitsagainstmagic"),
|
||||||
(u"Real Life Adventures", u"http://www.gocomics.com/reallifeadventures"),
|
#(u"Raising Duncan Classics", u"http://www.gocomics.com/raisingduncanclassics"),
|
||||||
# (u"Red and Rover", u"http://www.gocomics.com/redandrover"),
|
#(u"Real Life Adventures", u"http://www.gocomics.com/reallifeadventures"),
|
||||||
# (u"Red Meat", u"http://www.gocomics.com/redmeat"),
|
#(u"Reality Check", u"http://www.gocomics.com/realitycheck"),
|
||||||
# (u"Reynolds Unwrapped", u"http://www.gocomics.com/reynoldsunwrapped"),
|
#(u"Red and Rover", u"http://www.gocomics.com/redandrover"),
|
||||||
# (u"Ronaldinho Gaucho", u"http://www.gocomics.com/ronaldinhogaucho"),
|
#(u"Red Meat", u"http://www.gocomics.com/redmeat"),
|
||||||
# (u"Rubes", u"http://www.gocomics.com/rubes"),
|
#(u"Reynolds Unwrapped", u"http://www.gocomics.com/reynoldsunwrapped"),
|
||||||
# (u"Scary Gary", u"http://www.gocomics.com/scarygary"),
|
#(u"Rip Haywire", u"http://www.gocomics.com/riphaywire"),
|
||||||
(u"Shoe", u"http://www.gocomics.com/shoe"),
|
#(u"Ripley's Believe It or Not!", u"http://www.gocomics.com/ripleysbelieveitornot"),
|
||||||
# (u"Shoecabbage", u"http://www.gocomics.com/shoecabbage"),
|
#(u"Ronaldinho Gaucho", u"http://www.gocomics.com/ronaldinhogaucho"),
|
||||||
# (u"Skin Horse", u"http://www.gocomics.com/skinhorse"),
|
#(u"Rose Is Rose", u"http://www.gocomics.com/roseisrose"),
|
||||||
# (u"Slowpoke", u"http://www.gocomics.com/slowpoke"),
|
#(u"Rubes", u"http://www.gocomics.com/rubes"),
|
||||||
# (u"Speed Bump", u"http://www.gocomics.com/speedbump"),
|
#(u"Rudy Park", u"http://www.gocomics.com/rudypark"),
|
||||||
# (u"State of the Union", u"http://www.gocomics.com/stateoftheunion"),
|
#(u"Scary Gary", u"http://www.gocomics.com/scarygary"),
|
||||||
(u"Stone Soup", u"http://www.gocomics.com/stonesoup"),
|
#(u"Shirley and Son Classics", u"http://www.gocomics.com/shirleyandsonclassics"),
|
||||||
# (u"Strange Brew", u"http://www.gocomics.com/strangebrew"),
|
#(u"Shoe", u"http://www.gocomics.com/shoe"),
|
||||||
# (u"Sylvia", u"http://www.gocomics.com/sylvia"),
|
#(u"Shoecabbage", u"http://www.gocomics.com/shoecabbage"),
|
||||||
# (u"Tank McNamara", u"http://www.gocomics.com/tankmcnamara"),
|
#(u"Skin Horse", u"http://www.gocomics.com/skinhorse"),
|
||||||
# (u"Tiny Sepuku", u"http://www.gocomics.com/tinysepuku"),
|
#(u"Slowpoke", u"http://www.gocomics.com/slowpoke"),
|
||||||
# (u"TOBY", u"http://www.gocomics.com/toby"),
|
#(u"Soup To Nutz", u"http://www.gocomics.com/souptonutz"),
|
||||||
# (u"Tom the Dancing Bug", u"http://www.gocomics.com/tomthedancingbug"),
|
#(u"Speed Bump", u"http://www.gocomics.com/speedbump"),
|
||||||
# (u"Too Much Coffee Man", u"http://www.gocomics.com/toomuchcoffeeman"),
|
#(u"Spot The Frog", u"http://www.gocomics.com/spotthefrog"),
|
||||||
# (u"W.T. Duck", u"http://www.gocomics.com/wtduck"),
|
#(u"State of the Union", u"http://www.gocomics.com/stateoftheunion"),
|
||||||
# (u"Watch Your Head", u"http://www.gocomics.com/watchyourhead"),
|
#(u"Stone Soup", u"http://www.gocomics.com/stonesoup"),
|
||||||
# (u"Wee Pals", u"http://www.gocomics.com/weepals"),
|
#(u"Strange Brew", u"http://www.gocomics.com/strangebrew"),
|
||||||
# (u"Winnie the Pooh", u"http://www.gocomics.com/winniethepooh"),
|
#(u"Sylvia", u"http://www.gocomics.com/sylvia"),
|
||||||
(u"Wizard of Id", u"http://www.gocomics.com/wizardofid"),
|
#(u"Tank McNamara", u"http://www.gocomics.com/tankmcnamara"),
|
||||||
# (u"Working It Out", u"http://www.gocomics.com/workingitout"),
|
#(u"Tarzan Classics", u"http://www.gocomics.com/tarzanclassics"),
|
||||||
# (u"Yenny", u"http://www.gocomics.com/yenny"),
|
#(u"That's Life", u"http://www.gocomics.com/thatslife"),
|
||||||
# (u"Zack Hill", u"http://www.gocomics.com/zackhill"),
|
#(u"The Academia Waltz", u"http://www.gocomics.com/academiawaltz"),
|
||||||
|
#(u"The Argyle Sweater", u"http://www.gocomics.com/theargylesweater"),
|
||||||
|
#(u"The Barn", u"http://www.gocomics.com/thebarn"),
|
||||||
|
#(u"The Boiling Point", u"http://www.gocomics.com/theboilingpoint"),
|
||||||
|
#(u"The Boondocks", u"http://www.gocomics.com/boondocks"),
|
||||||
|
#(u"The Born Loser", u"http://www.gocomics.com/thebornloser"),
|
||||||
|
#(u"The Buckets", u"http://www.gocomics.com/thebuckets"),
|
||||||
|
#(u"The City", u"http://www.gocomics.com/thecity"),
|
||||||
|
#(u"The Dinette Set", u"http://www.gocomics.com/dinetteset"),
|
||||||
|
#(u"The Doozies", u"http://www.gocomics.com/thedoozies"),
|
||||||
|
#(u"The Duplex", u"http://www.gocomics.com/duplex"),
|
||||||
|
#(u"The Elderberries", u"http://www.gocomics.com/theelderberries"),
|
||||||
|
#(u"The Flying McCoys", u"http://www.gocomics.com/theflyingmccoys"),
|
||||||
|
#(u"The Fusco Brothers", u"http://www.gocomics.com/thefuscobrothers"),
|
||||||
|
#(u"The Grizzwells", u"http://www.gocomics.com/thegrizzwells"),
|
||||||
|
#(u"The Humble Stumble", u"http://www.gocomics.com/thehumblestumble"),
|
||||||
|
#(u"The Knight Life", u"http://www.gocomics.com/theknightlife"),
|
||||||
|
#(u"The Meaning of Lila", u"http://www.gocomics.com/meaningoflila"),
|
||||||
|
#(u"The Middletons", u"http://www.gocomics.com/themiddletons"),
|
||||||
|
#(u"The Norm", u"http://www.gocomics.com/thenorm"),
|
||||||
|
#(u"The Other Coast", u"http://www.gocomics.com/theothercoast"),
|
||||||
|
#(u"The Quigmans", u"http://www.gocomics.com/thequigmans"),
|
||||||
|
#(u"The Sunshine Club", u"http://www.gocomics.com/thesunshineclub"),
|
||||||
|
#(u"Tiny Sepuk", u"http://www.gocomics.com/tinysepuk"),
|
||||||
|
#(u"TOBY", u"http://www.gocomics.com/toby"),
|
||||||
|
#(u"Tom the Dancing Bug", u"http://www.gocomics.com/tomthedancingbug"),
|
||||||
|
#(u"Too Much Coffee Man", u"http://www.gocomics.com/toomuchcoffeeman"),
|
||||||
|
#(u"Unstrange Phenomena", u"http://www.gocomics.com/unstrangephenomena"),
|
||||||
|
#(u"W.T. Duck", u"http://www.gocomics.com/wtduck"),
|
||||||
|
#(u"Watch Your Head", u"http://www.gocomics.com/watchyourhead"),
|
||||||
|
#(u"Wee Pals", u"http://www.gocomics.com/weepals"),
|
||||||
|
#(u"Winnie the Pooh", u"http://www.gocomics.com/winniethepooh"),
|
||||||
|
#(u"Wizard of Id", u"http://www.gocomics.com/wizardofid"),
|
||||||
|
#(u"Working Daze", u"http://www.gocomics.com/workingdaze"),
|
||||||
|
#(u"Working It Out", u"http://www.gocomics.com/workingitout"),
|
||||||
|
#(u"Yenny", u"http://www.gocomics.com/yenny"),
|
||||||
|
#(u"Zack Hill", u"http://www.gocomics.com/zackhill"),
|
||||||
(u"Ziggy", u"http://www.gocomics.com/ziggy"),
|
(u"Ziggy", u"http://www.gocomics.com/ziggy"),
|
||||||
######## COMICS - EDITORIAL ########
|
#
|
||||||
("Lalo Alcaraz","http://www.gocomics.com/laloalcaraz"),
|
######## EDITORIAL CARTOONS #####################
|
||||||
("Nick Anderson","http://www.gocomics.com/nickanderson"),
|
(u"Adam Zyglis", u"http://www.gocomics.com/adamzyglis"),
|
||||||
("Chuck Asay","http://www.gocomics.com/chuckasay"),
|
#(u"Andy Singer", u"http://www.gocomics.com/andysinger"),
|
||||||
("Tony Auth","http://www.gocomics.com/tonyauth"),
|
#(u"Ben Sargent",u"http://www.gocomics.com/bensargent"),
|
||||||
("Donna Barstow","http://www.gocomics.com/donnabarstow"),
|
#(u"Bill Day", u"http://www.gocomics.com/billday"),
|
||||||
# ("Bruce Beattie","http://www.gocomics.com/brucebeattie"),
|
#(u"Bill Schorr", u"http://www.gocomics.com/billschorr"),
|
||||||
# ("Clay Bennett","http://www.gocomics.com/claybennett"),
|
#(u"Bob Englehart", u"http://www.gocomics.com/bobenglehart"),
|
||||||
# ("Lisa Benson","http://www.gocomics.com/lisabenson"),
|
(u"Bob Gorrell",u"http://www.gocomics.com/bobgorrell"),
|
||||||
# ("Steve Benson","http://www.gocomics.com/stevebenson"),
|
#(u"Brian Fairrington", u"http://www.gocomics.com/brianfairrington"),
|
||||||
# ("Chip Bok","http://www.gocomics.com/chipbok"),
|
#(u"Bruce Beattie", u"http://www.gocomics.com/brucebeattie"),
|
||||||
# ("Steve Breen","http://www.gocomics.com/stevebreen"),
|
#(u"Cam Cardow", u"http://www.gocomics.com/camcardow"),
|
||||||
# ("Chris Britt","http://www.gocomics.com/chrisbritt"),
|
#(u"Chan Lowe",u"http://www.gocomics.com/chanlowe"),
|
||||||
# ("Stuart Carlson","http://www.gocomics.com/stuartcarlson"),
|
#(u"Chip Bok",u"http://www.gocomics.com/chipbok"),
|
||||||
# ("Ken Catalino","http://www.gocomics.com/kencatalino"),
|
#(u"Chris Britt",u"http://www.gocomics.com/chrisbritt"),
|
||||||
# ("Paul Conrad","http://www.gocomics.com/paulconrad"),
|
#(u"Chuck Asay",u"http://www.gocomics.com/chuckasay"),
|
||||||
# ("Jeff Danziger","http://www.gocomics.com/jeffdanziger"),
|
#(u"Clay Bennett",u"http://www.gocomics.com/claybennett"),
|
||||||
# ("Matt Davies","http://www.gocomics.com/mattdavies"),
|
#(u"Clay Jones",u"http://www.gocomics.com/clayjones"),
|
||||||
# ("John Deering","http://www.gocomics.com/johndeering"),
|
#(u"Dan Wasserman",u"http://www.gocomics.com/danwasserman"),
|
||||||
# ("Bob Gorrell","http://www.gocomics.com/bobgorrell"),
|
#(u"Dana Summers",u"http://www.gocomics.com/danasummers"),
|
||||||
# ("Walt Handelsman","http://www.gocomics.com/walthandelsman"),
|
#(u"Daryl Cagle", u"http://www.gocomics.com/darylcagle"),
|
||||||
# ("Clay Jones","http://www.gocomics.com/clayjones"),
|
#(u"David Fitzsimmons", u"http://www.gocomics.com/davidfitzsimmons"),
|
||||||
# ("Kevin Kallaugher","http://www.gocomics.com/kevinkallaugher"),
|
(u"Dick Locher",u"http://www.gocomics.com/dicklocher"),
|
||||||
# ("Steve Kelley","http://www.gocomics.com/stevekelley"),
|
#(u"Don Wright",u"http://www.gocomics.com/donwright"),
|
||||||
# ("Dick Locher","http://www.gocomics.com/dicklocher"),
|
#(u"Donna Barstow",u"http://www.gocomics.com/donnabarstow"),
|
||||||
# ("Chan Lowe","http://www.gocomics.com/chanlowe"),
|
#(u"Drew Litton", u"http://www.gocomics.com/drewlitton"),
|
||||||
# ("Mike Luckovich","http://www.gocomics.com/mikeluckovich"),
|
#(u"Drew Sheneman",u"http://www.gocomics.com/drewsheneman"),
|
||||||
# ("Gary Markstein","http://www.gocomics.com/garymarkstein"),
|
#(u"Ed Stein", u"http://www.gocomics.com/edstein"),
|
||||||
# ("Glenn McCoy","http://www.gocomics.com/glennmccoy"),
|
#(u"Eric Allie", u"http://www.gocomics.com/ericallie"),
|
||||||
# ("Jim Morin","http://www.gocomics.com/jimmorin"),
|
#(u"Gary Markstein", u"http://www.gocomics.com/garymarkstein"),
|
||||||
# ("Jack Ohman","http://www.gocomics.com/jackohman"),
|
#(u"Gary McCoy", u"http://www.gocomics.com/garymccoy"),
|
||||||
# ("Pat Oliphant","http://www.gocomics.com/patoliphant"),
|
#(u"Gary Varvel", u"http://www.gocomics.com/garyvarvel"),
|
||||||
# ("Joel Pett","http://www.gocomics.com/joelpett"),
|
#(u"Glenn McCoy",u"http://www.gocomics.com/glennmccoy"),
|
||||||
# ("Ted Rall","http://www.gocomics.com/tedrall"),
|
#(u"Henry Payne", u"http://www.gocomics.com/henrypayne"),
|
||||||
# ("Michael Ramirez","http://www.gocomics.com/michaelramirez"),
|
#(u"Jack Ohman",u"http://www.gocomics.com/jackohman"),
|
||||||
# ("Marshall Ramsey","http://www.gocomics.com/marshallramsey"),
|
#(u"JD Crowe", u"http://www.gocomics.com/jdcrowe"),
|
||||||
# ("Steve Sack","http://www.gocomics.com/stevesack"),
|
#(u"Jeff Danziger",u"http://www.gocomics.com/jeffdanziger"),
|
||||||
# ("Ben Sargent","http://www.gocomics.com/bensargent"),
|
#(u"Jeff Parker", u"http://www.gocomics.com/jeffparker"),
|
||||||
# ("Drew Sheneman","http://www.gocomics.com/drewsheneman"),
|
#(u"Jeff Stahler", u"http://www.gocomics.com/jeffstahler"),
|
||||||
# ("John Sherffius","http://www.gocomics.com/johnsherffius"),
|
#(u"Jerry Holbert", u"http://www.gocomics.com/jerryholbert"),
|
||||||
# ("Small World","http://www.gocomics.com/smallworld"),
|
#(u"Jim Morin",u"http://www.gocomics.com/jimmorin"),
|
||||||
# ("Scott Stantis","http://www.gocomics.com/scottstantis"),
|
#(u"Joel Pett",u"http://www.gocomics.com/joelpett"),
|
||||||
# ("Wayne Stayskal","http://www.gocomics.com/waynestayskal"),
|
#(u"John Cole", u"http://www.gocomics.com/johncole"),
|
||||||
# ("Dana Summers","http://www.gocomics.com/danasummers"),
|
#(u"John Darkow", u"http://www.gocomics.com/johndarkow"),
|
||||||
# ("Paul Szep","http://www.gocomics.com/paulszep"),
|
#(u"John Deering",u"http://www.gocomics.com/johndeering"),
|
||||||
# ("Mike Thompson","http://www.gocomics.com/mikethompson"),
|
#(u"John Sherffius", u"http://www.gocomics.com/johnsherffius"),
|
||||||
# ("Tom Toles","http://www.gocomics.com/tomtoles"),
|
#(u"Ken Catalino",u"http://www.gocomics.com/kencatalino"),
|
||||||
# ("Gary Varvel","http://www.gocomics.com/garyvarvel"),
|
#(u"Kerry Waghorn",u"http://www.gocomics.com/facesinthenews"),
|
||||||
# ("ViewsAfrica","http://www.gocomics.com/viewsafrica"),
|
#(u"Kevin Kallaugher",u"http://www.gocomics.com/kevinkallaugher"),
|
||||||
# ("ViewsAmerica","http://www.gocomics.com/viewsamerica"),
|
#(u"Lalo Alcaraz",u"http://www.gocomics.com/laloalcaraz"),
|
||||||
# ("ViewsAsia","http://www.gocomics.com/viewsasia"),
|
#(u"Larry Wright", u"http://www.gocomics.com/larrywright"),
|
||||||
# ("ViewsBusiness","http://www.gocomics.com/viewsbusiness"),
|
#(u"Lisa Benson", u"http://www.gocomics.com/lisabenson"),
|
||||||
# ("ViewsEurope","http://www.gocomics.com/viewseurope"),
|
#(u"Marshall Ramsey", u"http://www.gocomics.com/marshallramsey"),
|
||||||
# ("ViewsLatinAmerica","http://www.gocomics.com/viewslatinamerica"),
|
#(u"Matt Bors", u"http://www.gocomics.com/mattbors"),
|
||||||
# ("ViewsMidEast","http://www.gocomics.com/viewsmideast"),
|
#(u"Matt Davies",u"http://www.gocomics.com/mattdavies"),
|
||||||
# ("Views of the World","http://www.gocomics.com/viewsoftheworld"),
|
#(u"Michael Ramirez", u"http://www.gocomics.com/michaelramirez"),
|
||||||
# ("Kerry Waghorn","http://www.gocomics.com/facesinthenews"),
|
#(u"Mike Keefe", u"http://www.gocomics.com/mikekeefe"),
|
||||||
# ("Dan Wasserman","http://www.gocomics.com/danwasserman"),
|
#(u"Mike Luckovich", u"http://www.gocomics.com/mikeluckovich"),
|
||||||
# ("Signe Wilkinson","http://www.gocomics.com/signewilkinson"),
|
#(u"MIke Thompson", u"http://www.gocomics.com/mikethompson"),
|
||||||
# ("Wit of the World","http://www.gocomics.com/witoftheworld"),
|
#(u"Monte Wolverton", u"http://www.gocomics.com/montewolverton"),
|
||||||
# ("Don Wright","http://www.gocomics.com/donwright"),
|
#(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;}
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
BIN
recipes/icons/ambito_financiero.png
Normal file
BIN
recipes/icons/ambito_financiero.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 508 B |
BIN
recipes/icons/observatorul_cultural.png
Normal file
BIN
recipes/icons/observatorul_cultural.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
BIN
recipes/icons/stiintasitehnica.png
Normal file
BIN
recipes/icons/stiintasitehnica.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 703 B |
45
recipes/metro_news_nl.recipe
Normal file
45
recipes/metro_news_nl.recipe
Normal 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')
|
||||||
|
]
|
42
recipes/nme.recipe
Normal file
42
recipes/nme.recipe
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
|
class AdvancedUserRecipe1306061239(BasicNewsRecipe):
|
||||||
|
title = u'New Musical Express Magazine'
|
||||||
|
__author__ = "scissors"
|
||||||
|
language = 'en'
|
||||||
|
remove_empty_feeds = True
|
||||||
|
remove_javascript = True
|
||||||
|
no_stylesheets = True
|
||||||
|
oldest_article = 7
|
||||||
|
max_articles_per_feed = 100
|
||||||
|
cover_url = 'http://tawanda3000.files.wordpress.com/2011/02/nme-logo.jpg'
|
||||||
|
|
||||||
|
remove_tags = [
|
||||||
|
dict( attrs={'class':'clear_icons'}),
|
||||||
|
dict( attrs={'class':'share_links'}),
|
||||||
|
dict( attrs={'id':'right_panel'}),
|
||||||
|
dict( attrs={'class':'today box'})
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
|
keep_only_tags = [
|
||||||
|
|
||||||
|
dict(name='h1'),
|
||||||
|
#dict(name='h3'),
|
||||||
|
dict(attrs={'class' : 'BText'}),
|
||||||
|
dict(attrs={'class' : 'Bmore'}),
|
||||||
|
dict(attrs={'class' : 'bPosts'}),
|
||||||
|
dict(attrs={'class' : 'text'}),
|
||||||
|
dict(attrs={'id' : 'article_gallery'}),
|
||||||
|
dict(attrs={'class' : 'article_text'})
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
feeds = [
|
||||||
|
(u'NME News', u'http://feeds2.feedburner.com/nmecom/rss/newsxml'),
|
||||||
|
(u'Reviews', u'http://feeds2.feedburner.com/nme/SdML'),
|
||||||
|
(u'Blogs', u'http://www.nme.com/blog/index.php?blog=140&tempskin=_rss2'),
|
||||||
|
|
||||||
|
]
|
56
recipes/stiintasitehnica.recipe
Normal file
56
recipes/stiintasitehnica.recipe
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
__license__ = 'GPL v3'
|
||||||
|
__copyright__ = u'2011, Silviu Cotoar\u0103'
|
||||||
|
'''
|
||||||
|
stiintasitehnica.com
|
||||||
|
'''
|
||||||
|
|
||||||
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
|
class Stiintasitehnica(BasicNewsRecipe):
|
||||||
|
title = u'\u0218tiin\u021b\u0103 \u015fi Tehnic\u0103'
|
||||||
|
__author__ = u'Silviu Cotoar\u0103'
|
||||||
|
description = u'\u0218tiin\u021b\u0103 \u015fi Tehnic\u0103'
|
||||||
|
publisher = u'\u0218tiin\u021b\u0103 \u015fi Tehnic\u0103'
|
||||||
|
oldest_article = 50
|
||||||
|
language = 'ro'
|
||||||
|
max_articles_per_feed = 100
|
||||||
|
no_stylesheets = True
|
||||||
|
use_embedded_content = False
|
||||||
|
category = u'Ziare,Reviste,Stiinta,Tehnica'
|
||||||
|
encoding = 'utf-8'
|
||||||
|
cover_url = 'http://www.stiintasitehnica.com/images/logo.jpg'
|
||||||
|
|
||||||
|
conversion_options = {
|
||||||
|
'comments' : description
|
||||||
|
,'tags' : category
|
||||||
|
,'language' : language
|
||||||
|
,'publisher' : publisher
|
||||||
|
}
|
||||||
|
|
||||||
|
keep_only_tags = [
|
||||||
|
dict(name='div', attrs={'id':'mainColumn2'})
|
||||||
|
]
|
||||||
|
|
||||||
|
remove_tags = [
|
||||||
|
dict(name='span', attrs={'class':['redEar']})
|
||||||
|
, dict(name='table', attrs={'class':['connect_widget_interactive_area']})
|
||||||
|
, dict(name='div', attrs={'class':['panel-overlay']})
|
||||||
|
, dict(name='div', attrs={'id':['pointer']})
|
||||||
|
, dict(name='img', attrs={'class':['nav-next', 'nav-prev']})
|
||||||
|
, dict(name='table', attrs={'class':['connect_widget_interactive_area']})
|
||||||
|
, dict(name='hr', attrs={'class':['dotted']})
|
||||||
|
]
|
||||||
|
|
||||||
|
remove_tags_after = [
|
||||||
|
dict(name='hr', attrs={'class':['dotted']})
|
||||||
|
]
|
||||||
|
|
||||||
|
feeds = [
|
||||||
|
(u'Feeds', u'http://www.stiintasitehnica.com/rss/stiri.xml')
|
||||||
|
]
|
||||||
|
|
||||||
|
def preprocess_html(self, soup):
|
||||||
|
return self.adeify_images(soup)
|
@ -93,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,
|
||||||
|
@ -4,7 +4,7 @@ __license__ = 'GPL v3'
|
|||||||
__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net'
|
__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net'
|
||||||
__docformat__ = 'restructuredtext en'
|
__docformat__ = 'restructuredtext en'
|
||||||
__appname__ = u'calibre'
|
__appname__ = u'calibre'
|
||||||
numeric_version = (0, 8, 4)
|
numeric_version = (0, 8, 5)
|
||||||
__version__ = u'.'.join(map(unicode, numeric_version))
|
__version__ = u'.'.join(map(unicode, numeric_version))
|
||||||
__author__ = u"Kovid Goyal <kovid@kovidgoyal.net>"
|
__author__ = u"Kovid Goyal <kovid@kovidgoyal.net>"
|
||||||
|
|
||||||
|
@ -355,11 +355,17 @@ def remove_plugin(plugin_or_name):
|
|||||||
name = getattr(plugin_or_name, 'name', plugin_or_name)
|
name = getattr(plugin_or_name, 'name', plugin_or_name)
|
||||||
plugins = config['plugins']
|
plugins = config['plugins']
|
||||||
removed = False
|
removed = False
|
||||||
if name in plugins.keys():
|
if name in plugins:
|
||||||
removed = True
|
removed = True
|
||||||
|
try:
|
||||||
|
zfp = os.path.join(plugin_dir, name+'.zip')
|
||||||
|
if os.path.exists(zfp):
|
||||||
|
os.remove(zfp)
|
||||||
zfp = plugins[name]
|
zfp = plugins[name]
|
||||||
if os.path.exists(zfp):
|
if os.path.exists(zfp):
|
||||||
os.remove(zfp)
|
os.remove(zfp)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
plugins.pop(name)
|
plugins.pop(name)
|
||||||
config['plugins'] = plugins
|
config['plugins'] = plugins
|
||||||
initialize_plugins()
|
initialize_plugins()
|
||||||
@ -495,8 +501,15 @@ def initialize_plugins():
|
|||||||
builtin_names]
|
builtin_names]
|
||||||
for p in conflicts:
|
for p in conflicts:
|
||||||
remove_plugin(p)
|
remove_plugin(p)
|
||||||
for zfp in list(config['plugins'].itervalues()) + builtin_plugins:
|
external_plugins = config['plugins']
|
||||||
|
for zfp in list(external_plugins) + builtin_plugins:
|
||||||
try:
|
try:
|
||||||
|
if not isinstance(zfp, type):
|
||||||
|
# We have a plugin name
|
||||||
|
pname = zfp
|
||||||
|
zfp = os.path.join(plugin_dir, zfp+'.zip')
|
||||||
|
if not os.path.exists(zfp):
|
||||||
|
zfp = external_plugins[pname]
|
||||||
try:
|
try:
|
||||||
plugin = load_plugin(zfp) if not isinstance(zfp, type) else zfp
|
plugin = load_plugin(zfp) if not isinstance(zfp, type) else zfp
|
||||||
except PluginNotFound:
|
except PluginNotFound:
|
||||||
|
@ -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',
|
||||||
|
@ -21,7 +21,7 @@ class KOBO(USBMS):
|
|||||||
name = 'Kobo Reader Device Interface'
|
name = 'Kobo Reader Device Interface'
|
||||||
gui_name = 'Kobo Reader'
|
gui_name = 'Kobo Reader'
|
||||||
description = _('Communicate with the Kobo Reader')
|
description = _('Communicate with the Kobo Reader')
|
||||||
author = 'Timothy Legge and Kovid Goyal'
|
author = 'Timothy Legge'
|
||||||
version = (1, 0, 9)
|
version = (1, 0, 9)
|
||||||
|
|
||||||
dbversion = 0
|
dbversion = 0
|
||||||
@ -37,8 +37,8 @@ class KOBO(USBMS):
|
|||||||
CAN_SET_METADATA = ['collections']
|
CAN_SET_METADATA = ['collections']
|
||||||
|
|
||||||
VENDOR_ID = [0x2237]
|
VENDOR_ID = [0x2237]
|
||||||
PRODUCT_ID = [0x4161]
|
PRODUCT_ID = [0x4161, 0x4163]
|
||||||
BCD = [0x0110, 0x0323]
|
BCD = [0x0110, 0x0323, 0x0326]
|
||||||
|
|
||||||
VENDOR_NAME = ['KOBO_INC', 'KOBO']
|
VENDOR_NAME = ['KOBO_INC', 'KOBO']
|
||||||
WINDOWS_MAIN_MEM = WINDOWS_CARD_A_MEM = ['.KOBOEREADER', 'EREADER']
|
WINDOWS_MAIN_MEM = WINDOWS_CARD_A_MEM = ['.KOBOEREADER', 'EREADER']
|
||||||
|
@ -77,7 +77,6 @@ class NOOK(USBMS):
|
|||||||
with open('%s.jpg' % os.path.join(path, filename), 'wb') as coverfile:
|
with open('%s.jpg' % os.path.join(path, filename), 'wb') as coverfile:
|
||||||
coverfile.write(coverdata)
|
coverfile.write(coverdata)
|
||||||
|
|
||||||
|
|
||||||
def sanitize_path_components(self, components):
|
def sanitize_path_components(self, components):
|
||||||
return [x.replace('#', '_') for x in components]
|
return [x.replace('#', '_') for x in components]
|
||||||
|
|
||||||
@ -110,6 +109,11 @@ class NOOK_COLOR(NOOK):
|
|||||||
def upload_cover(self, path, filename, metadata, filepath):
|
def upload_cover(self, path, filename, metadata, filepath):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def get_carda_ebook_dir(self, for_upload=False):
|
||||||
|
if for_upload:
|
||||||
|
return 'My Files/Books'
|
||||||
|
return ''
|
||||||
|
|
||||||
class NOOK_TSR(NOOK):
|
class NOOK_TSR(NOOK):
|
||||||
gui_name = _('Nook Simple')
|
gui_name = _('Nook Simple')
|
||||||
description = _('Communicate with the Nook TSR eBook reader.')
|
description = _('Communicate with the Nook TSR eBook reader.')
|
||||||
@ -117,9 +121,15 @@ class NOOK_TSR(NOOK):
|
|||||||
PRODUCT_ID = [0x003]
|
PRODUCT_ID = [0x003]
|
||||||
BCD = [0x216]
|
BCD = [0x216]
|
||||||
|
|
||||||
EBOOK_DIR_MAIN = EBOOK_DIR_CARD_A = 'My Files/Books'
|
EBOOK_DIR_MAIN = 'My Files/Books'
|
||||||
WINDOWS_MAIN_MEM = WINDOWS_CARD_A_MEM = 'EBOOK_DISK'
|
WINDOWS_MAIN_MEM = WINDOWS_CARD_A_MEM = 'EBOOK_DISK'
|
||||||
|
|
||||||
def upload_cover(self, path, filename, metadata, filepath):
|
def upload_cover(self, path, filename, metadata, filepath):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def get_carda_ebook_dir(self, for_upload=False):
|
||||||
|
if for_upload:
|
||||||
|
return 'My Files/Books'
|
||||||
|
return ''
|
||||||
|
|
||||||
|
|
||||||
|
@ -837,6 +837,9 @@ class Device(DeviceConfig, DevicePlugin):
|
|||||||
def get_main_ebook_dir(self, for_upload=False):
|
def get_main_ebook_dir(self, for_upload=False):
|
||||||
return self.EBOOK_DIR_MAIN
|
return self.EBOOK_DIR_MAIN
|
||||||
|
|
||||||
|
def get_carda_ebook_dir(self, for_upload=False):
|
||||||
|
return self.EBOOK_DIR_CARD_A
|
||||||
|
|
||||||
def _sanity_check(self, on_card, files):
|
def _sanity_check(self, on_card, files):
|
||||||
if on_card == 'carda' and not self._card_a_prefix:
|
if on_card == 'carda' and not self._card_a_prefix:
|
||||||
raise ValueError(_('The reader has no storage card in this slot.'))
|
raise ValueError(_('The reader has no storage card in this slot.'))
|
||||||
@ -847,7 +850,7 @@ class Device(DeviceConfig, DevicePlugin):
|
|||||||
|
|
||||||
if on_card == 'carda':
|
if on_card == 'carda':
|
||||||
path = os.path.join(self._card_a_prefix,
|
path = os.path.join(self._card_a_prefix,
|
||||||
*(self.EBOOK_DIR_CARD_A.split('/')))
|
*(self.get_carda_ebook_dir(for_upload=True).split('/')))
|
||||||
elif on_card == 'cardb':
|
elif on_card == 'cardb':
|
||||||
path = os.path.join(self._card_b_prefix,
|
path = os.path.join(self._card_b_prefix,
|
||||||
*(self.EBOOK_DIR_CARD_B.split('/')))
|
*(self.EBOOK_DIR_CARD_B.split('/')))
|
||||||
|
@ -132,7 +132,7 @@ class USBMS(CLI, Device):
|
|||||||
self._card_b_prefix if oncard == 'cardb' \
|
self._card_b_prefix if oncard == 'cardb' \
|
||||||
else self._main_prefix
|
else self._main_prefix
|
||||||
|
|
||||||
ebook_dirs = self.EBOOK_DIR_CARD_A if oncard == 'carda' else \
|
ebook_dirs = self.get_carda_ebook_dir() if oncard == 'carda' else \
|
||||||
self.EBOOK_DIR_CARD_B if oncard == 'cardb' else \
|
self.EBOOK_DIR_CARD_B if oncard == 'cardb' else \
|
||||||
self.get_main_ebook_dir()
|
self.get_main_ebook_dir()
|
||||||
|
|
||||||
|
@ -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:
|
||||||
|
@ -439,7 +439,8 @@ class EditMetadataAction(InterfaceAction):
|
|||||||
view.reset()
|
view.reset()
|
||||||
|
|
||||||
# Apply bulk metadata changes {{{
|
# Apply bulk metadata changes {{{
|
||||||
def apply_metadata_changes(self, id_map, title=None, msg='', callback=None):
|
def apply_metadata_changes(self, id_map, title=None, msg='', callback=None,
|
||||||
|
merge_tags=True):
|
||||||
'''
|
'''
|
||||||
Apply the metadata changes in id_map to the database synchronously
|
Apply the metadata changes in id_map to the database synchronously
|
||||||
id_map must be a mapping of ids to Metadata objects. Set any fields you
|
id_map must be a mapping of ids to Metadata objects. Set any fields you
|
||||||
@ -466,9 +467,9 @@ class EditMetadataAction(InterfaceAction):
|
|||||||
cancelable=False)
|
cancelable=False)
|
||||||
self.apply_pd.setModal(True)
|
self.apply_pd.setModal(True)
|
||||||
self.apply_pd.show()
|
self.apply_pd.show()
|
||||||
|
self._am_merge_tags = True
|
||||||
self.do_one_apply()
|
self.do_one_apply()
|
||||||
|
|
||||||
|
|
||||||
def do_one_apply(self):
|
def do_one_apply(self):
|
||||||
if self.apply_current_idx >= len(self.apply_id_map):
|
if self.apply_current_idx >= len(self.apply_id_map):
|
||||||
return self.finalize_apply()
|
return self.finalize_apply()
|
||||||
@ -484,6 +485,12 @@ class EditMetadataAction(InterfaceAction):
|
|||||||
mi.identifiers = idents
|
mi.identifiers = idents
|
||||||
if mi.is_null('series'):
|
if mi.is_null('series'):
|
||||||
mi.series_index = None
|
mi.series_index = None
|
||||||
|
if self._am_merge_tags:
|
||||||
|
old_tags = db.tags(i, index_is_id=True)
|
||||||
|
if old_tags:
|
||||||
|
tags = [x.strip() for x in old_tags.split(',')] + (
|
||||||
|
mi.tags if mi.tags else [])
|
||||||
|
mi.tags = list(set(tags))
|
||||||
db.set_metadata(i, mi, commit=False, set_title=set_title,
|
db.set_metadata(i, mi, commit=False, set_title=set_title,
|
||||||
set_authors=set_authors, notify=False)
|
set_authors=set_authors, notify=False)
|
||||||
self.applied_ids.append(i)
|
self.applied_ids.append(i)
|
||||||
|
@ -33,7 +33,6 @@ class SaveMenu(QMenu): # {{{
|
|||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
|
|
||||||
class SaveToDiskAction(InterfaceAction):
|
class SaveToDiskAction(InterfaceAction):
|
||||||
|
|
||||||
name = "Save To Disk"
|
name = "Save To Disk"
|
||||||
|
@ -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>
|
||||||
|
@ -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'):
|
||||||
|
if not empty:
|
||||||
error_dialog(self, _('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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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,13 +1061,71 @@ 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):
|
||||||
|
d = ISBNDialog(self, text)
|
||||||
|
if not d.exec_():
|
||||||
|
return
|
||||||
|
text = d.text()
|
||||||
|
if not text:
|
||||||
|
return
|
||||||
vals = self.current_val
|
vals = self.current_val
|
||||||
vals['isbn'] = text
|
vals['isbn'] = text
|
||||||
self.current_val = vals
|
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())
|
||||||
|
|
||||||
|
# }}}
|
||||||
|
|
||||||
class PublisherEdit(MultiCompleteComboBox): # {{{
|
class PublisherEdit(MultiCompleteComboBox): # {{{
|
||||||
LABEL = _('&Publisher:')
|
LABEL = _('&Publisher:')
|
||||||
|
|
||||||
|
@ -315,7 +315,7 @@ class MetadataSingleDialogBase(ResizableDialog):
|
|||||||
show=True)
|
show=True)
|
||||||
return
|
return
|
||||||
|
|
||||||
def update_from_mi(self, mi, update_sorts=True):
|
def update_from_mi(self, mi, update_sorts=True, merge_tags=True):
|
||||||
if not mi.is_null('title'):
|
if not mi.is_null('title'):
|
||||||
self.title.current_val = mi.title
|
self.title.current_val = mi.title
|
||||||
if update_sorts:
|
if update_sorts:
|
||||||
@ -334,7 +334,11 @@ class MetadataSingleDialogBase(ResizableDialog):
|
|||||||
if not mi.is_null('publisher'):
|
if not mi.is_null('publisher'):
|
||||||
self.publisher.current_val = mi.publisher
|
self.publisher.current_val = mi.publisher
|
||||||
if not mi.is_null('tags'):
|
if not mi.is_null('tags'):
|
||||||
self.tags.current_val = mi.tags
|
old_tags = self.tags.current_val
|
||||||
|
tags = mi.tags if mi.tags else []
|
||||||
|
if old_tags and merge_tags:
|
||||||
|
tags += old_tags
|
||||||
|
self.tags.current_val = tags
|
||||||
if not mi.is_null('identifiers'):
|
if not mi.is_null('identifiers'):
|
||||||
current = self.identifiers.current_val
|
current = self.identifiers.current_val
|
||||||
current.update(mi.identifiers)
|
current.update(mi.identifiers)
|
||||||
|
@ -8,10 +8,11 @@ import os, math, re, glob, sys
|
|||||||
from base64 import b64encode
|
from base64 import b64encode
|
||||||
from functools import partial
|
from functools import partial
|
||||||
|
|
||||||
from PyQt4.Qt import QSize, QSizePolicy, QUrl, SIGNAL, Qt, QTimer, \
|
from PyQt4.Qt import (QSize, QSizePolicy, QUrl, SIGNAL, Qt, QTimer,
|
||||||
QPainter, QPalette, QBrush, QFontDatabase, QDialog, \
|
QPainter, QPalette, QBrush, QFontDatabase, QDialog,
|
||||||
QColor, QPoint, QImage, QRegion, QVariant, QIcon, \
|
QColor, QPoint, QImage, QRegion, QVariant, QIcon,
|
||||||
QFont, pyqtSignature, QAction, QByteArray, QMenu
|
QFont, pyqtSignature, QAction, QByteArray, QMenu,
|
||||||
|
pyqtSignal)
|
||||||
from PyQt4.QtWebKit import QWebPage, QWebView, QWebSettings
|
from PyQt4.QtWebKit import QWebPage, QWebView, QWebSettings
|
||||||
|
|
||||||
from calibre.utils.config import Config, StringConfig
|
from calibre.utils.config import Config, StringConfig
|
||||||
@ -496,6 +497,7 @@ class EntityDeclarationProcessor(object): # {{{
|
|||||||
|
|
||||||
class DocumentView(QWebView): # {{{
|
class DocumentView(QWebView): # {{{
|
||||||
|
|
||||||
|
magnification_changed = pyqtSignal(object)
|
||||||
DISABLED_BRUSH = QBrush(Qt.lightGray, Qt.Dense5Pattern)
|
DISABLED_BRUSH = QBrush(Qt.lightGray, Qt.Dense5Pattern)
|
||||||
|
|
||||||
def __init__(self, *args):
|
def __init__(self, *args):
|
||||||
@ -908,15 +910,22 @@ class DocumentView(QWebView): # {{{
|
|||||||
if notify and self.manager is not None and self.document.ypos != old_pos:
|
if notify and self.manager is not None and self.document.ypos != old_pos:
|
||||||
self.manager.scrolled(self.scroll_fraction)
|
self.manager.scrolled(self.scroll_fraction)
|
||||||
|
|
||||||
|
@dynamic_property
|
||||||
def multiplier(self):
|
def multiplier(self):
|
||||||
|
def fget(self):
|
||||||
return self.document.mainFrame().textSizeMultiplier()
|
return self.document.mainFrame().textSizeMultiplier()
|
||||||
|
def fset(self, val):
|
||||||
|
self.document.mainFrame().setTextSizeMultiplier(val)
|
||||||
|
self.magnification_changed.emit(val)
|
||||||
|
return property(fget=fget, fset=fset)
|
||||||
|
|
||||||
def magnify_fonts(self):
|
def magnify_fonts(self):
|
||||||
self.document.mainFrame().setTextSizeMultiplier(self.multiplier()+0.2)
|
self.multiplier += 0.2
|
||||||
return self.document.scroll_fraction
|
return self.document.scroll_fraction
|
||||||
|
|
||||||
def shrink_fonts(self):
|
def shrink_fonts(self):
|
||||||
self.document.mainFrame().setTextSizeMultiplier(max(self.multiplier()-0.2, 0))
|
if self.multiplier >= 0.2:
|
||||||
|
self.multiplier -= 0.2
|
||||||
return self.document.scroll_fraction
|
return self.document.scroll_fraction
|
||||||
|
|
||||||
def changeEvent(self, event):
|
def changeEvent(self, event):
|
||||||
|
@ -175,6 +175,7 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
|
|||||||
def __init__(self, pathtoebook=None, debug_javascript=False):
|
def __init__(self, pathtoebook=None, debug_javascript=False):
|
||||||
MainWindow.__init__(self, None)
|
MainWindow.__init__(self, None)
|
||||||
self.setupUi(self)
|
self.setupUi(self)
|
||||||
|
self.view.magnification_changed.connect(self.magnification_changed)
|
||||||
self.show_toc_on_open = False
|
self.show_toc_on_open = False
|
||||||
self.current_book_has_toc = False
|
self.current_book_has_toc = False
|
||||||
self.base_window_title = unicode(self.windowTitle())
|
self.base_window_title = unicode(self.windowTitle())
|
||||||
@ -345,6 +346,7 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
|
|||||||
if self.toc.isVisible():
|
if self.toc.isVisible():
|
||||||
vprefs.set('viewer_splitter_state',
|
vprefs.set('viewer_splitter_state',
|
||||||
bytearray(self.splitter.saveState()))
|
bytearray(self.splitter.saveState()))
|
||||||
|
vprefs['multiplier'] = self.view.multiplier
|
||||||
|
|
||||||
def restore_state(self):
|
def restore_state(self):
|
||||||
state = vprefs.get('viewer_toolbar_state', None)
|
state = vprefs.get('viewer_toolbar_state', None)
|
||||||
@ -354,6 +356,9 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
|
|||||||
self.restoreState(state, self.STATE_VERSION)
|
self.restoreState(state, self.STATE_VERSION)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
mult = vprefs.get('multiplier', None)
|
||||||
|
if mult:
|
||||||
|
self.view.multiplier = mult
|
||||||
|
|
||||||
|
|
||||||
def lookup(self, word):
|
def lookup(self, word):
|
||||||
@ -476,16 +481,22 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
|
|||||||
|
|
||||||
def font_size_larger(self, checked):
|
def font_size_larger(self, checked):
|
||||||
frac = self.view.magnify_fonts()
|
frac = self.view.magnify_fonts()
|
||||||
self.action_font_size_larger.setEnabled(self.view.multiplier() < 3)
|
self.action_font_size_larger.setEnabled(self.view.multiplier < 3)
|
||||||
self.action_font_size_smaller.setEnabled(self.view.multiplier() > 0.2)
|
self.action_font_size_smaller.setEnabled(self.view.multiplier > 0.2)
|
||||||
self.set_page_number(frac)
|
self.set_page_number(frac)
|
||||||
|
|
||||||
def font_size_smaller(self, checked):
|
def font_size_smaller(self, checked):
|
||||||
frac = self.view.shrink_fonts()
|
frac = self.view.shrink_fonts()
|
||||||
self.action_font_size_larger.setEnabled(self.view.multiplier() < 3)
|
self.action_font_size_larger.setEnabled(self.view.multiplier < 3)
|
||||||
self.action_font_size_smaller.setEnabled(self.view.multiplier() > 0.2)
|
self.action_font_size_smaller.setEnabled(self.view.multiplier > 0.2)
|
||||||
self.set_page_number(frac)
|
self.set_page_number(frac)
|
||||||
|
|
||||||
|
def magnification_changed(self, val):
|
||||||
|
tt = _('Make font size %s\nCurrent magnification: %.1f')
|
||||||
|
self.action_font_size_larger.setToolTip(
|
||||||
|
tt %(_('larger'), val))
|
||||||
|
self.action_font_size_smaller.setToolTip(
|
||||||
|
tt %(_('smaller'), val))
|
||||||
|
|
||||||
def find(self, text, repeat=False, backwards=False):
|
def find(self, text, repeat=False, backwards=False):
|
||||||
if not text:
|
if not text:
|
||||||
|
@ -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:
|
||||||
|
@ -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()
|
||||||
|
@ -319,7 +319,7 @@ but it requires that the Kindle be rebooted *every time* it is disconnected from
|
|||||||
changes to the collections to be recognized. As such, it is unlikely that
|
changes to the collections to be recognized. As such, it is unlikely that
|
||||||
any |app| developers will ever feel motivated enough to support it. There is however, a |app| plugin
|
any |app| developers will ever feel motivated enough to support it. There is however, a |app| plugin
|
||||||
that allows you to create collections on your Kindle from the |app| metadata. It is available
|
that allows you to create collections on your Kindle from the |app| metadata. It is available
|
||||||
`here <http://www.mobileread.com/forums/showthread.php?t=118635>`_.
|
`from here <http://www.mobileread.com/forums/showthread.php?t=118635>`_.
|
||||||
|
|
||||||
Library Management
|
Library Management
|
||||||
------------------
|
------------------
|
||||||
@ -570,7 +570,7 @@ For many reasons:
|
|||||||
* *There is no need to update every week*. If you are happy with how |app| works turn off the update notification and be on your merry way. Check back to see if you want to update once a year or so.
|
* *There is no need to update every week*. If you are happy with how |app| works turn off the update notification and be on your merry way. Check back to see if you want to update once a year or so.
|
||||||
* Pre downloading the updates for all users in the background would mean require about 80TB of bandwidth *every week*. That costs thousands of dollars a month. And |app| is currently growing at 300,000 new users every month.
|
* Pre downloading the updates for all users in the background would mean require about 80TB of bandwidth *every week*. That costs thousands of dollars a month. And |app| is currently growing at 300,000 new users every month.
|
||||||
* If I implement a dialog that downloads the update and launches it, instead of going to the website as it does now, that would save the most ardent |app| updater, *at most five clicks a week*. There are far higher priority things to do in |app| development.
|
* If I implement a dialog that downloads the update and launches it, instead of going to the website as it does now, that would save the most ardent |app| updater, *at most five clicks a week*. There are far higher priority things to do in |app| development.
|
||||||
* If you really, really hate downloading |app| every week but still want to be upto the latest, I encourage you to run from source, which makes updating trivial. Instructions are :ref:`here <develop>`.
|
* If you really, really hate downloading |app| every week but still want to be up to the latest, I encourage you to run from source, which makes updating trivial. Instructions are :ref:`available here <develop>`.
|
||||||
|
|
||||||
How is |app| licensed?
|
How is |app| licensed?
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
@ -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?
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
@ -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.
|
|
@ -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
|
||||||
|
|
||||||
|
@ -99,12 +99,12 @@ def test():
|
|||||||
test_lxml()
|
test_lxml()
|
||||||
test_fontconfig()
|
test_fontconfig()
|
||||||
test_sqlite()
|
test_sqlite()
|
||||||
if iswindows:
|
|
||||||
test_winutil()
|
|
||||||
test_win32()
|
|
||||||
test_qt()
|
test_qt()
|
||||||
test_imaging()
|
test_imaging()
|
||||||
test_unrar()
|
test_unrar()
|
||||||
|
if iswindows:
|
||||||
|
test_win32()
|
||||||
|
test_winutil()
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
test()
|
test()
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
17024
src/calibre/translations/az.po
Normal file
17024
src/calibre/translations/az.po
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user