mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Sync to trunk
This commit is contained in:
commit
e8226b8479
@ -38,6 +38,10 @@ def freeze():
|
|||||||
'/usr/lib/libxml2.so.2',
|
'/usr/lib/libxml2.so.2',
|
||||||
'/usr/lib/libxslt.so.1',
|
'/usr/lib/libxslt.so.1',
|
||||||
'/usr/lib/libxslt.so.1',
|
'/usr/lib/libxslt.so.1',
|
||||||
|
'/usr/lib/libgthread-2.0.so.0',
|
||||||
|
'/usr/lib/libglib-2.0.so.0',
|
||||||
|
'/usr/lib/gcc/i686-pc-linux-gnu/4.3.3/libstdc++.so.6',
|
||||||
|
'/usr/lib/libpng12.so.0',
|
||||||
'/usr/lib/libexslt.so.0',
|
'/usr/lib/libexslt.so.0',
|
||||||
'/usr/lib/libMagickWand.so',
|
'/usr/lib/libMagickWand.so',
|
||||||
'/usr/lib/libMagickCore.so',
|
'/usr/lib/libMagickCore.so',
|
||||||
|
@ -69,7 +69,7 @@ def sanitize_file_name(name, substitute='_', as_unicode=False):
|
|||||||
one = re.sub(r'^\.+$', '_', one)
|
one = re.sub(r'^\.+$', '_', one)
|
||||||
if as_unicode:
|
if as_unicode:
|
||||||
one = one.decode(filesystem_encoding)
|
one = one.decode(filesystem_encoding)
|
||||||
return one
|
return one.replace('..', '_')
|
||||||
|
|
||||||
|
|
||||||
class CommandLineError(Exception):
|
class CommandLineError(Exception):
|
||||||
@ -382,8 +382,10 @@ def walk(dir):
|
|||||||
for f in record[-1]:
|
for f in record[-1]:
|
||||||
yield os.path.join(record[0], f)
|
yield os.path.join(record[0], f)
|
||||||
|
|
||||||
def strftime(fmt, t=time.localtime()):
|
def strftime(fmt, t=None):
|
||||||
''' A version of strtime that returns unicode strings. '''
|
''' A version of strtime that returns unicode strings. '''
|
||||||
|
if t is None:
|
||||||
|
t = time.localtime()
|
||||||
if iswindows:
|
if iswindows:
|
||||||
if isinstance(fmt, unicode):
|
if isinstance(fmt, unicode):
|
||||||
fmt = fmt.encode('mbcs')
|
fmt = fmt.encode('mbcs')
|
||||||
|
@ -2,7 +2,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__ = 'calibre'
|
__appname__ = 'calibre'
|
||||||
__version__ = '0.4.136'
|
__version__ = '0.4.137'
|
||||||
__author__ = "Kovid Goyal <kovid@kovidgoyal.net>"
|
__author__ = "Kovid Goyal <kovid@kovidgoyal.net>"
|
||||||
'''
|
'''
|
||||||
Various run time constants.
|
Various run time constants.
|
||||||
|
@ -32,7 +32,7 @@ class PRS505(Device):
|
|||||||
BCD = [0x229] #: Needed to disambiguate 505 and 700 on linux
|
BCD = [0x229] #: Needed to disambiguate 505 and 700 on linux
|
||||||
PRODUCT_NAME = 'PRS-505'
|
PRODUCT_NAME = 'PRS-505'
|
||||||
VENDOR_NAME = 'SONY'
|
VENDOR_NAME = 'SONY'
|
||||||
FORMATS = ['lrf', 'epub', 'lrx', 'rtf', 'pdf', 'txt']
|
FORMATS = ['epub', 'lrf', 'lrx', 'rtf', 'pdf', 'txt']
|
||||||
|
|
||||||
MEDIA_XML = 'database/cache/media.xml'
|
MEDIA_XML = 'database/cache/media.xml'
|
||||||
CACHE_XML = 'Sony Reader/database/cache.xml'
|
CACHE_XML = 'Sony Reader/database/cache.xml'
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<?python
|
<?python
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
|
import re
|
||||||
?>
|
?>
|
||||||
<ncx version="2005-1"
|
<ncx version="2005-1"
|
||||||
xml:lang="en"
|
xml:lang="en"
|
||||||
@ -19,7 +20,7 @@ from uuid import uuid4
|
|||||||
<py:def function="navpoint(np, level)">
|
<py:def function="navpoint(np, level)">
|
||||||
${'%*s'%(4*level,'')}<navPoint id="${str(uuid4())}" playOrder="${str(np.play_order)}">
|
${'%*s'%(4*level,'')}<navPoint id="${str(uuid4())}" playOrder="${str(np.play_order)}">
|
||||||
${'%*s'%(4*level,'')}<navLabel>
|
${'%*s'%(4*level,'')}<navLabel>
|
||||||
${'%*s'%(4*level,'')}<text>${np.text}</text>
|
${'%*s'%(4*level,'')}<text>${re.sub(r'\s+', ' ', np.text)}</text>
|
||||||
${'%*s'%(4*level,'')}</navLabel>
|
${'%*s'%(4*level,'')}</navLabel>
|
||||||
${'%*s'%(4*level,'')}<content src="${unicode(np.href)+(('#' + unicode(np.fragment)) if np.fragment else '')}" />
|
${'%*s'%(4*level,'')}<content src="${unicode(np.href)+(('#' + unicode(np.fragment)) if np.fragment else '')}" />
|
||||||
<py:for each="np2 in np">${navpoint(np2, level+1)}</py:for>
|
<py:for each="np2 in np">${navpoint(np2, level+1)}</py:for>
|
||||||
|
@ -186,6 +186,8 @@ class MobiReader(object):
|
|||||||
self.processed_html = self.processed_html.decode(self.book_header.codec, 'ignore')
|
self.processed_html = self.processed_html.decode(self.book_header.codec, 'ignore')
|
||||||
for pat in ENCODING_PATS:
|
for pat in ENCODING_PATS:
|
||||||
self.processed_html = pat.sub('', self.processed_html)
|
self.processed_html = pat.sub('', self.processed_html)
|
||||||
|
self.processed_html = re.sub(r'&(\S+?);', entity_to_unicode,
|
||||||
|
self.processed_html)
|
||||||
self.extract_images(processed_records, output_dir)
|
self.extract_images(processed_records, output_dir)
|
||||||
self.replace_page_breaks()
|
self.replace_page_breaks()
|
||||||
self.cleanup_html()
|
self.cleanup_html()
|
||||||
@ -271,6 +273,8 @@ class MobiReader(object):
|
|||||||
for key in tag.attrib.keys():
|
for key in tag.attrib.keys():
|
||||||
tag.attrib.pop(key)
|
tag.attrib.pop(key)
|
||||||
continue
|
continue
|
||||||
|
if tag.tag == 'pre' and not tag.text:
|
||||||
|
tag.tag = 'div'
|
||||||
styles, attrib = [], tag.attrib
|
styles, attrib = [], tag.attrib
|
||||||
if attrib.has_key('style'):
|
if attrib.has_key('style'):
|
||||||
style = attrib.pop('style').strip()
|
style = attrib.pop('style').strip()
|
||||||
@ -452,6 +456,7 @@ class MobiReader(object):
|
|||||||
pos = end
|
pos = end
|
||||||
self.processed_html += self.mobi_html[pos:]
|
self.processed_html += self.mobi_html[pos:]
|
||||||
|
|
||||||
|
|
||||||
def extract_images(self, processed_records, output_dir):
|
def extract_images(self, processed_records, output_dir):
|
||||||
if self.verbose:
|
if self.verbose:
|
||||||
print 'Extracting images...'
|
print 'Extracting images...'
|
||||||
|
BIN
src/calibre/gui2/images/news/chicago_breaking_news.png
Normal file
BIN
src/calibre/gui2/images/news/chicago_breaking_news.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 704 B |
@ -245,7 +245,7 @@ class BooksModel(QAbstractTableModel):
|
|||||||
if num > 0:
|
if num > 0:
|
||||||
self.beginInsertRows(QModelIndex(), 0, num-1)
|
self.beginInsertRows(QModelIndex(), 0, num-1)
|
||||||
self.endInsertRows()
|
self.endInsertRows()
|
||||||
self.count_changed()
|
self.count_changed()
|
||||||
|
|
||||||
def search(self, text, refinement, reset=True):
|
def search(self, text, refinement, reset=True):
|
||||||
self.db.search(text)
|
self.db.search(text)
|
||||||
|
@ -330,12 +330,17 @@ class Main(MainWindow, Ui_MainWindow):
|
|||||||
self.cover_flow.setVisible(False)
|
self.cover_flow.setVisible(False)
|
||||||
if not config['separate_cover_flow']:
|
if not config['separate_cover_flow']:
|
||||||
self.library.layout().addWidget(self.cover_flow)
|
self.library.layout().addWidget(self.cover_flow)
|
||||||
self.connect(self.cover_flow, SIGNAL('currentChanged(int)'), self.sync_cf_to_listview)
|
self.connect(self.cover_flow, SIGNAL('currentChanged(int)'),
|
||||||
self.connect(self.cover_flow, SIGNAL('itemActivated(int)'), self.show_book_info)
|
self.sync_cf_to_listview)
|
||||||
self.connect(self.status_bar.cover_flow_button, SIGNAL('toggled(bool)'), self.toggle_cover_flow)
|
self.connect(self.cover_flow, SIGNAL('itemActivated(int)'),
|
||||||
self.connect(self.cover_flow, SIGNAL('stop()'), self.status_bar.cover_flow_button.toggle)
|
self.show_book_info)
|
||||||
QObject.connect(self.library_view.selectionModel(), SIGNAL('currentRowChanged(QModelIndex, QModelIndex)'),
|
self.connect(self.status_bar.cover_flow_button,
|
||||||
self.sync_cf_to_listview)
|
SIGNAL('toggled(bool)'), self.toggle_cover_flow)
|
||||||
|
self.connect(self.cover_flow, SIGNAL('stop()'),
|
||||||
|
self.status_bar.cover_flow_button.toggle)
|
||||||
|
QObject.connect(self.library_view.selectionModel(),
|
||||||
|
SIGNAL('currentRowChanged(QModelIndex, QModelIndex)'),
|
||||||
|
self.sync_cf_to_listview)
|
||||||
self.db_images = DatabaseImages(self.library_view.model())
|
self.db_images = DatabaseImages(self.library_view.model())
|
||||||
self.cover_flow.setImages(self.db_images)
|
self.cover_flow.setImages(self.db_images)
|
||||||
else:
|
else:
|
||||||
@ -482,7 +487,8 @@ class Main(MainWindow, Ui_MainWindow):
|
|||||||
if not hasattr(index, 'row') and self.library_view.currentIndex().row() != index:
|
if not hasattr(index, 'row') and self.library_view.currentIndex().row() != index:
|
||||||
index = self.library_view.model().index(index, 0)
|
index = self.library_view.model().index(index, 0)
|
||||||
self.library_view.setCurrentIndex(index)
|
self.library_view.setCurrentIndex(index)
|
||||||
if hasattr(index, 'row') and self.cover_flow.isVisible() and self.cover_flow.currentSlide() != index.row():
|
if hasattr(index, 'row') and self.cover_flow.isVisible() and \
|
||||||
|
self.cover_flow.currentSlide() != index.row():
|
||||||
self.cover_flow.setCurrentSlide(index.row())
|
self.cover_flow.setCurrentSlide(index.row())
|
||||||
|
|
||||||
def another_instance_wants_to_talk(self, msg):
|
def another_instance_wants_to_talk(self, msg):
|
||||||
@ -709,6 +715,7 @@ class Main(MainWindow, Ui_MainWindow):
|
|||||||
t.process_duplicates()
|
t.process_duplicates()
|
||||||
if t.number_of_books_added > 0:
|
if t.number_of_books_added > 0:
|
||||||
self.library_view.model().books_added(t.number_of_books_added)
|
self.library_view.model().books_added(t.number_of_books_added)
|
||||||
|
self.db_images.reset()
|
||||||
|
|
||||||
def upload_books(self, files, names, metadata, on_card=False, memory=None):
|
def upload_books(self, files, names, metadata, on_card=False, memory=None):
|
||||||
'''
|
'''
|
||||||
|
@ -28,7 +28,7 @@ What formats does |app| support conversion to/from?
|
|||||||
| | | | | |
|
| | | | | |
|
||||||
| | LIT | ✔ | ✔ | ✔ |
|
| | LIT | ✔ | ✔ | ✔ |
|
||||||
| | | | | |
|
| | | | | |
|
||||||
| | PRC | ✔ | ✔ | ✔ |
|
| | PRC** | ✔ | ✔ | ✔ |
|
||||||
| | | | | |
|
| | | | | |
|
||||||
| | EPUB | ✔ | ✔ | ✔ |
|
| | EPUB | ✔ | ✔ | ✔ |
|
||||||
| | | | | |
|
| | | | | |
|
||||||
@ -49,6 +49,7 @@ What formats does |app| support conversion to/from?
|
|||||||
| | LRS | | ✔ | |
|
| | LRS | | ✔ | |
|
||||||
+-------------------+--------+------------------+-----------------------+-----------------------+
|
+-------------------+--------+------------------+-----------------------+-----------------------+
|
||||||
|
|
||||||
|
** PRC is a generic format, |app| supports PRC files with TextRead and MOBIBook headers
|
||||||
|
|
||||||
|
|
||||||
What are the best source formats to convert?
|
What are the best source formats to convert?
|
||||||
@ -146,7 +147,7 @@ When you first run |app|, it will ask you for a folder in which to store your bo
|
|||||||
Why doesn't |app| let me store books in my own directory structure?
|
Why doesn't |app| let me store books in my own directory structure?
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
The whole point if |app|'s library management features is that they provide an interface for locating books that is *much* more efficient than any possible directory scheme you could come up with for your collection. Indeed, once you become comfortable using |app|'s interface to find, sort and browse your collection, you wont ever feel the need to hunt through the files on your disk to find a book again. By managing books in its own directory struture of Author -> Title -> Book files, |app| is able to achieve a high level of reliability and standardization.
|
The whole point of |app|'s library management features is that they provide an interface for locating books that is *much* more efficient than any possible directory scheme you could come up with for your collection. Indeed, once you become comfortable using |app|'s interface to find, sort and browse your collection, you wont ever feel the need to hunt through the files on your disk to find a book again. By managing books in its own directory struture of Author -> Title -> Book files, |app| is able to achieve a high level of reliability and standardization.
|
||||||
|
|
||||||
Why doesn't |app| have a column for foo?
|
Why doesn't |app| have a column for foo?
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
@ -1,419 +1,386 @@
|
|||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
|
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
|
||||||
import re
|
|
||||||
from pkg_resources import resource_filename
|
|
||||||
|
|
||||||
from trac.core import Component, implements
|
|
||||||
from trac.web.chrome import INavigationContributor, ITemplateProvider, add_stylesheet
|
|
||||||
from trac.web.main import IRequestHandler
|
|
||||||
from trac.util import Markup
|
|
||||||
|
|
||||||
|
|
||||||
__appname__ = 'calibre'
|
__appname__ = 'calibre'
|
||||||
DOWNLOAD_DIR = '/var/www/calibre.kovidgoyal.net/htdocs/downloads'
|
import re, textwrap
|
||||||
MOBILEREAD = 'https://dev.mobileread.com/dist/kovid/calibre/'
|
|
||||||
|
|
||||||
class OS(dict):
|
DEPENDENCIES = [
|
||||||
"""Dictionary with a default value for unknown keys."""
|
#(Generic, version, gentoo, ubuntu, fedora)
|
||||||
def __init__(self, dict):
|
('python', '2.5', None, None, None),
|
||||||
self.update(dict)
|
('setuptools', '0.6c5', 'setuptools', 'python-setuptools', 'python-setuptools-devel'),
|
||||||
if not dict.has_key('img'):
|
('Python Imaging Library', '1.1.6', 'imaging', 'python-imaging', 'python-imaging'),
|
||||||
self['img'] = self['name']
|
('libusb', '0.1.12', None, None, None),
|
||||||
|
('Qt', '4.4.0', 'qt', 'libqt4-core libqt4-gui', 'qt4'),
|
||||||
|
('PyQt', '4.4.2', 'PyQt4', 'python-qt4', 'PyQt4'),
|
||||||
|
('python-mechanize', '0.1.11', 'dev-python/mechanize', 'python-mechanize', 'python-mechanize'),
|
||||||
|
('ImageMagick', '6.3.5', 'imagemagick', 'imagemagick', 'ImageMagick'),
|
||||||
|
('xdg-utils', '1.0.2', 'xdg-utils', 'xdg-utils', 'xdg-utils'),
|
||||||
|
('dbus-python', '0.82.2', 'dbus-python', 'python-dbus', 'dbus-python'),
|
||||||
|
('lxml', '2.0.5', 'lxml', 'python-lxml', 'python-lxml'),
|
||||||
|
('python-dateutil', '1.4.1', 'python-dateutil', 'python-dateutil', 'python-dateutil'),
|
||||||
|
('BeautifulSoup', '3.0.5', 'beautifulsoup', 'python-beautifulsoup', 'python-BeautifulSoup'),
|
||||||
|
('help2man', '1.36.4', 'help2man', 'help2man', 'help2man'),
|
||||||
|
]
|
||||||
|
|
||||||
class Distribution(object):
|
|
||||||
|
|
||||||
DEPENDENCIES = [
|
class CoolDistro:
|
||||||
#(Generic, version, gentoo, ubuntu, fedora)
|
|
||||||
('python', '2.5', None, None, None),
|
|
||||||
('setuptools', '0.6c5', 'setuptools', 'python-setuptools', 'python-setuptools-devel'),
|
|
||||||
('Python Imaging Library', '1.1.6', 'imaging', 'python-imaging', 'python-imaging'),
|
|
||||||
('libusb', '0.1.12', None, None, None),
|
|
||||||
('Qt', '4.4.0', 'qt', 'libqt4-core libqt4-gui', 'qt4'),
|
|
||||||
('PyQt', '4.4.2', 'PyQt4', 'python-qt4', 'PyQt4'),
|
|
||||||
('mechanize for python', '0.1.11', 'dev-python/mechanize', 'python-mechanize', 'python-mechanize'),
|
|
||||||
('ImageMagick', '6.3.5', 'imagemagick', 'imagemagick', 'ImageMagick'),
|
|
||||||
('xdg-utils', '1.0.2', 'xdg-utils', 'xdg-utils', 'xdg-utils'),
|
|
||||||
('dbus-python', '0.82.2', 'dbus-python', 'python-dbus', 'dbus-python'),
|
|
||||||
('lxml', '2.0.5', 'lxml', 'python-lxml', 'python-lxml'),
|
|
||||||
('python-dateutil', '1.4.1', 'python-dateutil', 'python-dateutil', 'python-dateutil'),
|
|
||||||
('BeautifulSoup', '3.0.5', 'beautifulsoup', 'python-beautifulsoup', 'python-BeautifulSoup'),
|
|
||||||
('help2man', '1.36.4', 'help2man', 'help2man', 'help2man'),
|
|
||||||
]
|
|
||||||
|
|
||||||
DISTRO_MAP = {'gentoo':2, 'ubuntu':3, 'fedora':4, 'debian':3}
|
def __init__(self, name, title, prefix=''):
|
||||||
|
self.title = title
|
||||||
|
url = prefix + '/chrome/dl/images/%s_logo.png'
|
||||||
|
self.img = url%name
|
||||||
|
|
||||||
INSTALLERS = ('emerge -avn', 'apt-get install', 'yum install')
|
def get_linux_data(version='1.0.0'):
|
||||||
AS_ROOT = (True, False, True)
|
data = {'version':version, 'app':__appname__}
|
||||||
|
data['title'] = 'Download calibre for linux'
|
||||||
|
data['supported'] = []
|
||||||
|
for name, title in [
|
||||||
|
('ubuntu', 'Ubuntu Jaunty Jackalope'),
|
||||||
|
('debian', 'Debian Sid'),
|
||||||
|
('exherbo', 'Exherbo'),
|
||||||
|
]:
|
||||||
|
data['supported'].append(CoolDistro(name, title,
|
||||||
|
prefix='http://calibre.kovidgoyal.net'))
|
||||||
|
data['dependencies'] = DEPENDENCIES
|
||||||
|
return data
|
||||||
|
|
||||||
TITLEMAP = {'gentoo':'Gentoo', 'ubuntu':'Ubuntu Intrepid Ibex',
|
if __name__ == '__main__':
|
||||||
'fedora':'Fedora 10', 'debian':'Debian sid', 'generic': 'Install from source'}
|
import os
|
||||||
|
from calibre.utils.genshi.template import MarkupTemplate
|
||||||
|
import cherrypy
|
||||||
|
class Test:
|
||||||
|
def index(self):
|
||||||
|
raw = open(os.path.dirname(os.path.abspath(__file__))+'/templates/linux.html').read()
|
||||||
|
return MarkupTemplate(raw).generate(**get_linux_data()).render('xhtml')
|
||||||
|
index.exposed = True
|
||||||
|
t = Test()
|
||||||
|
t.index()
|
||||||
|
cherrypy.quickstart(t)
|
||||||
|
else:
|
||||||
|
from pkg_resources import resource_filename
|
||||||
|
|
||||||
MANUAL_MAP = {
|
from trac.core import Component, implements
|
||||||
'fedora' : '''<li>You have to upgrade Qt to at least 4.4.0 and PyQt to at least 4.4.2</li>''',
|
from trac.web.chrome import INavigationContributor, ITemplateProvider, add_stylesheet
|
||||||
}
|
from trac.web.main import IRequestHandler
|
||||||
|
from trac.util import Markup
|
||||||
|
|
||||||
def __init__(self, os):
|
|
||||||
self.os = os
|
|
||||||
self.img = os
|
DOWNLOAD_DIR = '/var/www/calibre.kovidgoyal.net/htdocs/downloads'
|
||||||
self.title = self.TITLEMAP[os]
|
MOBILEREAD = 'https://dev.mobileread.com/dist/kovid/calibre/'
|
||||||
self.app = __appname__
|
|
||||||
self.is_generic = os == 'generic'
|
class OS(dict):
|
||||||
offset = 0
|
"""Dictionary with a default value for unknown keys."""
|
||||||
if not self.is_generic:
|
def __init__(self, dict):
|
||||||
index = self.DISTRO_MAP[self.os]
|
self.update(dict)
|
||||||
if os == 'debian':
|
if not dict.has_key('img'):
|
||||||
self.as_root = True
|
self['img'] = self['name']
|
||||||
else: self.as_root = self.AS_ROOT[index-2]
|
|
||||||
prefix = ''
|
|
||||||
if not self.as_root: prefix = 'sudo '
|
class Download(Component):
|
||||||
cmd = prefix + self.INSTALLERS[index-2]
|
implements(INavigationContributor, IRequestHandler, ITemplateProvider)
|
||||||
pre = ' \\\n '.ljust(len(cmd)+4)
|
|
||||||
for dep in self.DEPENDENCIES:
|
request_pat = re.compile(r'\/download$|\/download_\S+')
|
||||||
if len(cmd) > 70+offset:
|
|
||||||
offset += 70
|
# INavigationContributor methods
|
||||||
cmd += pre
|
def get_active_navigation_item(self, req):
|
||||||
cmd += ' '
|
return 'download'
|
||||||
if dep[index]: cmd += dep[index]
|
|
||||||
self.command = cmd.strip()
|
def get_navigation_items(self, req):
|
||||||
easy_install = 'easy_install'
|
yield 'mainnav', 'download', Markup('<a href="/download">Get %s</a>'%(__appname__,))
|
||||||
if os == 'debian':
|
|
||||||
easy_install = 'easy_install-2.5'
|
def get_templates_dirs(self):
|
||||||
self.command += '\n'+prefix+easy_install+' -U calibre \n'+prefix+'calibre_postinstall'
|
return [resource_filename(__name__, 'templates')]
|
||||||
|
|
||||||
|
def get_htdocs_dirs(self):
|
||||||
|
return [('dl', resource_filename(__name__, 'htdocs'))]
|
||||||
|
|
||||||
|
# IRequestHandler methods
|
||||||
|
def match_request(self, req):
|
||||||
|
return self.__class__.request_pat.match(req.path_info)
|
||||||
|
|
||||||
|
def process_request(self, req):
|
||||||
|
add_stylesheet(req, 'dl/css/download.css')
|
||||||
|
if req.path_info == '/download':
|
||||||
|
return self.top_level(req)
|
||||||
|
elif req.path_info == '/download_linux_binary_installer':
|
||||||
|
req.send(LINUX_INSTALLER.replace('%version', self.version_from_filename()), 'text/x-python')
|
||||||
|
else:
|
||||||
|
match = re.match(r'\/download_(\S+)', req.path_info)
|
||||||
|
if match:
|
||||||
|
os = match.group(1)
|
||||||
|
if os == 'windows':
|
||||||
|
return self.windows(req)
|
||||||
|
elif os == 'osx':
|
||||||
|
return self.osx(req)
|
||||||
|
elif os == 'linux':
|
||||||
|
return self.linux(req)
|
||||||
|
|
||||||
|
def top_level(self, req):
|
||||||
|
operating_systems = [
|
||||||
|
OS({'name' : 'windows', 'title' : 'Windows'}),
|
||||||
|
OS({'name' : 'osx', 'title' : 'OS X'}),
|
||||||
|
OS({'name' : 'linux', 'title' : 'Linux'}),
|
||||||
|
]
|
||||||
|
data = dict(title='Get ' + __appname__,
|
||||||
|
operating_systems=operating_systems, width=200,
|
||||||
|
font_size='xx-large', top_level=True)
|
||||||
|
return 'download.html', data, None
|
||||||
|
|
||||||
|
def version_from_filename(self):
|
||||||
try:
|
try:
|
||||||
self.manual = Markup(self.MANUAL_MAP[os])
|
return open(DOWNLOAD_DIR+'/latest_version', 'rb').read().strip()
|
||||||
except KeyError:
|
except:
|
||||||
self.manual = None
|
return '0.0.0'
|
||||||
else:
|
|
||||||
self.img = 'linux'
|
def windows(self, req):
|
||||||
|
version = self.version_from_filename()
|
||||||
|
file = '%s-%s.exe'%(__appname__, version,)
|
||||||
|
data = dict(version = version, name='windows',
|
||||||
|
installer_name='Windows installer',
|
||||||
|
title='Download %s for windows'%(__appname__),
|
||||||
|
compatibility='%s works on Windows XP and Windows Vista.'%(__appname__,),
|
||||||
|
path=MOBILEREAD+file, app=__appname__,
|
||||||
|
note=Markup(\
|
||||||
|
'''
|
||||||
|
<p>If you are using the <b>SONY PRS-500</b> and %(appname)s does not detect your reader, read on:</p>
|
||||||
|
<blockquote>
|
||||||
|
<p>
|
||||||
|
If you are using 64-bit windows, you're out of luck.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
There may be a conflict with the USB driver from SONY. In windows, you cannot install two drivers
|
||||||
|
for one device. In order to resolve the conflict:
|
||||||
|
<ol>
|
||||||
|
<li>Start Device Manager by clicking Start->Run, typing devmgmt.msc and pressing enter.</li>
|
||||||
|
<li>Uninstall all PRS500 related drivers. You will find them in two locations:
|
||||||
|
<ul>
|
||||||
|
<li>Under "Libusb-Win32"</li>
|
||||||
|
<li>Under "Universal Serial ..." (... depends on the version of windows)</li>
|
||||||
|
</ul>
|
||||||
|
You can uninstall a driver by right clicking on it and selecting uninstall.
|
||||||
|
</li>
|
||||||
|
<li>Once the drivers have been uninstalled, find the file prs500.inf (it will be in the
|
||||||
|
driver folder in the folder in which you installed %(appname)s. Right click on it and
|
||||||
|
select Install.</li>
|
||||||
|
</ol>
|
||||||
|
</p>
|
||||||
|
</blockquote>
|
||||||
|
'''%dict(appname=__appname__)))
|
||||||
|
return 'binary.html', data, None
|
||||||
|
|
||||||
|
def osx(self, req):
|
||||||
|
version = self.version_from_filename()
|
||||||
|
file = 'calibre-%s.dmg'%(version,)
|
||||||
|
data = dict(version = version, name='osx',
|
||||||
|
installer_name='OS X universal dmg',
|
||||||
|
title='Download %s for OS X'%(__appname__),
|
||||||
|
compatibility='%s works on OS X Tiger and above.'%(__appname__,),
|
||||||
|
path=MOBILEREAD+file, app=__appname__,
|
||||||
|
note=Markup(\
|
||||||
|
'''
|
||||||
|
<ol>
|
||||||
|
<li>Before trying to use the command line tools, you must run the app at least once. This will ask you for you password and then setup the symbolic links for the command line tools.</li>
|
||||||
|
<li>The app cannot be run from within the dmg. You must drag it to a folder on your filesystem (The Desktop, Applications, wherever).</li>
|
||||||
|
<li>In order for localization of the user interface in your language, select your language in the configuration dialog (by clicking the hammer icon next to the search bar) and select your language.</li>
|
||||||
|
</ol>
|
||||||
|
'''))
|
||||||
|
return 'binary.html', data, None
|
||||||
|
|
||||||
|
def linux(self, req):
|
||||||
|
data = get_linux_data(version=self.version_from_filename())
|
||||||
|
return 'linux.html', data, None
|
||||||
|
|
||||||
|
|
||||||
class Download(Component):
|
LINUX_INSTALLER = textwrap.dedent(r'''
|
||||||
implements(INavigationContributor, IRequestHandler, ITemplateProvider)
|
import sys, os, shutil, tarfile, subprocess, tempfile, urllib2, re, stat
|
||||||
|
|
||||||
request_pat = re.compile(r'\/download$|\/download_\S+')
|
MOBILEREAD='https://dev.mobileread.com/dist/kovid/calibre/'
|
||||||
|
|
||||||
# INavigationContributor methods
|
class TerminalController:
|
||||||
def get_active_navigation_item(self, req):
|
BOL = '' #: Move the cursor to the beginning of the line
|
||||||
return 'download'
|
UP = '' #: Move the cursor up one line
|
||||||
|
DOWN = '' #: Move the cursor down one line
|
||||||
|
LEFT = '' #: Move the cursor left one char
|
||||||
|
RIGHT = '' #: Move the cursor right one char
|
||||||
|
|
||||||
def get_navigation_items(self, req):
|
# Deletion:
|
||||||
yield 'mainnav', 'download', Markup('<a href="/download">Get %s</a>'%(__appname__,))
|
CLEAR_SCREEN = '' #: Clear the screen and move to home position
|
||||||
|
CLEAR_EOL = '' #: Clear to the end of the line.
|
||||||
|
CLEAR_BOL = '' #: Clear to the beginning of the line.
|
||||||
|
CLEAR_EOS = '' #: Clear to the end of the screen
|
||||||
|
|
||||||
def get_templates_dirs(self):
|
# Output modes:
|
||||||
return [resource_filename(__name__, 'templates')]
|
BOLD = '' #: Turn on bold mode
|
||||||
|
BLINK = '' #: Turn on blink mode
|
||||||
|
DIM = '' #: Turn on half-bright mode
|
||||||
|
REVERSE = '' #: Turn on reverse-video mode
|
||||||
|
NORMAL = '' #: Turn off all modes
|
||||||
|
|
||||||
def get_htdocs_dirs(self):
|
# Cursor display:
|
||||||
return [('dl', resource_filename(__name__, 'htdocs'))]
|
HIDE_CURSOR = '' #: Make the cursor invisible
|
||||||
|
SHOW_CURSOR = '' #: Make the cursor visible
|
||||||
|
|
||||||
# IRequestHandler methods
|
# Terminal size:
|
||||||
def match_request(self, req):
|
COLS = None #: Width of the terminal (None for unknown)
|
||||||
return self.__class__.request_pat.match(req.path_info)
|
LINES = None #: Height of the terminal (None for unknown)
|
||||||
|
|
||||||
def process_request(self, req):
|
# Foreground colors:
|
||||||
add_stylesheet(req, 'dl/css/download.css')
|
BLACK = BLUE = GREEN = CYAN = RED = MAGENTA = YELLOW = WHITE = ''
|
||||||
if req.path_info == '/download':
|
|
||||||
return self.top_level(req)
|
|
||||||
elif req.path_info == '/download_linux_binary_installer':
|
|
||||||
req.send(LINUX_INSTALLER.replace('%version', self.version_from_filename()), 'text/x-python')
|
|
||||||
else:
|
|
||||||
match = re.match(r'\/download_(\S+)', req.path_info)
|
|
||||||
if match:
|
|
||||||
os = match.group(1)
|
|
||||||
if os == 'windows':
|
|
||||||
return self.windows(req)
|
|
||||||
elif os == 'osx':
|
|
||||||
return self.osx(req)
|
|
||||||
elif os == 'linux':
|
|
||||||
return self.linux(req)
|
|
||||||
elif 'binary' in os:
|
|
||||||
return self.linux_binary(req)
|
|
||||||
else:
|
|
||||||
return self.linux_distro(req, os)
|
|
||||||
|
|
||||||
def linux_distro(self, req, os):
|
# Background colors:
|
||||||
version = self.version_from_filename()
|
BG_BLACK = BG_BLUE = BG_GREEN = BG_CYAN = ''
|
||||||
distro = Distribution(os)
|
BG_RED = BG_MAGENTA = BG_YELLOW = BG_WHITE = ''
|
||||||
data = dict(distro=distro,title=distro.title, version=version)
|
|
||||||
return 'distro.html', data, None
|
|
||||||
|
|
||||||
def top_level(self, req):
|
_STRING_CAPABILITIES = """
|
||||||
operating_systems = [
|
BOL=cr UP=cuu1 DOWN=cud1 LEFT=cub1 RIGHT=cuf1
|
||||||
OS({'name' : 'windows', 'title' : 'Windows'}),
|
CLEAR_SCREEN=clear CLEAR_EOL=el CLEAR_BOL=el1 CLEAR_EOS=ed BOLD=bold
|
||||||
OS({'name' : 'osx', 'title' : 'OS X'}),
|
BLINK=blink DIM=dim REVERSE=rev UNDERLINE=smul NORMAL=sgr0
|
||||||
OS({'name' : 'linux', 'title' : 'Linux'}),
|
HIDE_CURSOR=cinvis SHOW_CURSOR=cnorm""".split()
|
||||||
]
|
_COLORS = """BLACK BLUE GREEN CYAN RED MAGENTA YELLOW WHITE""".split()
|
||||||
data = dict(title='Get ' + __appname__,
|
_ANSICOLORS = "BLACK RED GREEN YELLOW BLUE MAGENTA CYAN WHITE".split()
|
||||||
operating_systems=operating_systems, width=200,
|
|
||||||
font_size='xx-large', top_level=True)
|
|
||||||
return 'download.html', data, None
|
|
||||||
|
|
||||||
def version_from_filename(self):
|
def __init__(self, term_stream=sys.stdout):
|
||||||
|
# Curses isn't available on all platforms
|
||||||
|
try: import curses
|
||||||
|
except: return
|
||||||
|
|
||||||
|
# If the stream isn't a tty, then assume it has no capabilities.
|
||||||
|
if not hasattr(term_stream, 'isatty') or not term_stream.isatty(): return
|
||||||
|
|
||||||
|
# Check the terminal type. If we fail, then assume that the
|
||||||
|
# terminal has no capabilities.
|
||||||
|
try: curses.setupterm()
|
||||||
|
except: return
|
||||||
|
|
||||||
|
# Look up numeric capabilities.
|
||||||
|
self.COLS = curses.tigetnum('cols')
|
||||||
|
self.LINES = curses.tigetnum('lines')
|
||||||
|
|
||||||
|
# Look up string capabilities.
|
||||||
|
for capability in self._STRING_CAPABILITIES:
|
||||||
|
(attrib, cap_name) = capability.split('=')
|
||||||
|
setattr(self, attrib, self._tigetstr(cap_name) or '')
|
||||||
|
|
||||||
|
# Colors
|
||||||
|
set_fg = self._tigetstr('setf')
|
||||||
|
if set_fg:
|
||||||
|
for i,color in zip(range(len(self._COLORS)), self._COLORS):
|
||||||
|
setattr(self, color, curses.tparm(set_fg, i) or '')
|
||||||
|
set_fg_ansi = self._tigetstr('setaf')
|
||||||
|
if set_fg_ansi:
|
||||||
|
for i,color in zip(range(len(self._ANSICOLORS)), self._ANSICOLORS):
|
||||||
|
setattr(self, color, curses.tparm(set_fg_ansi, i) or '')
|
||||||
|
set_bg = self._tigetstr('setb')
|
||||||
|
if set_bg:
|
||||||
|
for i,color in zip(range(len(self._COLORS)), self._COLORS):
|
||||||
|
setattr(self, 'BG_'+color, curses.tparm(set_bg, i) or '')
|
||||||
|
set_bg_ansi = self._tigetstr('setab')
|
||||||
|
if set_bg_ansi:
|
||||||
|
for i,color in zip(range(len(self._ANSICOLORS)), self._ANSICOLORS):
|
||||||
|
setattr(self, 'BG_'+color, curses.tparm(set_bg_ansi, i) or '')
|
||||||
|
|
||||||
|
def _tigetstr(self, cap_name):
|
||||||
|
# String capabilities can include "delays" of the form "$<2>".
|
||||||
|
# For any modern terminal, we should be able to just ignore
|
||||||
|
# these, so strip them out.
|
||||||
|
import curses
|
||||||
|
cap = curses.tigetstr(cap_name) or ''
|
||||||
|
return re.sub(r'\$<\d+>[/*]?', '', cap)
|
||||||
|
|
||||||
|
def render(self, template):
|
||||||
|
return re.sub(r'\$\$|\${\w+}', self._render_sub, template)
|
||||||
|
|
||||||
|
def _render_sub(self, match):
|
||||||
|
s = match.group()
|
||||||
|
if s == '$$': return s
|
||||||
|
else: return getattr(self, s[2:-1])
|
||||||
|
|
||||||
|
class ProgressBar:
|
||||||
|
BAR = '%3d%% ${GREEN}[${BOLD}%s%s${NORMAL}${GREEN}]${NORMAL}\n'
|
||||||
|
HEADER = '${BOLD}${CYAN}%s${NORMAL}\n\n'
|
||||||
|
|
||||||
|
def __init__(self, term, header):
|
||||||
|
self.term = term
|
||||||
|
if not (self.term.CLEAR_EOL and self.term.UP and self.term.BOL):
|
||||||
|
raise ValueError("Terminal isn't capable enough -- you "
|
||||||
|
"should use a simpler progress dispaly.")
|
||||||
|
self.width = self.term.COLS or 75
|
||||||
|
self.bar = term.render(self.BAR)
|
||||||
|
self.header = self.term.render(self.HEADER % header.center(self.width))
|
||||||
|
self.cleared = 1 #: true if we haven't drawn the bar yet.
|
||||||
|
|
||||||
|
def update(self, percent, message=''):
|
||||||
|
if isinstance(message, unicode):
|
||||||
|
message = message.encode('utf-8', 'ignore')
|
||||||
|
if self.cleared:
|
||||||
|
sys.stdout.write(self.header)
|
||||||
|
self.cleared = 0
|
||||||
|
n = int((self.width-10)*percent)
|
||||||
|
msg = message.center(self.width)
|
||||||
|
sys.stdout.write(
|
||||||
|
self.term.BOL + self.term.UP + self.term.CLEAR_EOL +
|
||||||
|
(self.bar % (100*percent, '='*n, '-'*(self.width-10-n))) +
|
||||||
|
self.term.CLEAR_EOL + msg)
|
||||||
|
sys.stdout.flush()
|
||||||
|
|
||||||
|
def clear(self):
|
||||||
|
if not self.cleared:
|
||||||
|
sys.stdout.write(self.term.BOL + self.term.CLEAR_EOL +
|
||||||
|
self.term.UP + self.term.CLEAR_EOL +
|
||||||
|
self.term.UP + self.term.CLEAR_EOL)
|
||||||
|
self.cleared = 1
|
||||||
|
|
||||||
|
def download_tarball():
|
||||||
try:
|
try:
|
||||||
return open(DOWNLOAD_DIR+'/latest_version', 'rb').read().strip()
|
pb = ProgressBar(TerminalController(sys.stdout), 'Downloading calibre...')
|
||||||
except:
|
except ValueError:
|
||||||
return '0.0.0'
|
print 'Downloading calibre...'
|
||||||
|
pb = None
|
||||||
def windows(self, req):
|
local = 'calibre-test.tar.bz2'
|
||||||
version = self.version_from_filename()
|
src = open(local) if os.access(local, os.R_OK) else urllib2.urlopen(MOBILEREAD+'calibre-%version-i686.tar.bz2')
|
||||||
file = '%s-%s.exe'%(__appname__, version,)
|
if hasattr(src, 'info'):
|
||||||
data = dict(version = version, name='windows',
|
size = int(src.info()['content-length'])
|
||||||
installer_name='Windows installer',
|
|
||||||
title='Download %s for windows'%(__appname__),
|
|
||||||
compatibility='%s works on Windows XP and Windows Vista.'%(__appname__,),
|
|
||||||
path=MOBILEREAD+file, app=__appname__,
|
|
||||||
note=Markup(\
|
|
||||||
'''
|
|
||||||
<p>If you are using the <b>SONY PRS-500</b> and %(appname)s does not detect your reader, read on:</p>
|
|
||||||
<blockquote>
|
|
||||||
<p>
|
|
||||||
If you are using 64-bit windows, you're out of luck.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
There may be a conflict with the USB driver from SONY. In windows, you cannot install two drivers
|
|
||||||
for one device. In order to resolve the conflict:
|
|
||||||
<ol>
|
|
||||||
<li>Start Device Manager by clicking Start->Run, typing devmgmt.msc and pressing enter.</li>
|
|
||||||
<li>Uninstall all PRS500 related drivers. You will find them in two locations:
|
|
||||||
<ul>
|
|
||||||
<li>Under "Libusb-Win32"</li>
|
|
||||||
<li>Under "Universal Serial ..." (... depends on the version of windows)</li>
|
|
||||||
</ul>
|
|
||||||
You can uninstall a driver by right clicking on it and selecting uninstall.
|
|
||||||
</li>
|
|
||||||
<li>Once the drivers have been uninstalled, find the file prs500.inf (it will be in the
|
|
||||||
driver folder in the folder in which you installed %(appname)s. Right click on it and
|
|
||||||
select Install.</li>
|
|
||||||
</ol>
|
|
||||||
</p>
|
|
||||||
</blockquote>
|
|
||||||
'''%dict(appname=__appname__)))
|
|
||||||
return 'binary.html', data, None
|
|
||||||
|
|
||||||
def linux_binary(self, req):
|
|
||||||
version = self.version_from_filename()
|
|
||||||
return 'pyinstaller.html', {'app':__appname__, 'version':version}, None
|
|
||||||
|
|
||||||
def osx(self, req):
|
|
||||||
version = self.version_from_filename()
|
|
||||||
file = 'calibre-%s.dmg'%(version,)
|
|
||||||
data = dict(version = version, name='osx',
|
|
||||||
installer_name='OS X universal dmg',
|
|
||||||
title='Download %s for OS X'%(__appname__),
|
|
||||||
compatibility='%s works on OS X Tiger and above.'%(__appname__,),
|
|
||||||
path=MOBILEREAD+file, app=__appname__,
|
|
||||||
note=Markup(\
|
|
||||||
'''
|
|
||||||
<ol>
|
|
||||||
<li>Before trying to use the command line tools, you must run the app at least once. This will ask you for you password and then setup the symbolic links for the command line tools.</li>
|
|
||||||
<li>The app cannot be run from within the dmg. You must drag it to a folder on your filesystem (The Desktop, Applications, wherever).</li>
|
|
||||||
<li>In order for localization of the user interface in your language, select your language in the configuration dialog (by clicking the hammer icon next to the search bar) and select your language.</li>
|
|
||||||
</ol>
|
|
||||||
'''))
|
|
||||||
return 'binary.html', data, None
|
|
||||||
|
|
||||||
def linux(self, req):
|
|
||||||
operating_systems = [
|
|
||||||
OS({'name' : 'binary', 'title': 'Binary Installer'}),
|
|
||||||
OS({'name' : 'gentoo', 'title': 'Gentoo'}),
|
|
||||||
OS({'name' : 'ubuntu', 'title': 'Ubuntu'}),
|
|
||||||
OS({'name' : 'fedora', 'title': 'Fedora'}),
|
|
||||||
OS({'name' : 'debian', 'title': 'Debian'}),
|
|
||||||
OS({'name' : 'generic','title': 'Install from source', 'img':'linux'}),
|
|
||||||
]
|
|
||||||
data = dict(title='Choose linux distribution', width=100,
|
|
||||||
operating_systems=operating_systems, font_size='x-large', top_level=False)
|
|
||||||
return 'download.html', data, None
|
|
||||||
|
|
||||||
|
|
||||||
LINUX_INSTALLER = r'''
|
|
||||||
import sys, os, shutil, tarfile, subprocess, tempfile, urllib2, re, stat
|
|
||||||
|
|
||||||
MOBILEREAD='https://dev.mobileread.com/dist/kovid/calibre/'
|
|
||||||
|
|
||||||
class TerminalController:
|
|
||||||
BOL = '' #: Move the cursor to the beginning of the line
|
|
||||||
UP = '' #: Move the cursor up one line
|
|
||||||
DOWN = '' #: Move the cursor down one line
|
|
||||||
LEFT = '' #: Move the cursor left one char
|
|
||||||
RIGHT = '' #: Move the cursor right one char
|
|
||||||
|
|
||||||
# Deletion:
|
|
||||||
CLEAR_SCREEN = '' #: Clear the screen and move to home position
|
|
||||||
CLEAR_EOL = '' #: Clear to the end of the line.
|
|
||||||
CLEAR_BOL = '' #: Clear to the beginning of the line.
|
|
||||||
CLEAR_EOS = '' #: Clear to the end of the screen
|
|
||||||
|
|
||||||
# Output modes:
|
|
||||||
BOLD = '' #: Turn on bold mode
|
|
||||||
BLINK = '' #: Turn on blink mode
|
|
||||||
DIM = '' #: Turn on half-bright mode
|
|
||||||
REVERSE = '' #: Turn on reverse-video mode
|
|
||||||
NORMAL = '' #: Turn off all modes
|
|
||||||
|
|
||||||
# Cursor display:
|
|
||||||
HIDE_CURSOR = '' #: Make the cursor invisible
|
|
||||||
SHOW_CURSOR = '' #: Make the cursor visible
|
|
||||||
|
|
||||||
# Terminal size:
|
|
||||||
COLS = None #: Width of the terminal (None for unknown)
|
|
||||||
LINES = None #: Height of the terminal (None for unknown)
|
|
||||||
|
|
||||||
# Foreground colors:
|
|
||||||
BLACK = BLUE = GREEN = CYAN = RED = MAGENTA = YELLOW = WHITE = ''
|
|
||||||
|
|
||||||
# Background colors:
|
|
||||||
BG_BLACK = BG_BLUE = BG_GREEN = BG_CYAN = ''
|
|
||||||
BG_RED = BG_MAGENTA = BG_YELLOW = BG_WHITE = ''
|
|
||||||
|
|
||||||
_STRING_CAPABILITIES = """
|
|
||||||
BOL=cr UP=cuu1 DOWN=cud1 LEFT=cub1 RIGHT=cuf1
|
|
||||||
CLEAR_SCREEN=clear CLEAR_EOL=el CLEAR_BOL=el1 CLEAR_EOS=ed BOLD=bold
|
|
||||||
BLINK=blink DIM=dim REVERSE=rev UNDERLINE=smul NORMAL=sgr0
|
|
||||||
HIDE_CURSOR=cinvis SHOW_CURSOR=cnorm""".split()
|
|
||||||
_COLORS = """BLACK BLUE GREEN CYAN RED MAGENTA YELLOW WHITE""".split()
|
|
||||||
_ANSICOLORS = "BLACK RED GREEN YELLOW BLUE MAGENTA CYAN WHITE".split()
|
|
||||||
|
|
||||||
def __init__(self, term_stream=sys.stdout):
|
|
||||||
# Curses isn't available on all platforms
|
|
||||||
try: import curses
|
|
||||||
except: return
|
|
||||||
|
|
||||||
# If the stream isn't a tty, then assume it has no capabilities.
|
|
||||||
if not hasattr(term_stream, 'isatty') or not term_stream.isatty(): return
|
|
||||||
|
|
||||||
# Check the terminal type. If we fail, then assume that the
|
|
||||||
# terminal has no capabilities.
|
|
||||||
try: curses.setupterm()
|
|
||||||
except: return
|
|
||||||
|
|
||||||
# Look up numeric capabilities.
|
|
||||||
self.COLS = curses.tigetnum('cols')
|
|
||||||
self.LINES = curses.tigetnum('lines')
|
|
||||||
|
|
||||||
# Look up string capabilities.
|
|
||||||
for capability in self._STRING_CAPABILITIES:
|
|
||||||
(attrib, cap_name) = capability.split('=')
|
|
||||||
setattr(self, attrib, self._tigetstr(cap_name) or '')
|
|
||||||
|
|
||||||
# Colors
|
|
||||||
set_fg = self._tigetstr('setf')
|
|
||||||
if set_fg:
|
|
||||||
for i,color in zip(range(len(self._COLORS)), self._COLORS):
|
|
||||||
setattr(self, color, curses.tparm(set_fg, i) or '')
|
|
||||||
set_fg_ansi = self._tigetstr('setaf')
|
|
||||||
if set_fg_ansi:
|
|
||||||
for i,color in zip(range(len(self._ANSICOLORS)), self._ANSICOLORS):
|
|
||||||
setattr(self, color, curses.tparm(set_fg_ansi, i) or '')
|
|
||||||
set_bg = self._tigetstr('setb')
|
|
||||||
if set_bg:
|
|
||||||
for i,color in zip(range(len(self._COLORS)), self._COLORS):
|
|
||||||
setattr(self, 'BG_'+color, curses.tparm(set_bg, i) or '')
|
|
||||||
set_bg_ansi = self._tigetstr('setab')
|
|
||||||
if set_bg_ansi:
|
|
||||||
for i,color in zip(range(len(self._ANSICOLORS)), self._ANSICOLORS):
|
|
||||||
setattr(self, 'BG_'+color, curses.tparm(set_bg_ansi, i) or '')
|
|
||||||
|
|
||||||
def _tigetstr(self, cap_name):
|
|
||||||
# String capabilities can include "delays" of the form "$<2>".
|
|
||||||
# For any modern terminal, we should be able to just ignore
|
|
||||||
# these, so strip them out.
|
|
||||||
import curses
|
|
||||||
cap = curses.tigetstr(cap_name) or ''
|
|
||||||
return re.sub(r'\$<\d+>[/*]?', '', cap)
|
|
||||||
|
|
||||||
def render(self, template):
|
|
||||||
return re.sub(r'\$\$|\${\w+}', self._render_sub, template)
|
|
||||||
|
|
||||||
def _render_sub(self, match):
|
|
||||||
s = match.group()
|
|
||||||
if s == '$$': return s
|
|
||||||
else: return getattr(self, s[2:-1])
|
|
||||||
|
|
||||||
class ProgressBar:
|
|
||||||
BAR = '%3d%% ${GREEN}[${BOLD}%s%s${NORMAL}${GREEN}]${NORMAL}\n'
|
|
||||||
HEADER = '${BOLD}${CYAN}%s${NORMAL}\n\n'
|
|
||||||
|
|
||||||
def __init__(self, term, header):
|
|
||||||
self.term = term
|
|
||||||
if not (self.term.CLEAR_EOL and self.term.UP and self.term.BOL):
|
|
||||||
raise ValueError("Terminal isn't capable enough -- you "
|
|
||||||
"should use a simpler progress dispaly.")
|
|
||||||
self.width = self.term.COLS or 75
|
|
||||||
self.bar = term.render(self.BAR)
|
|
||||||
self.header = self.term.render(self.HEADER % header.center(self.width))
|
|
||||||
self.cleared = 1 #: true if we haven't drawn the bar yet.
|
|
||||||
|
|
||||||
def update(self, percent, message=''):
|
|
||||||
if isinstance(message, unicode):
|
|
||||||
message = message.encode('utf-8', 'ignore')
|
|
||||||
if self.cleared:
|
|
||||||
sys.stdout.write(self.header)
|
|
||||||
self.cleared = 0
|
|
||||||
n = int((self.width-10)*percent)
|
|
||||||
msg = message.center(self.width)
|
|
||||||
sys.stdout.write(
|
|
||||||
self.term.BOL + self.term.UP + self.term.CLEAR_EOL +
|
|
||||||
(self.bar % (100*percent, '='*n, '-'*(self.width-10-n))) +
|
|
||||||
self.term.CLEAR_EOL + msg)
|
|
||||||
sys.stdout.flush()
|
|
||||||
|
|
||||||
def clear(self):
|
|
||||||
if not self.cleared:
|
|
||||||
sys.stdout.write(self.term.BOL + self.term.CLEAR_EOL +
|
|
||||||
self.term.UP + self.term.CLEAR_EOL +
|
|
||||||
self.term.UP + self.term.CLEAR_EOL)
|
|
||||||
self.cleared = 1
|
|
||||||
|
|
||||||
def download_tarball():
|
|
||||||
try:
|
|
||||||
pb = ProgressBar(TerminalController(sys.stdout), 'Downloading calibre...')
|
|
||||||
except ValueError:
|
|
||||||
print 'Downloading calibre...'
|
|
||||||
pb = None
|
|
||||||
local = 'calibre-test.tar.bz2'
|
|
||||||
src = open(local) if os.access(local, os.R_OK) else urllib2.urlopen(MOBILEREAD+'calibre-%version-i686.tar.bz2')
|
|
||||||
if hasattr(src, 'info'):
|
|
||||||
size = int(src.info()['content-length'])
|
|
||||||
else:
|
|
||||||
src.seek(0, 2)
|
|
||||||
size = src.tell()
|
|
||||||
src.seek(0)
|
|
||||||
f = tempfile.NamedTemporaryFile()
|
|
||||||
while f.tell() < size:
|
|
||||||
f.write(src.read(4*1024))
|
|
||||||
percent = f.tell()/float(size)
|
|
||||||
if pb is not None:
|
|
||||||
pb.update(percent)
|
|
||||||
else:
|
else:
|
||||||
print '%d%%, '%int(percent*100),
|
src.seek(0, 2)
|
||||||
f.seek(0)
|
size = src.tell()
|
||||||
return f
|
src.seek(0)
|
||||||
|
f = tempfile.NamedTemporaryFile()
|
||||||
|
while f.tell() < size:
|
||||||
|
f.write(src.read(4*1024))
|
||||||
|
percent = f.tell()/float(size)
|
||||||
|
if pb is not None:
|
||||||
|
pb.update(percent)
|
||||||
|
else:
|
||||||
|
print '%d%%, '%int(percent*100),
|
||||||
|
f.seek(0)
|
||||||
|
return f
|
||||||
|
|
||||||
def extract_tarball(tar, destdir):
|
def extract_tarball(tar, destdir):
|
||||||
print 'Extracting application files...'
|
print 'Extracting application files...'
|
||||||
if hasattr(tar, 'read'):
|
if hasattr(tar, 'read'):
|
||||||
try:
|
try:
|
||||||
tarfile.open(fileobj=tar, mode='r').extractall(destdir)
|
tarfile.open(fileobj=tar, mode='r').extractall(destdir)
|
||||||
except: # tarfile.py on Fedora 9 is buggy
|
except: # tarfile.py on Fedora 9 is buggy
|
||||||
subprocess.check_call(['tar', 'xjf', tar.name, '-C', destdir])
|
subprocess.check_call(['tar', 'xjf', tar.name, '-C', destdir])
|
||||||
else:
|
else:
|
||||||
tarfile.open(tar, 'r').extractall(destdir)
|
tarfile.open(tar, 'r').extractall(destdir)
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
defdir = '/opt/calibre'
|
defdir = '/opt/calibre'
|
||||||
destdir = raw_input('Enter the installation directory for calibre (Its contents will be deleted!)[%s]: '%defdir).strip()
|
destdir = raw_input('Enter the installation directory for calibre (Its contents will be deleted!)[%s]: '%defdir).strip()
|
||||||
if not destdir:
|
if not destdir:
|
||||||
destdir = defdir
|
destdir = defdir
|
||||||
destdir = os.path.abspath(destdir)
|
destdir = os.path.abspath(destdir)
|
||||||
if os.path.exists(destdir):
|
if os.path.exists(destdir):
|
||||||
shutil.rmtree(destdir)
|
shutil.rmtree(destdir)
|
||||||
os.makedirs(destdir)
|
os.makedirs(destdir)
|
||||||
|
|
||||||
f = download_tarball()
|
f = download_tarball()
|
||||||
|
|
||||||
|
print 'Extracting files to %s ...'%destdir
|
||||||
|
extract_tarball(f, destdir)
|
||||||
|
pi = os.path.join(destdir, 'calibre_postinstall')
|
||||||
|
subprocess.call(pi, shell=True)
|
||||||
|
return 0
|
||||||
|
''')
|
||||||
|
|
||||||
print 'Extracting files to %s ...'%destdir
|
|
||||||
extract_tarball(f, destdir)
|
|
||||||
pi = os.path.join(destdir, 'calibre_postinstall')
|
|
||||||
subprocess.call(pi, shell=True)
|
|
||||||
return 0
|
|
||||||
'''
|
|
||||||
|
BIN
src/calibre/trac/plugins/htdocs/images/exherbo_logo.png
Normal file
BIN
src/calibre/trac/plugins/htdocs/images/exherbo_logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 42 KiB |
@ -1,68 +0,0 @@
|
|||||||
<!DOCTYPE html
|
|
||||||
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
|
||||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml"
|
|
||||||
xmlns:py="http://genshi.edgewall.org/"
|
|
||||||
xmlns:xi="http://www.w3.org/2001/XInclude">
|
|
||||||
<xi:include href="layout.html" />
|
|
||||||
<head>
|
|
||||||
<title>$title</title>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<div id="ctxtnav" class="nav"></div>
|
|
||||||
|
|
||||||
<div id="content" class="download">
|
|
||||||
<h1><img src="${href.chrome('/dl/images/%s_logo.png'%(distro.img,))}" valign="middle" width="60" height="80"/> $title</h1>
|
|
||||||
See the <a href="/wiki/Changelog">Changelog</a> for the changes in the latest version. <span py:if="not distro.is_generic"><b>Note:</b> As of 0.4.80 this install
|
|
||||||
will not work on 64-bit CPUs. Try the precompiled binary available <a href="/download_binary">here</a> instead.</span>
|
|
||||||
<div py:if="not distro.is_generic">
|
|
||||||
First verify that you have a sufficiently new installation of python
|
|
||||||
<pre class="wiki">python --version</pre> should return at least 2.5.1<br />
|
|
||||||
<p py:if="distro.os == 'gentoo'">
|
|
||||||
Make sure your python is compiled with the sqlite USE flag.
|
|
||||||
</p>
|
|
||||||
<br />
|
|
||||||
Run the following commands in a terminal <span py:if="distro.as_root">as root</span>
|
|
||||||
<pre class="wiki">${distro.command}</pre>
|
|
||||||
<div py:if="distro.manual">
|
|
||||||
<h2>Manual steps</h2>
|
|
||||||
<ul>
|
|
||||||
${distro.manual}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div py:if="distro.is_generic">
|
|
||||||
<ol>
|
|
||||||
<li>Make sure that your system has <code>python >= 2.5</code></li>
|
|
||||||
<li>Install the various dependencies listed below: Make sure that any python packages are installed into python2.5 (e.g. setuptools, python-imaging, PyQt4, etc). You will also have to install the development versions of the packages (these packages usually have -dev added to their names).</li>
|
|
||||||
<li>Run the following commands in a terminal:
|
|
||||||
<pre class="wiki">
|
|
||||||
wget -O- http://calibre.kovidgoyal.net/downloads/calibre-${version}.tar.gz | tar xvz
|
|
||||||
cd calibre*
|
|
||||||
python setup.py build && sudo python setup.py install
|
|
||||||
</pre></li>
|
|
||||||
</ol>
|
|
||||||
<h2>Dependencies</h2>
|
|
||||||
<table border="1" cellpadding="10">
|
|
||||||
<tr><th style="font-weight:bold">Name</th><th style="font-weight:bold">Minimum version</th></tr>
|
|
||||||
<tr py:for="dep in distro.DEPENDENCIES">
|
|
||||||
<td>${dep[0]}</td><td>${dep[1]}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>HAL</td><td>0.5.10</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
While you wait for the installation to complete, please consider donating to support the development of ${distro.app}.
|
|
||||||
<div>
|
|
||||||
<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
|
|
||||||
<input type="hidden" name="cmd" value="_s-xclick" />
|
|
||||||
<input type="hidden" name="hosted_button_id" value="3029289" />
|
|
||||||
<input type="image" src="https://www.paypal.com/en_US/i/btn/btn_donateCC_LG.gif" border="0" name="submit" alt="Donate to support calibre development" />
|
|
||||||
<img alt="" border="0" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1" />
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
155
src/calibre/trac/plugins/templates/linux.html
Normal file
155
src/calibre/trac/plugins/templates/linux.html
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
<!DOCTYPE html
|
||||||
|
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||||
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml"
|
||||||
|
xmlns:py="http://genshi.edgewall.org/"
|
||||||
|
xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||||
|
<xi:include href="layout.html" />
|
||||||
|
<head>
|
||||||
|
<title>${title}</title>
|
||||||
|
<style type="text/css">
|
||||||
|
table tr th.distro_type {
|
||||||
|
font-family: monospace;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: larger;
|
||||||
|
vertical-align:middle;
|
||||||
|
text-align: center;
|
||||||
|
border-bottom: solid 1pt black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right {
|
||||||
|
margin-left:2em;
|
||||||
|
border-left: solid 1pt black;
|
||||||
|
}
|
||||||
|
|
||||||
|
table#install_info {
|
||||||
|
border-collapse: collapse;
|
||||||
|
border-width: 1pt;
|
||||||
|
border-style: solid;
|
||||||
|
table-layout: fixed;
|
||||||
|
width: 95%;
|
||||||
|
background: #F7F7F0 none repeat scroll 0 0;
|
||||||
|
}
|
||||||
|
table#dependencies {
|
||||||
|
border-collapse: collapse;
|
||||||
|
border-width: 0pt;
|
||||||
|
font-family:monospace;
|
||||||
|
}
|
||||||
|
.tdata {vertical-align: top;}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="ctxtnav" class="nav"></div>
|
||||||
|
<div id="content" class="download">
|
||||||
|
<h1>${title}</h1>
|
||||||
|
<p>
|
||||||
|
The latest release of ${app} is ${version}. See the
|
||||||
|
<a href="/wiki/Changelog">Changelog</a> for a list of new features.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
${app} is available in the software repositories of the following
|
||||||
|
linux distributions:
|
||||||
|
<table id="install_info">
|
||||||
|
<col width="150" /><col width="*" />
|
||||||
|
<tr>
|
||||||
|
<th class="left distro_type">Supported<br/>distributions</th>
|
||||||
|
<th class="right distro_type">Unsupported distributions</th>
|
||||||
|
</tr>
|
||||||
|
<tr class="tdata">
|
||||||
|
<td class="left" style="overflow-y:scroll">
|
||||||
|
<div py:for="distro in supported"
|
||||||
|
style="text-align:center;margin-top:2ex;">
|
||||||
|
<div>
|
||||||
|
<img width="64px" height="64px"
|
||||||
|
src="${distro.img}" alt="${distro.title}" />
|
||||||
|
</div>
|
||||||
|
${distro.title}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td class="right">
|
||||||
|
<div style="margin-left:2em">
|
||||||
|
<h3>Binary install</h3>
|
||||||
|
<p>
|
||||||
|
${app} has a binary installer that has been
|
||||||
|
tested on a number of distributions on both
|
||||||
|
32-bit and 64-bit x86 machines. To install,
|
||||||
|
copy paste the following command into a terminal
|
||||||
|
and press Enter:
|
||||||
|
</p>
|
||||||
|
<pre class="wiki">
|
||||||
|
sudo python -c "import urllib2; exec urllib2.urlopen('http://calibre.kovidgoyal.net/download_linux_binary_installer').read(); main()"
|
||||||
|
</pre>
|
||||||
|
<h4>Note</h4>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
When running the command line utilities,
|
||||||
|
they will segfault after completion. This can
|
||||||
|
be ignored.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
You must have help2man and xdg-utils installed
|
||||||
|
on your system before running the installer.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
On a 64bit machine, you must have 32-bit versions
|
||||||
|
of common libraries like X11, freetype, fontconfig,
|
||||||
|
expat and their varios dependencies installed.
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<h3>Source install</h3>
|
||||||
|
<p>
|
||||||
|
<ol>
|
||||||
|
<li>
|
||||||
|
Make sure your system has python ≥ ${dependencies[0][1]}
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Install the various dependencies listed below
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Run the following commands in a terminal:
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
<pre class="wiki">
|
||||||
|
wget -O- http://calibre.kovidgoyal.net/downloads/${app}-${version}.tar.gz | tar xvz
|
||||||
|
cd calibre*
|
||||||
|
python setup.py build && sudo python setup.py install
|
||||||
|
</pre>
|
||||||
|
Note that if your distribution does not have a
|
||||||
|
correctly compiled libunrar.so, ${app} will not
|
||||||
|
support rar files.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
While you wait for the download to complete, please consider
|
||||||
|
donating to support the development of ${app}.
|
||||||
|
</p>
|
||||||
|
<div>
|
||||||
|
<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
|
||||||
|
<input type="hidden" name="cmd" value="_s-xclick" />
|
||||||
|
<input type="image" src="https://www.paypal.com/en_US/i/btn/btn_donateCC_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!" />
|
||||||
|
<img alt="" border="0" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1" />
|
||||||
|
<input type="hidden" name="encrypted" value="-----BEGIN PKCS7-----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-----END PKCS7-----" />
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<hr/>
|
||||||
|
<h3>Dependencies</h3>
|
||||||
|
${app} has the following dependencies (the listed version is the minimum version)
|
||||||
|
<br/><br/>
|
||||||
|
<table id="dependencies">
|
||||||
|
<tr>
|
||||||
|
<th class="distro_type" style="margin-right:2em">Package</th>
|
||||||
|
<th class="distro_type">Version</th>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr class="dependency" py:for="dep in dependencies">
|
||||||
|
<td style="margin-right:2em">${dep[0]}</td><td>${dep[1]}</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -1,47 +0,0 @@
|
|||||||
<!DOCTYPE html
|
|
||||||
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
|
||||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml"
|
|
||||||
xmlns:py="http://genshi.edgewall.org/"
|
|
||||||
xmlns:xi="http://www.w3.org/2001/XInclude">
|
|
||||||
<xi:include href="layout.html" />
|
|
||||||
<head>
|
|
||||||
<title>Download $app for Linux</title>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<div id="ctxtnav" class="nav"></div>
|
|
||||||
|
|
||||||
<div id="content" class="binary">
|
|
||||||
<h1>Download $app for Linux</h1>
|
|
||||||
<p>This binary package is compatible with most recent linux distributions running on Intel 32 bit CPUs. It needs testing on 64 bit CPUs. There have been reports of its working on some 64bit machines. </p>
|
|
||||||
<p>
|
|
||||||
<img width="50" height="50" style="border:1px red solid" src="${href.chrome('/dl/images/binary_logo.png')}" />
|
|
||||||
(Version: $version <a href="/wiki/Changelog">Changelog</a>)
|
|
||||||
</p>
|
|
||||||
<p>To install, copy paste the following command into a terminal and press Enter:
|
|
||||||
</p>
|
|
||||||
<pre class="wiki">sudo python -c "import urllib2; exec urllib2.urlopen('http://calibre.kovidgoyal.net/download_linux_binary_installer').read(); main()"</pre>
|
|
||||||
<p>
|
|
||||||
While you wait for the download to complete, please consider donating to support the development
|
|
||||||
of ${app}.</p>
|
|
||||||
<div>
|
|
||||||
<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
|
|
||||||
<input type="hidden" name="cmd" value="_s-xclick" />
|
|
||||||
<input type="image" src="https://www.paypal.com/en_US/i/btn/btn_donateCC_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!" />
|
|
||||||
<img alt="" border="0" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1" />
|
|
||||||
<input type="hidden" name="encrypted" value="-----BEGIN PKCS7-----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-----END PKCS7-----" />
|
|
||||||
</form>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<h2>Note</h2>
|
|
||||||
<div class="note">
|
|
||||||
<ul>
|
|
||||||
<li>This installer is very new and has only been tested on a couple of systems, so if you encounter
|
|
||||||
problems, please report them.</li>
|
|
||||||
<li>You shoud have help2man and xdg-utils installed on your system.</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
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
@ -6,7 +6,7 @@ __docformat__ = 'restructuredtext en'
|
|||||||
'''
|
'''
|
||||||
Manage application-wide preferences.
|
Manage application-wide preferences.
|
||||||
'''
|
'''
|
||||||
import os, re, cPickle, textwrap
|
import os, re, cPickle, textwrap, traceback
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from optparse import OptionParser as _OptionParser
|
from optparse import OptionParser as _OptionParser
|
||||||
@ -314,7 +314,12 @@ class OptionSet(object):
|
|||||||
if not isinstance(src, unicode):
|
if not isinstance(src, unicode):
|
||||||
src = src.decode('utf-8')
|
src = src.decode('utf-8')
|
||||||
if src is not None:
|
if src is not None:
|
||||||
exec src in options
|
try:
|
||||||
|
exec src in options
|
||||||
|
except:
|
||||||
|
print 'Failed to parse options string:'
|
||||||
|
print repr(src)
|
||||||
|
traceback.print_exc()
|
||||||
opts = OptionValues()
|
opts = OptionValues()
|
||||||
for pref in self.preferences:
|
for pref in self.preferences:
|
||||||
val = options.get(pref.name, pref.default)
|
val = options.get(pref.name, pref.default)
|
||||||
@ -539,7 +544,7 @@ def _prefs():
|
|||||||
help=_('Path to directory in which your library of books is stored'))
|
help=_('Path to directory in which your library of books is stored'))
|
||||||
c.add_opt('language', default=None,
|
c.add_opt('language', default=None,
|
||||||
help=_('The language in which to display the user interface'))
|
help=_('The language in which to display the user interface'))
|
||||||
c.add_opt('output_format', default='LRF',
|
c.add_opt('output_format', default='EPUB',
|
||||||
help=_('The default output format for ebook conversions.'))
|
help=_('The default output format for ebook conversions.'))
|
||||||
c.add_opt('read_file_metadata', default=True,
|
c.add_opt('read_file_metadata', default=True,
|
||||||
help=_('Read metadata from files'))
|
help=_('Read metadata from files'))
|
||||||
|
@ -28,7 +28,7 @@ recipe_modules = ['recipe_' + r for r in (
|
|||||||
'la_tercera', 'el_mercurio_chile', 'la_cuarta', 'lanacion_chile', 'la_segunda',
|
'la_tercera', 'el_mercurio_chile', 'la_cuarta', 'lanacion_chile', 'la_segunda',
|
||||||
'jb_online', 'estadao', 'o_globo', 'vijesti', 'elmundo', 'the_oz',
|
'jb_online', 'estadao', 'o_globo', 'vijesti', 'elmundo', 'the_oz',
|
||||||
'honoluluadvertiser', 'starbulletin', 'exiled', 'indy_star', 'dna',
|
'honoluluadvertiser', 'starbulletin', 'exiled', 'indy_star', 'dna',
|
||||||
'pobjeda',
|
'pobjeda', 'chicago_breaking_news', 'glasgow_herald',
|
||||||
)]
|
)]
|
||||||
|
|
||||||
import re, imp, inspect, time, os
|
import re, imp, inspect, time, os
|
||||||
|
@ -1,50 +1,60 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
__license__ = 'GPL v3'
|
|
||||||
__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net'
|
|
||||||
__docformat__ = 'restructuredtext en'
|
|
||||||
|
|
||||||
|
__license__ = 'GPL v3'
|
||||||
|
__copyright__ = '2008-2009, Darko Miletic <darko.miletic at gmail.com>'
|
||||||
'''
|
'''
|
||||||
arstechnica.com
|
arstechnica.com
|
||||||
'''
|
'''
|
||||||
|
|
||||||
from calibre.web.feeds.news import BasicNewsRecipe
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
class ArsTechnica(BasicNewsRecipe):
|
class ArsTechnica2(BasicNewsRecipe):
|
||||||
title = 'Ars Technica'
|
title = u'Ars Technica'
|
||||||
description = 'The art of technology'
|
language = _('English')
|
||||||
oldest_article = 7
|
__author__ = 'Darko Miletic'
|
||||||
language = _('English')
|
description = 'The art of technology'
|
||||||
no_stylesheets = True
|
publisher = 'Ars Technica'
|
||||||
__author__ = 'Michael Warner'
|
category = 'news, IT, technology'
|
||||||
|
language = _('English')
|
||||||
|
oldest_article = 2
|
||||||
max_articles_per_feed = 100
|
max_articles_per_feed = 100
|
||||||
extra_css = """
|
no_stylesheets = True
|
||||||
body {
|
encoding = 'utf8'
|
||||||
font: normal 19px/180% Times, serif;
|
remove_javascript = True
|
||||||
}
|
use_embedded_content = False
|
||||||
|
|
||||||
|
html2lrf_options = [
|
||||||
|
'--comment', description
|
||||||
|
, '--category', category
|
||||||
|
, '--publisher', publisher
|
||||||
|
]
|
||||||
|
|
||||||
|
html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"'
|
||||||
|
|
||||||
|
keep_only_tags = [dict(name='div', attrs={'id':['news-item-info','news-item']})]
|
||||||
|
|
||||||
h1, h2, h3, h4 {
|
|
||||||
font: bold 28px/100% Verdana, Arial, Helvetica, sans-serif;
|
|
||||||
margin-top: 19px
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
remove_tags = [
|
remove_tags = [
|
||||||
dict(id="Masthead"),
|
dict(name=['object','link','embed'])
|
||||||
dict(id="Banner"),
|
,dict(name='div', attrs={'class':'related-stories'})
|
||||||
dict(id="Nav"),
|
]
|
||||||
dict(name='div', attrs={'class':'ContentHeader'}),
|
|
||||||
dict(name='img'),
|
|
||||||
dict(name='div', attrs={'class':'Inset RelatedStories'}),
|
feeds = [
|
||||||
dict(name='div', attrs={'class':'Tags'}),
|
(u'Infinite Loop (Apple content)' , u'http://feeds.arstechnica.com/arstechnica/apple/' )
|
||||||
dict(name='div', attrs={'class':'PostOptions flat'}),
|
,(u'Opposable Thumbs (Gaming content)' , u'http://feeds.arstechnica.com/arstechnica/gaming/' )
|
||||||
dict(name='div', attrs={'class':'ContentFooter'}),
|
,(u'Gear and Gadgets' , u'http://feeds.arstechnica.com/arstechnica/gadgets/' )
|
||||||
dict(id="Sidebar"),
|
,(u'Chipster (Hardware content)' , u'http://feeds.arstechnica.com/arstechnica/hardware/' )
|
||||||
dict(id="LatestPosts"),
|
,(u'Uptime (IT content)' , u'http://feeds.arstechnica.com/arstechnica/business/' )
|
||||||
dict(id="Footer")]
|
,(u'Open Ended (Open Source content)' , u'http://feeds.arstechnica.com/arstechnica/open-source/')
|
||||||
feeds = [(u'News and Features', u'http://feeds.arstechnica.com/arstechnica/BAaf'),
|
,(u'One Microsoft Way' , u'http://feeds.arstechnica.com/arstechnica/microsoft/' )
|
||||||
(u'Nobel Intent (Science)', u'http://arstechnica.com/journals/science.rssx'),
|
,(u'Nobel Intent (Science content)' , u'http://feeds.arstechnica.com/arstechnica/science/' )
|
||||||
(u'Infinite Loop (Apple)', u'http://arstechnica.com/journals/apple.rssx'),
|
,(u'Law & Disorder (Tech policy content)' , u'http://feeds.arstechnica.com/arstechnica/tech-policy/')
|
||||||
(u'M-Dollar (Microsoft)', u'http://arstechnica.com/journals/microsoft.rssx'),
|
]
|
||||||
(u'Open Ended (Linux)', u'http://arstechnica.com/journals/linux.rssx'),
|
|
||||||
(u'Opposable Thumbs (Games)', u'http://arstechnica.com/journals/thumbs.rssx'),
|
def preprocess_html(self, soup):
|
||||||
(u'Kit (Hardware)', u'http://arstechnica.com/journals/hardware.rssx'),
|
ftag = soup.find('div', attrs={'class':'news-item-byline'})
|
||||||
(u'Journals', u'http://arstechnica.com/journals.rssx')]
|
if ftag:
|
||||||
|
ftag.insert(4,'<br /><br />')
|
||||||
|
for item in soup.findAll(style=True):
|
||||||
|
del item['style']
|
||||||
|
return soup
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2008, Darko Miletic <darko.miletic at gmail.com>'
|
__copyright__ = '2008-2009, Darko Miletic <darko.miletic at gmail.com>'
|
||||||
'''
|
'''
|
||||||
b92.net
|
b92.net
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from calibre.web.feeds.news import BasicNewsRecipe
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
class B92(BasicNewsRecipe):
|
class B92(BasicNewsRecipe):
|
||||||
@ -22,19 +21,22 @@ class B92(BasicNewsRecipe):
|
|||||||
no_stylesheets = True
|
no_stylesheets = True
|
||||||
use_embedded_content = False
|
use_embedded_content = False
|
||||||
cover_url = 'http://static.b92.net/images/fp/logo.gif'
|
cover_url = 'http://static.b92.net/images/fp/logo.gif'
|
||||||
extra_css = '@font-face {font-family: "serif1";src:url(res:///opt/sony/ebook/FONT/tt0011m_.ttf)} @font-face {font-family: "monospace1";src:url(res:///opt/sony/ebook/FONT/tt0419m_.ttf)} @font-face {font-family: "sans1";src:url(res:///opt/sony/ebook/FONT/tt0003m_.ttf)} body{text-align: left; font-family: serif1, serif} .article_date{font-family: monospace1, monospace} .article_description{font-family: sans1, sans-serif} .navbar{font-family: monospace1, monospace}'
|
language = _('Serbian')
|
||||||
|
extra_css = '@font-face {font-family: "serif1";src:url(res:///opt/sony/ebook/FONT/tt0011m_.ttf)} @font-face {font-family: "sans1";src:url(res:///opt/sony/ebook/FONT/tt0003m_.ttf)} body{font-family: serif1, serif} .article_description{font-family: sans1, sans-serif}'
|
||||||
|
|
||||||
|
html2lrf_options = [
|
||||||
|
'--comment' , description
|
||||||
|
, '--category' , category
|
||||||
|
, '--publisher', publisher
|
||||||
|
, '--ignore-tables'
|
||||||
|
]
|
||||||
|
|
||||||
|
html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"\nlinearize_tables=True'
|
||||||
|
|
||||||
keep_only_tags = [ dict(name='div', attrs={'class':'sama_vest'}) ]
|
keep_only_tags = [ dict(name='div', attrs={'class':'sama_vest'}) ]
|
||||||
|
|
||||||
html2lrf_options = [
|
|
||||||
'--comment', description
|
|
||||||
, '--category', category
|
|
||||||
, '--publisher', publisher
|
|
||||||
]
|
|
||||||
|
|
||||||
html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"'
|
|
||||||
|
|
||||||
preprocess_regexps = [(re.compile(u'\u0110'), lambda match: u'\u00D0')]
|
preprocess_regexps = [(re.compile(u'\u0110'), lambda match: u'\u00D0')]
|
||||||
|
|
||||||
feeds = [
|
feeds = [
|
||||||
(u'Vesti', u'http://www.b92.net/info/rss/vesti.xml')
|
(u'Vesti', u'http://www.b92.net/info/rss/vesti.xml')
|
||||||
,(u'Biz' , u'http://www.b92.net/info/rss/biz.xml' )
|
,(u'Biz' , u'http://www.b92.net/info/rss/biz.xml' )
|
||||||
@ -54,9 +56,10 @@ class B92(BasicNewsRecipe):
|
|||||||
return nurl
|
return nurl
|
||||||
|
|
||||||
def preprocess_html(self, soup):
|
def preprocess_html(self, soup):
|
||||||
soup.html['xml:lang'] = 'sr-Latn'
|
lng = 'sr-Latn-RS'
|
||||||
soup.html['lang'] = 'sr-Latn'
|
soup.html['xml:lang'] = lng
|
||||||
mtag = '<meta http-equiv="Content-Language" content="sr-Latn"/>'
|
soup.html['lang'] = lng
|
||||||
|
mtag = '<meta http-equiv="Content-Language" content="sr-Latn-RS"/>'
|
||||||
soup.head.insert(0,mtag)
|
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']
|
||||||
@ -64,4 +67,3 @@ class B92(BasicNewsRecipe):
|
|||||||
del item['align']
|
del item['align']
|
||||||
item.insert(0,'<br /><br />')
|
item.insert(0,'<br /><br />')
|
||||||
return soup
|
return soup
|
||||||
language = _('Serbian')
|
|
@ -1,13 +1,12 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2008, Darko Miletic <darko.miletic at gmail.com>'
|
__copyright__ = '2008-2009, Darko Miletic <darko.miletic at gmail.com>'
|
||||||
'''
|
'''
|
||||||
blic.rs
|
blic.rs
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from calibre.web.feeds.news import BasicNewsRecipe
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
class Blic(BasicNewsRecipe):
|
class Blic(BasicNewsRecipe):
|
||||||
@ -21,15 +20,17 @@ class Blic(BasicNewsRecipe):
|
|||||||
remove_javascript = True
|
remove_javascript = True
|
||||||
no_stylesheets = True
|
no_stylesheets = True
|
||||||
use_embedded_content = False
|
use_embedded_content = False
|
||||||
extra_css = '@font-face {font-family: "serif1";src:url(res:///opt/sony/ebook/FONT/tt0011m_.ttf)} @font-face {font-family: "monospace1";src:url(res:///opt/sony/ebook/FONT/tt0419m_.ttf)} @font-face {font-family: "sans1";src:url(res:///opt/sony/ebook/FONT/tt0003m_.ttf)} body{text-align: left; font-family: serif1, serif} .article_date{font-family: monospace1, monospace} .article_description{font-family: sans1, sans-serif} .navbar{font-family: monospace1, monospace}'
|
language = _('Serbian')
|
||||||
|
extra_css = '@font-face {font-family: "serif1";src:url(res:///opt/sony/ebook/FONT/tt0011m_.ttf)} @font-face {font-family: "sans1";src:url(res:///opt/sony/ebook/FONT/tt0003m_.ttf)} body{font-family: serif1, serif} .article_description{font-family: sans1, sans-serif}'
|
||||||
|
|
||||||
html2lrf_options = [
|
html2lrf_options = [
|
||||||
'--comment', description
|
'--comment' , description
|
||||||
, '--category', category
|
, '--category' , category
|
||||||
, '--publisher', publisher
|
, '--publisher', publisher
|
||||||
|
, '--ignore-tables'
|
||||||
]
|
]
|
||||||
|
|
||||||
html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"'
|
html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"\nlinearize_tables=True'
|
||||||
|
|
||||||
preprocess_regexps = [(re.compile(u'\u0110'), lambda match: u'\u00D0')]
|
preprocess_regexps = [(re.compile(u'\u0110'), lambda match: u'\u00D0')]
|
||||||
|
|
||||||
@ -44,10 +45,9 @@ class Blic(BasicNewsRecipe):
|
|||||||
return u'http://www.blic.rs/_print.php?' + rest_url
|
return u'http://www.blic.rs/_print.php?' + rest_url
|
||||||
|
|
||||||
def preprocess_html(self, soup):
|
def preprocess_html(self, soup):
|
||||||
mtag = '<meta http-equiv="Content-Language" content="sr-Latn"/>'
|
mtag = '<meta http-equiv="Content-Language" content="sr-Latn-RS"/>'
|
||||||
soup.head.insert(0,mtag)
|
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']
|
||||||
return soup
|
return soup
|
||||||
|
|
||||||
language = _('Serbian')
|
|
@ -0,0 +1,45 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
__license__ = 'GPL v3'
|
||||||
|
__copyright__ = '2009, Darko Miletic <darko.miletic at gmail.com>'
|
||||||
|
'''
|
||||||
|
chicagobreakingnews.com
|
||||||
|
'''
|
||||||
|
|
||||||
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
|
class ChicagoBreakingNews(BasicNewsRecipe):
|
||||||
|
title = 'Chicago Breaking News'
|
||||||
|
__author__ = 'Darko Miletic'
|
||||||
|
description = 'Breaking News from Chicago'
|
||||||
|
oldest_article = 1
|
||||||
|
max_articles_per_feed = 100
|
||||||
|
no_stylesheets = True
|
||||||
|
use_embedded_content = True
|
||||||
|
publisher = 'Chicago Breaking News'
|
||||||
|
category = 'news, politics, USA, Chicago'
|
||||||
|
encoding = 'utf8'
|
||||||
|
language = _('English')
|
||||||
|
|
||||||
|
html2lrf_options = [
|
||||||
|
'--comment', description
|
||||||
|
, '--category', category
|
||||||
|
, '--publisher', publisher
|
||||||
|
]
|
||||||
|
|
||||||
|
html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"'
|
||||||
|
|
||||||
|
feeds = [(u'Breaking news', u'http://feeds2.feedburner.com/ChicagoBreakingNews/')]
|
||||||
|
|
||||||
|
def preprocess_html(self, soup):
|
||||||
|
links = soup.findAll('a')
|
||||||
|
for item in soup.findAll('a'):
|
||||||
|
if item['href'].find('http://feedads.googleadservices.com') > -1:
|
||||||
|
item.extract()
|
||||||
|
for item in soup.findAll(style=True):
|
||||||
|
del item['style']
|
||||||
|
for item in soup.findAll(color=True):
|
||||||
|
del item['color']
|
||||||
|
for item in soup.findAll(size=True):
|
||||||
|
del item['size']
|
||||||
|
return soup
|
@ -1,12 +1,11 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2008, Darko Miletic <darko.miletic at gmail.com>'
|
__copyright__ = '2008-2009, Darko Miletic <darko.miletic at gmail.com>'
|
||||||
'''
|
'''
|
||||||
danas.rs
|
danas.rs
|
||||||
'''
|
'''
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from calibre.web.feeds.news import BasicNewsRecipe
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
class Danas(BasicNewsRecipe):
|
class Danas(BasicNewsRecipe):
|
||||||
@ -20,15 +19,17 @@ class Danas(BasicNewsRecipe):
|
|||||||
no_stylesheets = False
|
no_stylesheets = False
|
||||||
remove_javascript = True
|
remove_javascript = True
|
||||||
use_embedded_content = False
|
use_embedded_content = False
|
||||||
extra_css = '@font-face {font-family: "serif1";src:url(res:///opt/sony/ebook/FONT/tt0011m_.ttf)} @font-face {font-family: "monospace1";src:url(res:///opt/sony/ebook/FONT/tt0419m_.ttf)} @font-face {font-family: "sans1";src:url(res:///opt/sony/ebook/FONT/tt0003m_.ttf)} body{text-align: left; font-family: serif1, serif} .article_date{font-family: monospace1, monospace} .article_description{font-family: sans1, sans-serif} .navbar{font-family: monospace1, monospace}'
|
language = _('Serbian')
|
||||||
|
extra_css = '@font-face {font-family: "serif1";src:url(res:///opt/sony/ebook/FONT/tt0011m_.ttf)} @font-face {font-family: "sans1";src:url(res:///opt/sony/ebook/FONT/tt0003m_.ttf)} body{font-family: serif1, serif} .article_description{font-family: sans1, sans-serif}'
|
||||||
|
|
||||||
html2lrf_options = [
|
html2lrf_options = [
|
||||||
'--comment', description
|
'--comment' , description
|
||||||
, '--category', category
|
, '--category' , category
|
||||||
, '--publisher', publisher
|
, '--publisher', publisher
|
||||||
|
, '--ignore-tables'
|
||||||
]
|
]
|
||||||
|
|
||||||
html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"'
|
html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"\nlinearize_tables=True'
|
||||||
|
|
||||||
|
|
||||||
preprocess_regexps = [(re.compile(u'\u0110'), lambda match: u'\u00D0')]
|
preprocess_regexps = [(re.compile(u'\u0110'), lambda match: u'\u00D0')]
|
||||||
@ -43,9 +44,8 @@ class Danas(BasicNewsRecipe):
|
|||||||
feeds = [ (u'Vesti', u'http://www.danas.rs/rss/rss.asp')]
|
feeds = [ (u'Vesti', u'http://www.danas.rs/rss/rss.asp')]
|
||||||
|
|
||||||
def preprocess_html(self, soup):
|
def preprocess_html(self, soup):
|
||||||
mtag = '<meta http-equiv="Content-Language" content="sr-Latn"/>'
|
mtag = '<meta http-equiv="Content-Language" content="sr-Latn-RS"/>'
|
||||||
soup.head.insert(0,mtag)
|
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']
|
||||||
return soup
|
return soup
|
||||||
language = _('Serbian')
|
|
@ -5,7 +5,6 @@ __copyright__ = '2008-2009, Darko Miletic <darko.miletic at gmail.com>'
|
|||||||
'''
|
'''
|
||||||
elargentino.com
|
elargentino.com
|
||||||
'''
|
'''
|
||||||
|
|
||||||
from calibre.web.feeds.news import BasicNewsRecipe
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
class ElArgentino(BasicNewsRecipe):
|
class ElArgentino(BasicNewsRecipe):
|
||||||
@ -21,6 +20,7 @@ class ElArgentino(BasicNewsRecipe):
|
|||||||
use_embedded_content = False
|
use_embedded_content = False
|
||||||
encoding = 'utf8'
|
encoding = 'utf8'
|
||||||
cover_url = 'http://www.elargentino.com/TemplateWeb/MediosFooter/tapa_elargentino.png'
|
cover_url = 'http://www.elargentino.com/TemplateWeb/MediosFooter/tapa_elargentino.png'
|
||||||
|
language = _('Spanish')
|
||||||
|
|
||||||
html2lrf_options = [
|
html2lrf_options = [
|
||||||
'--comment', description
|
'--comment', description
|
||||||
@ -59,5 +59,3 @@ class ElArgentino(BasicNewsRecipe):
|
|||||||
for item in soup.findAll(style=True):
|
for item in soup.findAll(style=True):
|
||||||
del item['style']
|
del item['style']
|
||||||
return soup
|
return soup
|
||||||
|
|
||||||
language = _('Spanish')
|
|
34
src/calibre/web/feeds/recipes/recipe_glasgow_herald.py
Normal file
34
src/calibre/web/feeds/recipes/recipe_glasgow_herald.py
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import re
|
||||||
|
|
||||||
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
|
class GlasgowHerald(BasicNewsRecipe):
|
||||||
|
title = u'Glasgow Herald'
|
||||||
|
oldest_article = 1
|
||||||
|
max_articles_per_feed = 100
|
||||||
|
no_stylesheets = True
|
||||||
|
language = _('English')
|
||||||
|
__author__ = 'McCande'
|
||||||
|
|
||||||
|
preprocess_regexps = [ (re.compile(i[0], re.IGNORECASE | re.DOTALL), i[1]) for i in
|
||||||
|
[
|
||||||
|
(r'<center><h3>', lambda match : '<h3>'),
|
||||||
|
(r'Click here to comment on this story...', lambda match : ''),
|
||||||
|
(r'<h3>Related links</h3>.*?</head>', lambda match : '</head>'),
|
||||||
|
]
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
feeds = [
|
||||||
|
(u'News', u'http://www.theherald.co.uk/news/news/rss.xml'),
|
||||||
|
(u'Politics', u'http://www.theherald.co.uk/politics/news/rss.xml'),
|
||||||
|
(u'Features', u'http://www.theherald.co.uk/features/features/rss.xml'),
|
||||||
|
(u'Business', u'http://www.theherald.co.uk/business/news/rss.xml')]
|
||||||
|
|
||||||
|
def print_version(self, url):
|
||||||
|
(beginning,end)=url.split(".var.")
|
||||||
|
num=end[0:7]
|
||||||
|
main="http://www.theherald.co.uk/misc/print.php?artid="+num
|
||||||
|
return main
|
@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2008, Darko Miletic <darko.miletic at gmail.com>'
|
__copyright__ = '2008-2009, Darko Miletic <darko.miletic at gmail.com>'
|
||||||
'''
|
'''
|
||||||
granma.cubaweb.cu
|
granma.cubaweb.cu
|
||||||
'''
|
'''
|
||||||
@ -21,19 +21,22 @@ class Granma(BasicNewsRecipe):
|
|||||||
use_embedded_content = False
|
use_embedded_content = False
|
||||||
encoding = 'cp1252'
|
encoding = 'cp1252'
|
||||||
cover_url = 'http://www.granma.cubaweb.cu/imagenes/granweb229d.jpg'
|
cover_url = 'http://www.granma.cubaweb.cu/imagenes/granweb229d.jpg'
|
||||||
|
language = _('Spanish')
|
||||||
remove_javascript = True
|
remove_javascript = True
|
||||||
|
|
||||||
html2lrf_options = [
|
html2lrf_options = [
|
||||||
'--comment', description
|
'--comment' , description
|
||||||
, '--category', category
|
, '--category' , category
|
||||||
, '--publisher', publisher
|
, '--publisher', publisher
|
||||||
, '--ignore-tables'
|
, '--ignore-tables'
|
||||||
]
|
]
|
||||||
|
|
||||||
html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"'
|
html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"\nlinearize_tables=True'
|
||||||
|
|
||||||
keep_only_tags = [dict(name='table', attrs={'height':'466'})]
|
keep_only_tags = [dict(name='table', attrs={'height':'466'})]
|
||||||
|
|
||||||
|
remove_tags = [dict(name=['embed','link','object'])]
|
||||||
|
|
||||||
feeds = [(u'Noticias', u'http://www.granma.cubaweb.cu/noticias.xml' )]
|
feeds = [(u'Noticias', u'http://www.granma.cubaweb.cu/noticias.xml' )]
|
||||||
|
|
||||||
|
|
||||||
@ -49,4 +52,3 @@ class Granma(BasicNewsRecipe):
|
|||||||
del item['style']
|
del item['style']
|
||||||
return soup
|
return soup
|
||||||
|
|
||||||
language = _('Spanish')
|
|
@ -14,21 +14,28 @@ class Infobae(BasicNewsRecipe):
|
|||||||
description = 'Informacion Libre las 24 horas'
|
description = 'Informacion Libre las 24 horas'
|
||||||
publisher = 'Infobae.com'
|
publisher = 'Infobae.com'
|
||||||
category = 'news, politics, Argentina'
|
category = 'news, politics, Argentina'
|
||||||
oldest_article = 2
|
oldest_article = 1
|
||||||
max_articles_per_feed = 100
|
max_articles_per_feed = 100
|
||||||
no_stylesheets = True
|
no_stylesheets = True
|
||||||
use_embedded_content = False
|
use_embedded_content = False
|
||||||
|
language = _('Spanish')
|
||||||
encoding = 'iso-8859-1'
|
encoding = 'iso-8859-1'
|
||||||
cover_url = 'http://www.infobae.com/imgs/header/header.gif'
|
cover_url = 'http://www.infobae.com/imgs/header/header.gif'
|
||||||
remove_javascript = True
|
remove_javascript = True
|
||||||
|
|
||||||
html2lrf_options = [
|
html2lrf_options = [
|
||||||
'--comment', description
|
'--comment' , description
|
||||||
, '--category', category
|
, '--category' , category
|
||||||
, '--publisher', publisher
|
, '--publisher', publisher
|
||||||
|
, '--ignore-tables'
|
||||||
]
|
]
|
||||||
|
|
||||||
html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"'
|
html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"\nlinearize_tables=True'
|
||||||
|
|
||||||
|
remove_tags = [
|
||||||
|
dict(name=['embed','link','object'])
|
||||||
|
,dict(name='a', attrs={'onclick':'javascript:window.print()'})
|
||||||
|
]
|
||||||
|
|
||||||
feeds = [
|
feeds = [
|
||||||
(u'Noticias' , u'http://www.infobae.com/adjuntos/html/RSS/hoy.xml' )
|
(u'Noticias' , u'http://www.infobae.com/adjuntos/html/RSS/hoy.xml' )
|
||||||
@ -48,5 +55,3 @@ class Infobae(BasicNewsRecipe):
|
|||||||
for item in soup.findAll(style=True):
|
for item in soup.findAll(style=True):
|
||||||
del item['style']
|
del item['style']
|
||||||
return soup
|
return soup
|
||||||
|
|
||||||
language = _('Spanish')
|
|
@ -1,13 +1,12 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2008, Darko Miletic <darko.miletic at gmail.com>'
|
__copyright__ = '2008-2009, Darko Miletic <darko.miletic at gmail.com>'
|
||||||
'''
|
'''
|
||||||
jutarnji.hr
|
jutarnji.hr
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from calibre.web.feeds.news import BasicNewsRecipe
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
class Jutarnji(BasicNewsRecipe):
|
class Jutarnji(BasicNewsRecipe):
|
||||||
@ -16,32 +15,32 @@ class Jutarnji(BasicNewsRecipe):
|
|||||||
description = u'Hrvatski portal'
|
description = u'Hrvatski portal'
|
||||||
publisher = 'Jutarnji.hr'
|
publisher = 'Jutarnji.hr'
|
||||||
category = 'news, politics, Croatia'
|
category = 'news, politics, Croatia'
|
||||||
oldest_article = 2
|
oldest_article = 1
|
||||||
max_articles_per_feed = 100
|
max_articles_per_feed = 100
|
||||||
simultaneous_downloads = 1
|
simultaneous_downloads = 2
|
||||||
delay = 1
|
delay = 1
|
||||||
language = _('Croatian')
|
language = _('Croatian')
|
||||||
no_stylesheets = True
|
no_stylesheets = True
|
||||||
use_embedded_content = False
|
use_embedded_content = False
|
||||||
remove_javascript = True
|
remove_javascript = True
|
||||||
encoding = 'cp1250'
|
encoding = 'cp1250'
|
||||||
extra_css = '@font-face {font-family: "serif1";src:url(res:///opt/sony/ebook/FONT/tt0011m_.ttf)} @font-face {font-family: "monospace1";src:url(res:///opt/sony/ebook/FONT/tt0419m_.ttf)} @font-face {font-family: "sans1";src:url(res:///opt/sony/ebook/FONT/tt0003m_.ttf)} body{text-align: left; font-family: serif1, serif} .article_date{font-family: monospace1, monospace} .article_description{font-family: sans1, sans-serif} .navbar{font-family: monospace1, monospace}'
|
extra_css = '@font-face {font-family: "serif1";src:url(res:///opt/sony/ebook/FONT/tt0011m_.ttf)} @font-face {font-family: "sans1";src:url(res:///opt/sony/ebook/FONT/tt0003m_.ttf)} body{text-align: justify; font-family: serif1, serif} .article_description{font-family: sans1, sans-serif}'
|
||||||
|
|
||||||
html2lrf_options = [
|
html2lrf_options = [
|
||||||
'--comment', description
|
'--comment' , description
|
||||||
, '--category', category
|
, '--category' , category
|
||||||
, '--publisher', publisher
|
, '--publisher', publisher
|
||||||
|
, '--ignore-tables'
|
||||||
]
|
]
|
||||||
|
|
||||||
html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"'
|
html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"\nlinearize_tables=True'
|
||||||
|
|
||||||
|
|
||||||
preprocess_regexps = [(re.compile(u'\u0110'), lambda match: u'\u00D0')]
|
preprocess_regexps = [(re.compile(u'\u0110'), lambda match: u'\u00D0')]
|
||||||
|
|
||||||
remove_tags = [
|
remove_tags = [
|
||||||
dict(name='embed')
|
dict(name=['embed','hr','link','object'])
|
||||||
,dict(name='a', attrs={'class':'a11'})
|
,dict(name='a', attrs={'class':'a11'})
|
||||||
,dict(name='hr')
|
|
||||||
]
|
]
|
||||||
|
|
||||||
feeds = [
|
feeds = [
|
||||||
@ -60,9 +59,7 @@ class Jutarnji(BasicNewsRecipe):
|
|||||||
return 'http://www.jutarnji.hr/ispis_clanka.jl?artid=' + rrest
|
return 'http://www.jutarnji.hr/ispis_clanka.jl?artid=' + rrest
|
||||||
|
|
||||||
def preprocess_html(self, soup):
|
def preprocess_html(self, soup):
|
||||||
mtag = '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">'
|
mtag = '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">\n<meta http-equiv="Content-Language" content="hr-HR"/>'
|
||||||
soup.head.insert(0,mtag)
|
|
||||||
mtag = '<meta http-equiv="Content-Language" content="hr"/>'
|
|
||||||
soup.head.insert(0,mtag)
|
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']
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2008, Darko Miletic <darko.miletic at gmail.com>'
|
__copyright__ = '2008-2009, Darko Miletic <darko.miletic at gmail.com>'
|
||||||
'''
|
'''
|
||||||
juventudrebelde.cu
|
juventudrebelde.cu
|
||||||
'''
|
'''
|
||||||
from calibre import strftime
|
|
||||||
|
|
||||||
|
from calibre import strftime
|
||||||
from calibre.web.feeds.news import BasicNewsRecipe
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
class Juventudrebelde(BasicNewsRecipe):
|
class Juventudrebelde(BasicNewsRecipe):
|
||||||
@ -20,17 +20,18 @@ class Juventudrebelde(BasicNewsRecipe):
|
|||||||
no_stylesheets = True
|
no_stylesheets = True
|
||||||
use_embedded_content = False
|
use_embedded_content = False
|
||||||
encoding = 'cp1252'
|
encoding = 'cp1252'
|
||||||
|
language = _('Spanish')
|
||||||
cover_url = strftime('http://www.juventudrebelde.cu/UserFiles/File/impreso/iportada-%Y-%m-%d.jpg')
|
cover_url = strftime('http://www.juventudrebelde.cu/UserFiles/File/impreso/iportada-%Y-%m-%d.jpg')
|
||||||
remove_javascript = True
|
remove_javascript = True
|
||||||
|
|
||||||
html2lrf_options = [
|
html2lrf_options = [
|
||||||
'--comment', description
|
'--comment' , description
|
||||||
, '--category', category
|
, '--category' , category
|
||||||
, '--publisher', publisher
|
, '--publisher', publisher
|
||||||
, '--ignore-tables'
|
, '--ignore-tables'
|
||||||
]
|
]
|
||||||
|
|
||||||
html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"'
|
html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"\nlinearize_tables=True'
|
||||||
|
|
||||||
keep_only_tags = [dict(name='div', attrs={'id':'noticia'})]
|
keep_only_tags = [dict(name='div', attrs={'id':'noticia'})]
|
||||||
|
|
||||||
@ -51,4 +52,3 @@ class Juventudrebelde(BasicNewsRecipe):
|
|||||||
del item['style']
|
del item['style']
|
||||||
return soup
|
return soup
|
||||||
|
|
||||||
language = _('Spanish')
|
|
@ -1,13 +1,12 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2008, Darko Miletic <darko.miletic at gmail.com>'
|
__copyright__ = '2008-2009, Darko Miletic <darko.miletic at gmail.com>'
|
||||||
'''
|
'''
|
||||||
nin.co.yu
|
nin.co.yu
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import re, urllib
|
import re, urllib
|
||||||
|
|
||||||
from calibre.web.feeds.news import BasicNewsRecipe
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
class Nin(BasicNewsRecipe):
|
class Nin(BasicNewsRecipe):
|
||||||
@ -27,15 +26,17 @@ class Nin(BasicNewsRecipe):
|
|||||||
LOGIN = PREFIX + '/?logout=true'
|
LOGIN = PREFIX + '/?logout=true'
|
||||||
remove_javascript = True
|
remove_javascript = True
|
||||||
use_embedded_content = False
|
use_embedded_content = False
|
||||||
extra_css = '@font-face {font-family: "serif1";src:url(res:///opt/sony/ebook/FONT/tt0011m_.ttf)} @font-face {font-family: "monospace1";src:url(res:///opt/sony/ebook/FONT/tt0419m_.ttf)} @font-face {font-family: "sans1";src:url(res:///opt/sony/ebook/FONT/tt0003m_.ttf)} body{text-align: left; font-family: serif1, serif} .article_date{font-family: monospace1, monospace} .article_description{font-family: sans1, sans-serif} .navbar{font-family: monospace1, monospace}'
|
language = _('Serbian')
|
||||||
|
extra_css = '@font-face {font-family: "serif1";src:url(res:///opt/sony/ebook/FONT/tt0011m_.ttf)} @font-face {font-family: "sans1";src:url(res:///opt/sony/ebook/FONT/tt0003m_.ttf)} body{text-align: justify; font-family: serif1, serif} .article_description{font-family: sans1, sans-serif}'
|
||||||
|
|
||||||
html2lrf_options = [
|
html2lrf_options = [
|
||||||
'--comment', description
|
'--comment' , description
|
||||||
, '--category', category
|
, '--category' , category
|
||||||
, '--publisher', publisher
|
, '--publisher', publisher
|
||||||
|
, '--ignore-tables'
|
||||||
]
|
]
|
||||||
|
|
||||||
html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"'
|
html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"\nlinearize_tables=True'
|
||||||
|
|
||||||
preprocess_regexps = [(re.compile(u'\u0110'), lambda match: u'\u00D0')]
|
preprocess_regexps = [(re.compile(u'\u0110'), lambda match: u'\u00D0')]
|
||||||
|
|
||||||
@ -69,5 +70,3 @@ class Nin(BasicNewsRecipe):
|
|||||||
for item in soup.findAll(style=True):
|
for item in soup.findAll(style=True):
|
||||||
del item['style']
|
del item['style']
|
||||||
return soup
|
return soup
|
||||||
|
|
||||||
language = _('Serbian')
|
|
@ -1,13 +1,12 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2008, Darko Miletic <darko.miletic at gmail.com>'
|
__copyright__ = '2008-2009, Darko Miletic <darko.miletic at gmail.com>'
|
||||||
'''
|
'''
|
||||||
novosti.rs
|
novosti.rs
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from calibre.web.feeds.news import BasicNewsRecipe
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
class Novosti(BasicNewsRecipe):
|
class Novosti(BasicNewsRecipe):
|
||||||
@ -22,15 +21,17 @@ class Novosti(BasicNewsRecipe):
|
|||||||
use_embedded_content = False
|
use_embedded_content = False
|
||||||
encoding = 'utf8'
|
encoding = 'utf8'
|
||||||
remove_javascript = True
|
remove_javascript = True
|
||||||
extra_css = '@font-face {font-family: "serif1";src:url(res:///opt/sony/ebook/FONT/tt0011m_.ttf)} @font-face {font-family: "monospace1";src:url(res:///opt/sony/ebook/FONT/tt0419m_.ttf)} @font-face {font-family: "sans1";src:url(res:///opt/sony/ebook/FONT/tt0003m_.ttf)} body{text-align: left; font-family: serif1, serif} .article_date{font-family: monospace1, monospace} .article_description{font-family: sans1, sans-serif} .navbar{font-family: monospace1, monospace}'
|
language = _('Serbian')
|
||||||
|
extra_css = '@font-face {font-family: "serif1";src:url(res:///opt/sony/ebook/FONT/tt0011m_.ttf)} @font-face {font-family: "sans1";src:url(res:///opt/sony/ebook/FONT/tt0003m_.ttf)} body{font-family: serif1, serif} .article_description{font-family: sans1, sans-serif}'
|
||||||
|
|
||||||
html2lrf_options = [
|
html2lrf_options = [
|
||||||
'--comment', description
|
'--comment' , description
|
||||||
, '--category', category
|
, '--category' , category
|
||||||
, '--publisher', publisher
|
, '--publisher', publisher
|
||||||
|
, '--ignore-tables'
|
||||||
]
|
]
|
||||||
|
|
||||||
html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"'
|
html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"\nlinearize_tables=True'
|
||||||
|
|
||||||
preprocess_regexps = [(re.compile(u'\u0110'), lambda match: u'\u00D0')]
|
preprocess_regexps = [(re.compile(u'\u0110'), lambda match: u'\u00D0')]
|
||||||
|
|
||||||
@ -40,10 +41,8 @@ class Novosti(BasicNewsRecipe):
|
|||||||
feeds = [(u'Vesti', u'http://www.novosti.rs/php/vesti/rss.php')]
|
feeds = [(u'Vesti', u'http://www.novosti.rs/php/vesti/rss.php')]
|
||||||
|
|
||||||
def preprocess_html(self, soup):
|
def preprocess_html(self, soup):
|
||||||
mtag = '<meta http-equiv="Content-Language" content="sr-Latn"/>'
|
mtag = '<meta http-equiv="Content-Language" content="sr-Latn-RS"/>'
|
||||||
soup.head.insert(0,mtag)
|
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']
|
||||||
return soup
|
return soup
|
||||||
|
|
||||||
language = _('Serbian')
|
|
@ -1,13 +1,12 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2008, Darko Miletic <darko.miletic at gmail.com>'
|
__copyright__ = '2008-2009, Darko Miletic <darko.miletic at gmail.com>'
|
||||||
'''
|
'''
|
||||||
nspm.rs
|
nspm.rs
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from calibre.web.feeds.news import BasicNewsRecipe
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
class Nspm(BasicNewsRecipe):
|
class Nspm(BasicNewsRecipe):
|
||||||
@ -16,26 +15,30 @@ class Nspm(BasicNewsRecipe):
|
|||||||
description = 'Casopis za politicku teoriju i drustvena istrazivanja'
|
description = 'Casopis za politicku teoriju i drustvena istrazivanja'
|
||||||
publisher = 'NSPM'
|
publisher = 'NSPM'
|
||||||
category = 'news, politics, Serbia'
|
category = 'news, politics, Serbia'
|
||||||
oldest_article = 7
|
oldest_article = 2
|
||||||
max_articles_per_feed = 100
|
max_articles_per_feed = 100
|
||||||
no_stylesheets = True
|
no_stylesheets = True
|
||||||
use_embedded_content = False
|
use_embedded_content = False
|
||||||
INDEX = 'http://www.nspm.rs/?alphabet=l'
|
INDEX = 'http://www.nspm.rs/?alphabet=l'
|
||||||
encoding = 'utf8'
|
encoding = 'utf8'
|
||||||
remove_javascript = True
|
remove_javascript = True
|
||||||
extra_css = '@font-face {font-family: "serif1";src:url(res:///opt/sony/ebook/FONT/tt0011m_.ttf)} @font-face {font-family: "monospace1";src:url(res:///opt/sony/ebook/FONT/tt0419m_.ttf)} @font-face {font-family: "sans1";src:url(res:///opt/sony/ebook/FONT/tt0003m_.ttf)} body{text-align: left; font-family: serif1, serif} .article_date{font-family: monospace1, monospace} .article_description{font-family: sans1, sans-serif} .navbar{font-family: monospace1, monospace}'
|
language = _('Serbian')
|
||||||
|
extra_css = '@font-face {font-family: "serif1";src:url(res:///opt/sony/ebook/FONT/tt0011m_.ttf)} @font-face {font-family: "sans1";src:url(res:///opt/sony/ebook/FONT/tt0003m_.ttf)} body{text-align: justify; font-family: serif1, serif} .article_description{font-family: sans1, sans-serif}'
|
||||||
|
|
||||||
html2lrf_options = [
|
html2lrf_options = [
|
||||||
'--comment', description
|
'--comment' , description
|
||||||
, '--category', category
|
, '--category' , category
|
||||||
, '--publisher', publisher
|
, '--publisher', publisher
|
||||||
, '--ignore-tables'
|
, '--ignore-tables'
|
||||||
]
|
]
|
||||||
|
|
||||||
html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"'
|
html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"\nlinearize_tables=True'
|
||||||
|
|
||||||
preprocess_regexps = [(re.compile(u'\u0110'), lambda match: u'\u00D0')]
|
preprocess_regexps = [(re.compile(u'\u0110'), lambda match: u'\u00D0')]
|
||||||
remove_tags = [dict(name='a')]
|
remove_tags = [
|
||||||
|
dict(name=['a','img','link','object','embed'])
|
||||||
|
,dict(name='td', attrs={'class':'buttonheading'})
|
||||||
|
]
|
||||||
|
|
||||||
def get_browser(self):
|
def get_browser(self):
|
||||||
br = BasicNewsRecipe.get_browser()
|
br = BasicNewsRecipe.get_browser()
|
||||||
@ -48,13 +51,12 @@ class Nspm(BasicNewsRecipe):
|
|||||||
return url.replace('.html','/stampa.html')
|
return url.replace('.html','/stampa.html')
|
||||||
|
|
||||||
def preprocess_html(self, soup):
|
def preprocess_html(self, soup):
|
||||||
soup.html['xml:lang'] = 'sr-Latn-RS'
|
lng = 'sr-Latn-RS'
|
||||||
soup.html['lang'] = 'sr-Latn-RS'
|
soup.html['xml:lang'] = lng
|
||||||
|
soup.html['lang'] = lng
|
||||||
ftag = soup.find('meta',attrs={'http-equiv':'Content-Language'})
|
ftag = soup.find('meta',attrs={'http-equiv':'Content-Language'})
|
||||||
if ftag:
|
if ftag:
|
||||||
ftag['content'] = 'sr-Latn-RS'
|
ftag['content'] = lng
|
||||||
for item in soup.findAll(style=True):
|
for item in soup.findAll(style=True):
|
||||||
del item['style']
|
del item['style']
|
||||||
return soup
|
return soup
|
||||||
|
|
||||||
language = _('Serbian')
|
|
@ -1,13 +1,12 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2008, Darko Miletic <darko.miletic at gmail.com>'
|
__copyright__ = '2008-2009, Darko Miletic <darko.miletic at gmail.com>'
|
||||||
'''
|
'''
|
||||||
pescanik.net
|
pescanik.net
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from calibre.web.feeds.news import BasicNewsRecipe
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
class Pescanik(BasicNewsRecipe):
|
class Pescanik(BasicNewsRecipe):
|
||||||
@ -16,30 +15,32 @@ class Pescanik(BasicNewsRecipe):
|
|||||||
description = 'Pescanik'
|
description = 'Pescanik'
|
||||||
publisher = 'Pescanik'
|
publisher = 'Pescanik'
|
||||||
category = 'news, politics, Serbia'
|
category = 'news, politics, Serbia'
|
||||||
oldest_article = 7
|
oldest_article = 5
|
||||||
max_articles_per_feed = 100
|
max_articles_per_feed = 100
|
||||||
no_stylesheets = True
|
no_stylesheets = True
|
||||||
use_embedded_content = False
|
use_embedded_content = False
|
||||||
remove_javascript = True
|
remove_javascript = True
|
||||||
encoding = 'utf8'
|
encoding = 'utf8'
|
||||||
extra_css = '@font-face {font-family: "serif1";src:url(res:///opt/sony/ebook/FONT/tt0011m_.ttf)} @font-face {font-family: "monospace1";src:url(res:///opt/sony/ebook/FONT/tt0419m_.ttf)} @font-face {font-family: "sans1";src:url(res:///opt/sony/ebook/FONT/tt0003m_.ttf)} body{text-align: left; font-family: serif1, serif} .article_date{font-family: monospace1, monospace} .article_description{font-family: sans1, sans-serif} .navbar{font-family: monospace1, monospace}'
|
cover_url = "http://pescanik.net/templates/ja_teline/images/logo.png"
|
||||||
|
language = _('Serbian')
|
||||||
|
extra_css = '@font-face {font-family: "serif1";src:url(res:///opt/sony/ebook/FONT/tt0011m_.ttf)} @font-face {font-family: "sans1";src:url(res:///opt/sony/ebook/FONT/tt0003m_.ttf)} body{font-family: serif1, serif} .article_description{font-family: sans1, sans-serif}'
|
||||||
|
|
||||||
html2lrf_options = [
|
html2lrf_options = [
|
||||||
'--comment', description
|
'--comment' , description
|
||||||
, '--category', category
|
, '--category' , category
|
||||||
, '--publisher', publisher
|
, '--publisher', publisher
|
||||||
|
, '--ignore-tables'
|
||||||
]
|
]
|
||||||
|
|
||||||
html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"'
|
html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"\nlinearize_tables=True'
|
||||||
|
|
||||||
cover_url = "http://pescanik.net/templates/ja_teline/images/logo.png"
|
|
||||||
|
|
||||||
preprocess_regexps = [(re.compile(u'\u0110'), lambda match: u'\u00D0')]
|
preprocess_regexps = [(re.compile(u'\u0110'), lambda match: u'\u00D0')]
|
||||||
|
|
||||||
remove_tags = [
|
remove_tags = [
|
||||||
dict(name='td' , attrs={'class':'buttonheading'})
|
dict(name='td' , attrs={'class':'buttonheading'})
|
||||||
,dict(name='span', attrs={'class':'article_seperator'})
|
,dict(name='span', attrs={'class':'article_seperator'})
|
||||||
,dict(name=['object','link'])
|
,dict(name=['object','link','img','h4','ul'])
|
||||||
]
|
]
|
||||||
|
|
||||||
feeds = [(u'Pescanik Online', u'http://pescanik.net/index.php?option=com_rd_rss&id=12')]
|
feeds = [(u'Pescanik Online', u'http://pescanik.net/index.php?option=com_rd_rss&id=12')]
|
||||||
@ -54,5 +55,3 @@ class Pescanik(BasicNewsRecipe):
|
|||||||
for item in soup.findAll(style=True):
|
for item in soup.findAll(style=True):
|
||||||
del item['style']
|
del item['style']
|
||||||
return soup
|
return soup
|
||||||
|
|
||||||
language = _('Serbian')
|
|
@ -6,7 +6,6 @@ __copyright__ = '2008, Darko Miletic <darko.miletic at gmail.com>'
|
|||||||
politika.rs
|
politika.rs
|
||||||
'''
|
'''
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from calibre.web.feeds.news import BasicNewsRecipe
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
class Politika(BasicNewsRecipe):
|
class Politika(BasicNewsRecipe):
|
||||||
@ -16,13 +15,13 @@ class Politika(BasicNewsRecipe):
|
|||||||
publisher = 'Politika novine i Magazini d.o.o'
|
publisher = 'Politika novine i Magazini d.o.o'
|
||||||
category = 'news, politics, Serbia'
|
category = 'news, politics, Serbia'
|
||||||
oldest_article = 2
|
oldest_article = 2
|
||||||
language = _('Serbian')
|
|
||||||
max_articles_per_feed = 100
|
max_articles_per_feed = 100
|
||||||
no_stylesheets = True
|
no_stylesheets = True
|
||||||
use_embedded_content = False
|
use_embedded_content = False
|
||||||
remove_javascript = True
|
remove_javascript = True
|
||||||
encoding = 'utf8'
|
encoding = 'utf8'
|
||||||
extra_css = '@font-face {font-family: "serif1";src:url(res:///opt/sony/ebook/FONT/tt0011m_.ttf)} @font-face {font-family: "monospace1";src:url(res:///opt/sony/ebook/FONT/tt0419m_.ttf)} @font-face {font-family: "sans1";src:url(res:///opt/sony/ebook/FONT/tt0003m_.ttf)} body{text-align: left; font-family: serif1, serif} .article_date{font-family: monospace1, monospace} .article_description{font-family: sans1, sans-serif} .navbar{font-family: monospace1, monospace}'
|
language = _('Serbian')
|
||||||
|
extra_css = '@font-face {font-family: "serif1";src:url(res:///opt/sony/ebook/FONT/tt0011m_.ttf)} @font-face {font-family: "sans1";src:url(res:///opt/sony/ebook/FONT/tt0003m_.ttf)} body{font-family: serif1, serif} .article_description{font-family: sans1, sans-serif}'
|
||||||
|
|
||||||
html2lrf_options = [
|
html2lrf_options = [
|
||||||
'--comment', description
|
'--comment', description
|
||||||
@ -61,6 +60,6 @@ class Politika(BasicNewsRecipe):
|
|||||||
for item in soup.findAll(style=True):
|
for item in soup.findAll(style=True):
|
||||||
del item['style']
|
del item['style']
|
||||||
ftag = soup.find('div',attrs={'class':'content_center_border'})
|
ftag = soup.find('div',attrs={'class':'content_center_border'})
|
||||||
if ftag:
|
if ftag.has_key('align'):
|
||||||
ftag['align'] = 'left'
|
del ftag['align']
|
||||||
return soup
|
return soup
|
||||||
|
@ -4,11 +4,10 @@ __license__ = 'GPL v3'
|
|||||||
__copyright__ = '2009, Darko Miletic <darko.miletic at gmail.com>'
|
__copyright__ = '2009, Darko Miletic <darko.miletic at gmail.com>'
|
||||||
|
|
||||||
'''
|
'''
|
||||||
vijesti.cg.yu
|
vijesti.me
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from calibre.web.feeds.news import BasicNewsRecipe
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
class Vijesti(BasicNewsRecipe):
|
class Vijesti(BasicNewsRecipe):
|
||||||
@ -22,10 +21,11 @@ class Vijesti(BasicNewsRecipe):
|
|||||||
no_stylesheets = True
|
no_stylesheets = True
|
||||||
remove_javascript = True
|
remove_javascript = True
|
||||||
encoding = 'cp1250'
|
encoding = 'cp1250'
|
||||||
cover_url = 'http://www.vijesti.cg.yu/img/logo.gif'
|
cover_url = 'http://www.vijesti.me/img/logo.gif'
|
||||||
remove_javascript = True
|
remove_javascript = True
|
||||||
use_embedded_content = False
|
use_embedded_content = False
|
||||||
extra_css = '@font-face {font-family: "serif1";src:url(res:///opt/sony/ebook/FONT/tt0011m_.ttf)} @font-face {font-family: "monospace1";src:url(res:///opt/sony/ebook/FONT/tt0419m_.ttf)} @font-face {font-family: "sans1";src:url(res:///opt/sony/ebook/FONT/tt0003m_.ttf)} body{text-align: left; font-family: serif1, serif} .article_date{font-family: monospace1, monospace} .article_description{font-family: sans1, sans-serif} .navbar{font-family: monospace1, monospace}'
|
language = _('Serbian')
|
||||||
|
extra_css = '@font-face {font-family: "serif1";src:url(res:///opt/sony/ebook/FONT/tt0011m_.ttf)} @font-face {font-family: "sans1";src:url(res:///opt/sony/ebook/FONT/tt0003m_.ttf)} body{text-align: justify; font-family: serif1, serif} .article_description{font-family: sans1, sans-serif}'
|
||||||
|
|
||||||
html2lrf_options = [
|
html2lrf_options = [
|
||||||
'--comment', description
|
'--comment', description
|
||||||
@ -39,12 +39,9 @@ class Vijesti(BasicNewsRecipe):
|
|||||||
|
|
||||||
keep_only_tags = [dict(name='div', attrs={'id':'mainnews'})]
|
keep_only_tags = [dict(name='div', attrs={'id':'mainnews'})]
|
||||||
|
|
||||||
remove_tags = [
|
remove_tags = [dict(name=['object','link','embed'])]
|
||||||
dict(name='div', attrs={'align':'right'})
|
|
||||||
,dict(name=['object','link'])
|
|
||||||
]
|
|
||||||
|
|
||||||
feeds = [(u'Sve vijesti', u'http://www.vijesti.cg.yu/rss.php' )]
|
feeds = [(u'Sve vijesti', u'http://www.vijesti.me/rss.php' )]
|
||||||
|
|
||||||
def preprocess_html(self, soup):
|
def preprocess_html(self, soup):
|
||||||
soup.html['xml:lang'] = 'sr-Latn-ME'
|
soup.html['xml:lang'] = 'sr-Latn-ME'
|
||||||
@ -56,5 +53,3 @@ class Vijesti(BasicNewsRecipe):
|
|||||||
del item['align']
|
del item['align']
|
||||||
item.insert(0,'<br /><br />')
|
item.insert(0,'<br /><br />')
|
||||||
return soup
|
return soup
|
||||||
|
|
||||||
language = _('Serbian')
|
|
@ -1,14 +1,13 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2008, Darko Miletic <darko.miletic at gmail.com>'
|
__copyright__ = '2008-2009, Darko Miletic <darko.miletic at gmail.com>'
|
||||||
'''
|
'''
|
||||||
vreme.com
|
vreme.com
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import re
|
import re
|
||||||
from calibre import strftime
|
from calibre import strftime
|
||||||
|
|
||||||
from calibre.web.feeds.news import BasicNewsRecipe
|
from calibre.web.feeds.news import BasicNewsRecipe
|
||||||
|
|
||||||
class Vreme(BasicNewsRecipe):
|
class Vreme(BasicNewsRecipe):
|
||||||
@ -24,15 +23,17 @@ class Vreme(BasicNewsRecipe):
|
|||||||
LOGIN = 'http://www.vreme.com/account/index.php'
|
LOGIN = 'http://www.vreme.com/account/index.php'
|
||||||
remove_javascript = True
|
remove_javascript = True
|
||||||
use_embedded_content = False
|
use_embedded_content = False
|
||||||
extra_css = '@font-face {font-family: "serif1";src:url(res:///opt/sony/ebook/FONT/tt0011m_.ttf)} @font-face {font-family: "monospace1";src:url(res:///opt/sony/ebook/FONT/tt0419m_.ttf)} @font-face {font-family: "sans1";src:url(res:///opt/sony/ebook/FONT/tt0003m_.ttf)} body{text-align: left; font-family: serif1, serif} .article_date{font-family: monospace1, monospace} .article_description{font-family: sans1, sans-serif} .navbar{font-family: monospace1, monospace}'
|
language = _('Serbian')
|
||||||
|
extra_css = '@font-face {font-family: "serif1";src:url(res:///opt/sony/ebook/FONT/tt0011m_.ttf)} @font-face {font-family: "sans1";src:url(res:///opt/sony/ebook/FONT/tt0003m_.ttf)} body{font-family: serif1, serif} .article_description{font-family: sans1, sans-serif}'
|
||||||
|
|
||||||
html2lrf_options = [
|
html2lrf_options = [
|
||||||
'--comment', description
|
'--comment' , description
|
||||||
, '--category', category
|
, '--category' , category
|
||||||
, '--publisher', publisher
|
, '--publisher', publisher
|
||||||
|
, '--ignore-tables'
|
||||||
]
|
]
|
||||||
|
|
||||||
html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"'
|
html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"\nlinearize_tables=True'
|
||||||
|
|
||||||
preprocess_regexps = [(re.compile(u'\u0110'), lambda match: u'\u00D0')]
|
preprocess_regexps = [(re.compile(u'\u0110'), lambda match: u'\u00D0')]
|
||||||
|
|
||||||
@ -87,7 +88,12 @@ class Vreme(BasicNewsRecipe):
|
|||||||
del soup.body['text' ]
|
del soup.body['text' ]
|
||||||
del soup.body['bgcolor']
|
del soup.body['bgcolor']
|
||||||
del soup.body['onload' ]
|
del soup.body['onload' ]
|
||||||
mtag = '<meta http-equiv="Content-Language" content="sr-Latn"/>'
|
for item in soup.findAll('table'):
|
||||||
|
if item.has_key('width'):
|
||||||
|
del item['width']
|
||||||
|
if item.has_key('height'):
|
||||||
|
del item['height']
|
||||||
|
mtag = '<meta http-equiv="Content-Language" content="sr-Latn-RS"/>'
|
||||||
soup.head.insert(0,mtag)
|
soup.head.insert(0,mtag)
|
||||||
tbl = soup.body.table
|
tbl = soup.body.table
|
||||||
tbbb = soup.find('td')
|
tbbb = soup.find('td')
|
||||||
@ -104,5 +110,3 @@ class Vreme(BasicNewsRecipe):
|
|||||||
if cover_item:
|
if cover_item:
|
||||||
cover_url = self.INDEX + cover_item['src']
|
cover_url = self.INDEX + cover_item['src']
|
||||||
return cover_url
|
return cover_url
|
||||||
|
|
||||||
language = _('Serbian')
|
|
@ -8,7 +8,7 @@ Fetch a webpage and its links recursively. The webpages are saved to disk in
|
|||||||
UTF-8 encoding with any charset declarations removed.
|
UTF-8 encoding with any charset declarations removed.
|
||||||
'''
|
'''
|
||||||
import sys, socket, os, urlparse, logging, re, time, copy, urllib2, threading, traceback
|
import sys, socket, os, urlparse, logging, re, time, copy, urllib2, threading, traceback
|
||||||
from urllib import url2pathname
|
from urllib import url2pathname, quote
|
||||||
from threading import RLock
|
from threading import RLock
|
||||||
from httplib import responses
|
from httplib import responses
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
@ -179,6 +179,8 @@ class RecursiveFetcher(object, LoggingInterface):
|
|||||||
delta = time.time() - self.last_fetch_at
|
delta = time.time() - self.last_fetch_at
|
||||||
if delta < self.delay:
|
if delta < self.delay:
|
||||||
time.sleep(delta)
|
time.sleep(delta)
|
||||||
|
if re.search(r'\s+', url) is not None:
|
||||||
|
url = quote(url)
|
||||||
with self.browser_lock:
|
with self.browser_lock:
|
||||||
try:
|
try:
|
||||||
with closing(self.browser.open(url)) as f:
|
with closing(self.browser.open(url)) as f:
|
||||||
|
@ -58,7 +58,7 @@ class Checker(object):
|
|||||||
"specific sections. You must explicitly pass "
|
"specific sections. You must explicitly pass "
|
||||||
"application config via "
|
"application config via "
|
||||||
"cherrypy.tree.mount(..., config=app_config)")
|
"cherrypy.tree.mount(..., config=app_config)")
|
||||||
warnings.warn(msg)
|
warnings.warn(msg[:5])
|
||||||
return
|
return
|
||||||
|
|
||||||
def check_static_paths(self):
|
def check_static_paths(self):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user