From 14891bdd52d08a298a0557c312176f91b7a1e0a5 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 8 Mar 2009 10:25:00 -0700 Subject: [PATCH 1/5] New recipe for Wikinews by Darko Miletic --- src/calibre/gui2/images/news/wikinews_en.png | Bin 0 -> 951 bytes src/calibre/web/feeds/recipes/__init__.py | 2 +- .../web/feeds/recipes/recipe_wikinews_en.py | 70 ++++++++++++++++++ 3 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 src/calibre/gui2/images/news/wikinews_en.png create mode 100644 src/calibre/web/feeds/recipes/recipe_wikinews_en.py diff --git a/src/calibre/gui2/images/news/wikinews_en.png b/src/calibre/gui2/images/news/wikinews_en.png new file mode 100644 index 0000000000000000000000000000000000000000..489061b923e207b18d5dfee4e08ab715d198d7fc GIT binary patch literal 951 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4%caKYZ?lYt_f1s;*b zK-vS0-A-oPfdtD69Mgd`SU*F|v9*U87?>V-x;TbdoX(wmzDp)l;%NQ%YkNbl{$G_o z!))?PHNOHY-;yJ)i(VX4eBk9+u=w4XQ|u>%c|Nn`u{sLOcj#$S;AmRS={9k}OG)-Q z8P;lwGyjE`u70<+I+jJWH@))5Im?0{eLH^K)BjVFJNe>035J=fG4<8DXM7fHF%|IG zqU6nbxGwsG{GV=%IcJ>XvXquy&{|Y9%|Rj1@Z8lMw=VYR9bdf<-O5KErU-h?7FsUoIv7GtjO=1c4pPAgR36>*pl+P=fP_0Y0Z%*wVw-@u^IZC=yk&Rq)-gC%3ndHyMCAREXxat1$S`RZ~{-J_$XT zV4C{B;$ZLOS-+1Jm%p4LI`3@XqgPA$o*Q`@=LJkP&CHRrz4YB(O{K6&+*Eyeu-%@( zg3m`bP1Lk$JUey9>gl^H!Z%zzJ3;YKh-!Xajn0#dd>`YjGgc+dls>nvWaqZcr#`2f z9{XL{2#lG1k!K{h}%VamM zS+G!wLw=#MFNY;C75sTWW15?==TUxj)%ZJhPp@`M-hQonAh_CHdux5SyfK5s+uoml z?$*r^V+^)zX>ifr#d|PY-bZftf8k=A=-tbkBGZ5gU$w+Fq9nN}HL)aBHw8#A7#SE? z>KYj98d!uFnp+teSQ%Mp8yHv_7?>V?#0%4qo1c=IR*9*>%*x2j%Fqm=A;rhh6{vy1 M)78&qol`;+0E-%zP5=M^ literal 0 HcmV?d00001 diff --git a/src/calibre/web/feeds/recipes/__init__.py b/src/calibre/web/feeds/recipes/__init__.py index a513f34728..8253021c57 100644 --- a/src/calibre/web/feeds/recipes/__init__.py +++ b/src/calibre/web/feeds/recipes/__init__.py @@ -33,7 +33,7 @@ recipe_modules = ['recipe_' + r for r in ( 'la_republica', 'physics_today', 'chicago_tribune', 'e_novine', 'al_jazeera', 'winsupersite', 'borba', 'courrierinternational', 'lamujerdemivida', 'soldiers', 'theonion', 'news_times', - 'el_universal', 'mediapart', + 'el_universal', 'mediapart', 'wikinews_en', )] import re, imp, inspect, time, os diff --git a/src/calibre/web/feeds/recipes/recipe_wikinews_en.py b/src/calibre/web/feeds/recipes/recipe_wikinews_en.py new file mode 100644 index 0000000000..932981ca4c --- /dev/null +++ b/src/calibre/web/feeds/recipes/recipe_wikinews_en.py @@ -0,0 +1,70 @@ +#!/usr/bin/env python + +__license__ = 'GPL v3' +__copyright__ = '2009, Darko Miletic ' +''' +en.wikinews.org +''' + +from calibre.web.feeds.news import BasicNewsRecipe + +class WikiNews(BasicNewsRecipe): + title = 'Wikinews' + __author__ = 'Darko Miletic' + description = 'News from wikipedia' + category = 'news, world' + oldest_article = 7 + max_articles_per_feed = 100 + publisher = 'Wiki' + no_stylesheets = True + use_embedded_content = False + encoding = 'utf-8' + remove_javascript = True + language = _('English') + + html2lrf_options = [ + '--comment', description + , '--category', category + , '--publisher', publisher + ] + + html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"' + + keep_only_tags = [ + dict(name='h1', attrs={'id':'firstHeading'}) + ,dict(name='div', attrs={'id':'bodyContent'}) + ] + + remove_tags = [ + dict(name='link') + ,dict(name='div',attrs={'id':['printfooter','catlinks','footer']}) + ,dict(name='div',attrs={'class':['thumb left','thumb right']}) + ] + + remove_tags_after = dict(name='h2') + + feeds = [(u'News', u'http://feeds.feedburner.com/WikinewsLatestNews')] + + def get_article_url(self, article): + artl = article.get('link', None) + rest, sep, article_id = artl.rpartition('/') + return 'http://en.wikinews.org/wiki/' + article_id + + def print_version(self, url): + rest, sep, article_id = url.rpartition('/') + return 'http://en.wikinews.org/w/index.php?title=' + article_id + '&printable=yes' + + def preprocess_html(self, soup): + mtag = '' + soup.head.insert(0,mtag) + btag = soup.find('div',attrs={'id':'bodyContent'}) + for item in btag.findAll('div'): + item.extract() + for item in btag.findAll('h2'): + item.extract() + for item in soup.findAll(style=True): + del item['style'] + for item in soup.findAll(font=True): + del item['font'] + return soup + From 1ee09b193012f76ed68fd0109048467e87935c6e Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 8 Mar 2009 10:43:28 -0700 Subject: [PATCH 2/5] Fix #2017 (Another PRC file cover detection issue) --- src/calibre/ebooks/mobi/reader.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/calibre/ebooks/mobi/reader.py b/src/calibre/ebooks/mobi/reader.py index 2c80cc1c8c..3ca1fd6c18 100644 --- a/src/calibre/ebooks/mobi/reader.py +++ b/src/calibre/ebooks/mobi/reader.py @@ -370,6 +370,11 @@ class MobiReader(object): opf.cover = 'images/%05d.jpg'%(self.book_header.exth.cover_offset+1) elif mi.cover is not None: opf.cover = mi.cover + else: + opf.cover = 'images/%05d.jpg'%1 + if not os.path.exists(os.path.join(os.path.dirname(htmlfile), + *opf.cover.split('/'))): + opf.cover = None manifest = [(htmlfile, 'text/x-oeb1-document')] bp = os.path.dirname(htmlfile) for i in getattr(self, 'image_names', []): From 0f1414679eb0ba81b5428038e7024b404653cf04 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 8 Mar 2009 10:53:11 -0700 Subject: [PATCH 3/5] Fix #2018 ([ERROR] CSSValue: Missing token for production Choice) --- src/calibre/ebooks/html.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/calibre/ebooks/html.py b/src/calibre/ebooks/html.py index 2883e39f8a..0b4f69b38b 100644 --- a/src/calibre/ebooks/html.py +++ b/src/calibre/ebooks/html.py @@ -859,7 +859,7 @@ class Processor(Parser): except ValueError: setting = '' face = font.attrib.pop('face', None) - if face is not None: + if face: faces = [] for face in face.split(','): face = face.strip() From 05eea1baf8c9764b0421153519990ce1f9de3a9a Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 8 Mar 2009 12:30:50 -0700 Subject: [PATCH 4/5] Remove dependency on help2man. Also significantly speds up man page generation --- src/calibre/__init__.py | 6 +- src/calibre/linux.py | 52 +++++---------- src/calibre/trac/plugins/download.py | 1 - src/calibre/trac/plugins/templates/linux.html | 2 +- src/calibre/utils/help2man.py | 63 +++++++++++++++++++ 5 files changed, 86 insertions(+), 38 deletions(-) create mode 100644 src/calibre/utils/help2man.py diff --git a/src/calibre/__init__.py b/src/calibre/__init__.py index 706391f1a7..3bf1f03b42 100644 --- a/src/calibre/__init__.py +++ b/src/calibre/__init__.py @@ -2,11 +2,15 @@ __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' __docformat__ = 'restructuredtext en' -import sys, os, re, logging, time, subprocess, atexit, mimetypes + +import sys, os, re, logging, time, subprocess, atexit, mimetypes, warnings from htmlentitydefs import name2codepoint from math import floor from logging import Formatter +warnings.simplefilter('ignore', DeprecationWarning) + + from PyQt4.QtCore import QUrl from PyQt4.QtGui import QDesktopServices from calibre.startup import plugins, winutil, winutilerror diff --git a/src/calibre/linux.py b/src/calibre/linux.py index 7abd9c027c..039d52985a 100644 --- a/src/calibre/linux.py +++ b/src/calibre/linux.py @@ -410,45 +410,27 @@ def option_parser(): help='Save a manifest of all installed files to the specified location') return parser -def install_man_pages(fatal_errors): - from bz2 import compress - import subprocess +def install_man_pages(fatal_errors, use_destdir=False): + from calibre.utils.help2man import create_man_page + prefix = os.environ.get('DESTDIR', '/') if use_destdir else '/' + manpath = os.path.join(prefix, 'usr/share/man/man1') + if not os.path.exists(manpath): + os.makedirs(manpath) print 'Installing MAN pages...' - manpath = '/usr/share/man/man1' - f = NamedTemporaryFile() - f.write('[see also]\nhttp://%s.kovidgoyal.net\n'%__appname__) - f.flush() manifest = [] - os.environ['PATH'] += ':'+os.path.expanduser('~/bin') for src in entry_points['console_scripts']: - prog = src[:src.index('=')].strip() - if prog in ('prs500', 'pdf-meta', 'epub-meta', 'lit-meta', - 'markdown-calibre', 'calibre-debug', 'fb2-meta', - 'calibre-fontconfig', 'calibre-parallel', 'odt-meta', - 'rb-meta', 'imp-meta', 'mobi-meta'): + prog, right = src.split('=') + prog = prog.strip() + module = __import__(right.split(':')[0].strip(), fromlist=['a']) + parser = getattr(module, 'option_parser', None) + if parser is None: continue - - help2man = ('help2man', prog, '--name', 'part of %s'%__appname__, - '--section', '1', '--no-info', '--include', - f.name, '--manual', __appname__) + parser = parser() + raw = create_man_page(prog, parser) manfile = os.path.join(manpath, prog+'.1'+__appname__+'.bz2') print '\tInstalling MAN page for', prog - try: - p = subprocess.Popen(help2man, stdout=subprocess.PIPE) - except OSError, err: - import errno - if err.errno != errno.ENOENT: - raise - print 'Failed to install MAN pages as help2man is missing from your system' - break - o = p.stdout.read() - raw = re.compile(r'^\.IP\s*^([A-Z :]+)$', re.MULTILINE).sub(r'.SS\n\1', o) - if not raw.strip(): - print 'Unable to create MAN page for', prog - continue - f2 = open_file(manfile) - manifest.append(f2.name) - f2.write(compress(raw)) + open(manfile, 'wb').write(raw) + manifest.append(manfile) return manifest def post_install(): @@ -460,9 +442,9 @@ def post_install(): manifest = [] setup_desktop_integration(opts.fatal_errors) if opts.no_root or os.geteuid() == 0: + manifest += install_man_pages(opts.fatal_errors, use_destdir) manifest += setup_udev_rules(opts.group_file, not opts.dont_reload, opts.fatal_errors) - manifest += setup_completion(opts.fatal_errors) - manifest += install_man_pages(opts.fatal_errors) + manifest += setup_completion(opts.fatal_errors) else: print "Skipping udev, completion, and man-page install for non-root user." diff --git a/src/calibre/trac/plugins/download.py b/src/calibre/trac/plugins/download.py index 9c852c554e..020c0a0e3d 100644 --- a/src/calibre/trac/plugins/download.py +++ b/src/calibre/trac/plugins/download.py @@ -18,7 +18,6 @@ DEPENDENCIES = [ ('lxml', '2.1.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'), ] diff --git a/src/calibre/trac/plugins/templates/linux.html b/src/calibre/trac/plugins/templates/linux.html index 066f3c9b6d..96881aa108 100644 --- a/src/calibre/trac/plugins/templates/linux.html +++ b/src/calibre/trac/plugins/templates/linux.html @@ -88,7 +88,7 @@ sudo python -c "import urllib2; exec urllib2.urlopen('http://calibre.kovidgoyal. be ignored.
  • - You must have help2man and xdg-utils installed + You must have xdg-utils installed on your system before running the installer.
  • diff --git a/src/calibre/utils/help2man.py b/src/calibre/utils/help2man.py new file mode 100644 index 0000000000..603c0d6484 --- /dev/null +++ b/src/calibre/utils/help2man.py @@ -0,0 +1,63 @@ +from __future__ import with_statement +__license__ = 'GPL 3' +__copyright__ = '2009, Kovid Goyal ' +__docformat__ = 'restructuredtext en' + +import time, bz2 + +from calibre.constants import __version__, __appname__, __author__ + + +def create_man_page(prog, parser): + usage = parser.usage.splitlines() + for i, line in enumerate(list(usage)): + if not line.strip(): + usage[i] = '.PP' + else: + usage[i] = line.replace('%prog', prog) + lines = [ + '.TH ' + prog.upper() + ' "1" ' + time.strftime('"%B %Y"') + + ' "%s (%s %s)" "%s"'%(prog, __appname__, __version__, __appname__), + '.SH NAME', + prog + r' \- part of '+__appname__, + '.SH SYNOPSIS', + '.B "%s"'%prog + r'\fR '+' '.join(usage[0].split()[1:]), + '.SH DESCRIPTION', + ] + lines += usage[1:] + + lines += [ + '.SH OPTIONS' + ] + def format_option(opt): + ans = ['.TP'] + opts = [] + opts += opt._short_opts + opts.append(opt.get_opt_string()) + opts = [r'\fB'+x.replace('-', r'\-')+r'\fR' for x in opts] + ans.append(', '.join(opts)) + help = opt.help if opt.help else '' + ans.append(help.replace('%prog', prog).replace('%default', str(opt.default))) + return ans + + for opt in parser.option_list: + lines.extend(format_option(opt)) + for group in parser.option_groups: + lines.append('.SS '+group.title) + for opt in group.option_list: + lines.extend(format_option(opt)) + + lines += ['.SH SEE ALSO', + 'The User Manual is available at ' + 'http://calibre.kovidgoyal.net/user_manual', + '.PP', '.B Created by '+__author__] + + return bz2.compress('\n'.join(lines)) + +def main(): + from calibre.ebooks.epub.from_any import option_parser + open('/tmp/any2epub.1calibre.bz2', 'w').write(create_man_page( + 'any2epub', option_parser())) + +if __name__ == '__main__': + main() \ No newline at end of file From 05329f8ca130b2713da70fd1eb07004e19368305 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 8 Mar 2009 13:44:11 -0700 Subject: [PATCH 5/5] IGN:... --- src/calibre/utils/help2man.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/calibre/utils/help2man.py b/src/calibre/utils/help2man.py index 603c0d6484..9777ea24cd 100644 --- a/src/calibre/utils/help2man.py +++ b/src/calibre/utils/help2man.py @@ -44,6 +44,8 @@ def create_man_page(prog, parser): lines.extend(format_option(opt)) for group in parser.option_groups: lines.append('.SS '+group.title) + if group.description: + lines.extend(['.PP', group.description]) for opt in group.option_list: lines.extend(format_option(opt)) @@ -54,10 +56,4 @@ def create_man_page(prog, parser): return bz2.compress('\n'.join(lines)) -def main(): - from calibre.ebooks.epub.from_any import option_parser - open('/tmp/any2epub.1calibre.bz2', 'w').write(create_man_page( - 'any2epub', option_parser())) - -if __name__ == '__main__': - main() \ No newline at end of file +