Sync to pluginize

This commit is contained in:
John Schember 2009-04-01 06:33:35 -04:00
commit 7973c41073
27 changed files with 503 additions and 367 deletions

View File

@ -1,5 +1,5 @@
" Project wide builtins " Project wide builtins
let g:pyflakes_builtins += ["dynamic_property", '__'] let g:pyflakes_builtins += ["dynamic_property", "__"]
python << EOFPY python << EOFPY
import os import os

View File

@ -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.5.3' __version__ = '0.5.4'
__author__ = "Kovid Goyal <kovid@kovidgoyal.net>" __author__ = "Kovid Goyal <kovid@kovidgoyal.net>"
''' '''
Various run time constants. Various run time constants.

View File

@ -170,7 +170,8 @@ class InputFormatPlugin(Plugin):
if not os.path.exists(options.debug_input): if not os.path.exists(options.debug_input):
os.makedirs(options.debug_input) os.makedirs(options.debug_input)
shutil.rmtree(options.debug_input) shutil.rmtree(options.debug_input)
shutil.copytree('.', options.debug_input) shutil.copytree(output_dir, options.debug_input)
log.info('Input debug saved to:', options.debug_input)
return ret return ret
@ -195,7 +196,14 @@ class OutputFormatPlugin(Plugin):
#: Options shared by all Input format plugins. Do not override #: Options shared by all Input format plugins. Do not override
#: in sub-classes. Use :member:`options` instead. Every option must be an #: in sub-classes. Use :member:`options` instead. Every option must be an
#: instance of :class:`OptionRecommendation`. #: instance of :class:`OptionRecommendation`.
common_options = set([]) common_options = set([
OptionRecommendation(name='pretty_print',
recommended_value=False, level=OptionRecommendation.LOW,
help=_('If specified, the output plugin will try to create output '
'that is as human readable as possible. May not have any effect '
'for some output plugins.')
),
])
#: Options to customize the behavior of this plugin. Every option must be an #: Options to customize the behavior of this plugin. Every option must be an
#: instance of :class:`OptionRecommendation`. #: instance of :class:`OptionRecommendation`.

View File

@ -25,9 +25,11 @@ class Plugin(_Plugin):
screen_size = (800, 600) screen_size = (800, 600)
dpi = 100 dpi = 100
def initialize(self): def __init__(self, *args, **kwargs):
_Plugin.__init__(self, *args, **kwargs)
self.width, self.height = self.screen_size self.width, self.height = self.screen_size
fsizes = list(self.fsizes) fsizes = list(self.fsizes)
self.fkey = list(self.fsizes)
self.fsizes = [] self.fsizes = []
for (name, num), size in izip(FONT_SIZES, fsizes): for (name, num), size in izip(FONT_SIZES, fsizes):
self.fsizes.append((name, num, float(size))) self.fsizes.append((name, num, float(size)))

View File

@ -92,9 +92,9 @@ def add_input_output_options(parser, plumber):
parser.add_option_group(io) parser.add_option_group(io)
if output_options: if output_options:
title = plumber.output_fmt.upper() + ' ' + _('OPTIONS') title = _('OUTPUT OPTIONS')
oo = OptionGroup(parser, title, _('Options to control the processing' oo = OptionGroup(parser, title, _('Options to control the processing'
' of the output %s file')%plumber.input_fmt) ' of the output %s')%plumber.output_fmt)
add_options(oo.add_option, output_options) add_options(oo.add_option, output_options)
parser.add_option_group(oo) parser.add_option_group(oo)

View File

@ -9,6 +9,7 @@ from calibre.customize.conversion import OptionRecommendation
from calibre.customize.ui import input_profiles, output_profiles, \ from calibre.customize.ui import input_profiles, output_profiles, \
plugin_for_input_format, plugin_for_output_format plugin_for_input_format, plugin_for_output_format
from calibre.ebooks.conversion.preprocess import HTMLPreProcessor from calibre.ebooks.conversion.preprocess import HTMLPreProcessor
from calibre.ptempfile import PersistentTemporaryDirectory
class OptionValues(object): class OptionValues(object):
pass pass
@ -289,6 +290,8 @@ OptionRecommendation(name='language',
''' '''
# Setup baseline option values # Setup baseline option values
self.setup_options() self.setup_options()
if self.opts.verbose:
self.log.filter_level = self.log.DEBUG
# Run any preprocess plugins # Run any preprocess plugins
from calibre.customize.ui import run_plugins_on_preprocess from calibre.customize.ui import run_plugins_on_preprocess
@ -300,9 +303,11 @@ OptionRecommendation(name='language',
from calibre.ebooks.oeb.base import OEBBook from calibre.ebooks.oeb.base import OEBBook
accelerators = {} accelerators = {}
tdir = PersistentTemporaryDirectory('_plumber')
opfpath = self.input_plugin(open(self.input, 'rb'), self.opts, opfpath = self.input_plugin(open(self.input, 'rb'), self.opts,
self.input_fmt, self.log, self.input_fmt, self.log,
accelerators) accelerators, tdir)
html_preprocessor = HTMLPreProcessor() html_preprocessor = HTMLPreProcessor()
self.reader = OEBReader() self.reader = OEBReader()
self.oeb = OEBBook(self.log, html_preprocessor=html_preprocessor) self.oeb = OEBBook(self.log, html_preprocessor=html_preprocessor)
@ -316,15 +321,16 @@ OptionRecommendation(name='language',
from calibre.ebooks.oeb.transforms.flatcss import CSSFlattener from calibre.ebooks.oeb.transforms.flatcss import CSSFlattener
fbase = self.opts.base_font_size fbase = self.opts.base_font_size
if fbase == 0: if fbase == 0:
fbase = self.opts.dest.fbase fbase = float(self.opts.dest.fbase)
fkey = self.opts.font_size_mapping fkey = self.opts.font_size_mapping
if fkey is None: if fkey is None:
fkey = self.opts.dest.fsizes fkey = self.opts.dest.fkey
else:
fkey = map(float, fkey.split(','))
flattener = CSSFlattener(fbase=fbase, fkey=fkey, flattener = CSSFlattener(fbase=fbase, fkey=fkey,
lineh=self.opts.line_height, lineh=self.opts.line_height,
untable=self.opts.linearize_tables) untable=self.opts.linearize_tables)
self.log.info('Flattening CSS...')
flattener(self.oeb, self.opts) flattener(self.oeb, self.opts)
from calibre.ebooks.oeb.transforms.trimmanifest import ManifestTrimmer from calibre.ebooks.oeb.transforms.trimmanifest import ManifestTrimmer
@ -334,7 +340,7 @@ OptionRecommendation(name='language',
trimmer(self.oeb, self.opts) trimmer(self.oeb, self.opts)
self.log.info('Creating %s output...'%self.output_plugin.name) self.log.info('Creating %s output...'%self.output_plugin.name)
self.output_plugin(self.oeb, self.output, self.input_plugin, self.opts, self.output_plugin.convert(self.oeb, self.output, self.input_plugin, self.opts,
self.log) self.log)

View File

@ -510,8 +510,6 @@ class OPF(object):
except: except:
pass pass
def get_text(self, elem): def get_text(self, elem):
return u''.join(self.CONTENT(elem) or self.TEXT(elem)) return u''.join(self.CONTENT(elem) or self.TEXT(elem))

View File

@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
__license__ = 'GPL v3' __license__ = 'GPL v3'
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>' __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
import os, glob import os, glob, re
from urlparse import urlparse from urlparse import urlparse
from urllib import unquote from urllib import unquote
@ -151,12 +151,12 @@ class TOC(list):
if play_order is None: if play_order is None:
play_order = int(np.get('playorder', 1)) play_order = int(np.get('playorder', 1))
href = fragment = text = None href = fragment = text = None
nl = np.find('navlabel') nl = np.find(re.compile('navlabel'))
if nl is not None: if nl is not None:
text = u'' text = u''
for txt in nl.findAll('text'): for txt in nl.findAll(re.compile('text')):
text += ''.join([unicode(s) for s in txt.findAll(text=True)]) text += ''.join([unicode(s) for s in txt.findAll(text=True)])
content = np.find('content') content = np.find(re.compile('content'))
if content is None or not content.has_key('src') or not txt: if content is None or not content.has_key('src') or not txt:
return return
@ -166,15 +166,15 @@ class TOC(list):
nd.play_order = play_order nd.play_order = play_order
for c in np: for c in np:
if getattr(c, 'name', None) == 'navpoint': if 'navpoint' in getattr(c, 'name', ''):
process_navpoint(c, nd) process_navpoint(c, nd)
nm = soup.find('navmap') nm = soup.find(re.compile('navmap'))
if nm is None: if nm is None:
raise ValueError('NCX files must have a <navmap> element.') raise ValueError('NCX files must have a <navmap> element.')
for elem in nm: for elem in nm:
if getattr(elem, 'name', None) == 'navpoint': if 'navpoint' in getattr(elem, 'name', ''):
process_navpoint(elem, self) process_navpoint(elem, self)

View File

@ -5,7 +5,7 @@ __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
Read data from .mobi files Read data from .mobi files
''' '''
import struct, os, cStringIO, re, functools, datetime import struct, os, cStringIO, re, functools, datetime, textwrap
try: try:
from PIL import Image as PILImage from PIL import Image as PILImage
@ -162,7 +162,7 @@ class MobiReader(object):
self.log = log self.log = log
self.debug = debug self.debug = debug
self.embedded_mi = None self.embedded_mi = None
self.base_css_rules = ''' self.base_css_rules = textwrap.dedent('''
blockquote { margin: 0em 0em 0em 1.25em; text-align: justify } blockquote { margin: 0em 0em 0em 1.25em; text-align: justify }
p { margin: 0em; text-align: justify } p { margin: 0em; text-align: justify }
@ -174,7 +174,7 @@ class MobiReader(object):
.mbp_pagebreak { .mbp_pagebreak {
page-break-after: always; margin: 0; display: block page-break-after: always; margin: 0; display: block
} }
''' ''')
self.tag_css_rules = [] self.tag_css_rules = []
if hasattr(filename_or_stream, 'read'): if hasattr(filename_or_stream, 'read'):
@ -223,7 +223,7 @@ class MobiReader(object):
processed_records = self.extract_text() processed_records = self.extract_text()
if self.debug is not None: if self.debug is not None:
self.parse_cache['calibre_raw_mobi_markup'] = self.mobi_html parse_cache['calibre_raw_mobi_markup'] = self.mobi_html
self.add_anchors() self.add_anchors()
self.processed_html = self.processed_html.decode(self.book_header.codec, self.processed_html = self.processed_html.decode(self.book_header.codec,
'ignore') 'ignore')
@ -265,7 +265,6 @@ class MobiReader(object):
pass pass
parse_cache[htmlfile] = root parse_cache[htmlfile] = root
self.htmlfile = htmlfile self.htmlfile = htmlfile
self.log.debug('Creating OPF...')
ncx = cStringIO.StringIO() ncx = cStringIO.StringIO()
opf = self.create_opf(htmlfile, guide, root) opf = self.create_opf(htmlfile, guide, root)
self.created_opf_path = os.path.splitext(htmlfile)[0]+'.opf' self.created_opf_path = os.path.splitext(htmlfile)[0]+'.opf'
@ -283,8 +282,7 @@ class MobiReader(object):
if self.book_header.exth is not None or self.embedded_mi is not None: if self.book_header.exth is not None or self.embedded_mi is not None:
if self.verbose: self.log.debug('Creating OPF...')
print 'Creating OPF...'
ncx = cStringIO.StringIO() ncx = cStringIO.StringIO()
opf = self.create_opf(htmlfile, guide, root) opf = self.create_opf(htmlfile, guide, root)
opf.render(open(os.path.splitext(htmlfile)[0]+'.opf', 'wb'), ncx) opf.render(open(os.path.splitext(htmlfile)[0]+'.opf', 'wb'), ncx)

View File

@ -658,9 +658,9 @@ class Manifest(object):
def _parse_css(self, data): def _parse_css(self, data):
data = self.oeb.decode(data) data = self.oeb.decode(data)
data = self.CSSPreProcessor(data) data = self.oeb.css_preprocessor(data)
data = XHTML_CSS_NAMESPACE + data data = XHTML_CSS_NAMESPACE + data
parser = CSSParser(log=self.oeb.logger, loglevel=logging.WARNING, parser = CSSParser(loglevel=logging.WARNING,
fetcher=self._fetch_css) fetcher=self._fetch_css)
data = parser.parseString(data, href=self.href) data = parser.parseString(data, href=self.href)
data.namespaces['h'] = XHTML_NS data.namespaces['h'] = XHTML_NS

View File

@ -25,7 +25,7 @@ class OEBOutput(OutputFormatPlugin):
with CurrentDir(output_path): with CurrentDir(output_path):
results = oeb_book.to_opf2(page_map=True) results = oeb_book.to_opf2(page_map=True)
for key in (OPF_MIME, NCX_MIME, PAGE_MAP_MIME): for key in (OPF_MIME, NCX_MIME, PAGE_MAP_MIME):
href, root = results.pop(key, None) href, root = results.pop(key, [None, None])
if root is not None: if root is not None:
raw = etree.tostring(root, pretty_print=True, raw = etree.tostring(root, pretty_print=True,
encoding='utf-8') encoding='utf-8')
@ -33,6 +33,21 @@ class OEBOutput(OutputFormatPlugin):
f.write(raw) f.write(raw)
for item in oeb_book.manifest: for item in oeb_book.manifest:
print item.href path = os.path.abspath(item.href)
dir = os.path.dirname(path)
if not os.path.exists(dir):
os.makedirs(dir)
raw = item.data
if not isinstance(raw, basestring):
if hasattr(raw, 'cssText'):
raw = raw.cssText
else:
raw = etree.tostring(raw, encoding='utf-8',
pretty_print=opts.pretty_print)
raw = raw + '<?xml version="1.0" encoding="utf-8" ?>\n'
if isinstance(raw, unicode):
raw = raw.encode('utf-8')
with open(path, 'wb') as f:
f.write(raw)

View File

@ -168,7 +168,7 @@ class OEBReader(object):
data. data.
''' '''
bad = [] bad = []
check = OEB_DOCS+OEB_STYLES check = OEB_DOCS.union(OEB_STYLES)
for item in list(self.oeb.manifest.values()): for item in list(self.oeb.manifest.values()):
if item.media_type in check: if item.media_type in check:
try: try:

View File

@ -263,7 +263,7 @@ class EmailAccounts(QAbstractTableModel):
def remove(self, index): def remove(self, index):
if index.isValid(): if index.isValid():
row = self.index.row() row = index.row()
account = self.account_order[row] account = self.account_order[row]
self.accounts.pop(account) self.accounts.pop(account)
self.account_order = sorted(self.accounts.keys()) self.account_order = sorted(self.accounts.keys())
@ -425,6 +425,8 @@ class ConfigDialog(QDialog, Ui_Dialog):
self.email_view.resizeColumnsToContents() self.email_view.resizeColumnsToContents()
self.connect(self.test_email_button, SIGNAL('clicked(bool)'), self.connect(self.test_email_button, SIGNAL('clicked(bool)'),
self.test_email) self.test_email)
self.connect(self.email_remove, SIGNAL('clicked()'),
self.remove_email_account)
def add_email_account(self, checked): def add_email_account(self, checked):
index = self._email_accounts.add() index = self._email_accounts.add()
@ -432,6 +434,10 @@ class ConfigDialog(QDialog, Ui_Dialog):
self.email_view.resizeColumnsToContents() self.email_view.resizeColumnsToContents()
self.email_view.edit(index) self.email_view.edit(index)
def remove_email_account(self, *args):
idx = self.email_view.currentIndex()
self._email_accounts.remove(idx)
def create_gmail_relay(self, *args): def create_gmail_relay(self, *args):
self.relay_username.setText('@gmail.com') self.relay_username.setText('@gmail.com')
self.relay_password.setText('') self.relay_password.setText('')

View File

@ -727,7 +727,7 @@
<string> px</string> <string> px</string>
</property> </property>
<property name="maximum" > <property name="maximum" >
<number>200</number> <number>250</number>
</property> </property>
<property name="value" > <property name="value" >
<number>20</number> <number>20</number>
@ -750,7 +750,7 @@
<string> px</string> <string> px</string>
</property> </property>
<property name="maximum" > <property name="maximum" >
<number>200</number> <number>250</number>
</property> </property>
<property name="value" > <property name="value" >
<number>20</number> <number>20</number>
@ -773,7 +773,7 @@
<string> px</string> <string> px</string>
</property> </property>
<property name="maximum" > <property name="maximum" >
<number>200</number> <number>250</number>
</property> </property>
<property name="value" > <property name="value" >
<number>10</number> <number>10</number>
@ -796,7 +796,7 @@
<string> px</string> <string> px</string>
</property> </property>
<property name="maximum" > <property name="maximum" >
<number>200</number> <number>250</number>
</property> </property>
<property name="value" > <property name="value" >
<number>0</number> <number>0</number>

Binary file not shown.

After

Width:  |  Height:  |  Size: 638 B

View File

@ -368,7 +368,7 @@ class DocumentView(QWebView):
def load_path(self, path, pos=0.0): def load_path(self, path, pos=0.0):
self.initial_pos = pos self.initial_pos = pos
html = open(path, 'rb').read().decode(path.encoding) html = open(path, 'rb').read().decode(path.encoding, 'replace')
html = EntityDeclarationProcessor(html).processed_html html = EntityDeclarationProcessor(html).processed_html
self.setHtml(html, QUrl.fromLocalFile(path)) self.setHtml(html, QUrl.fromLocalFile(path))

View File

@ -18,7 +18,7 @@ function find_enclosing_block(y) {
if (min != 0 && min.height() < 200) break; if (min != 0 && min.height() < 200) break;
} }
if (y <= 0) return document.body; if (y <= 0) return document.body;
if (min == 0) { return find_enclosing_block(x, y-20); } if (min == 0) { return find_enclosing_block(y-20); }
return min; return min;
} }

View File

@ -262,7 +262,6 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
self.connect(self.toc, SIGNAL('clicked(QModelIndex)'), self.toc_clicked) self.connect(self.toc, SIGNAL('clicked(QModelIndex)'), self.toc_clicked)
self.connect(self.reference, SIGNAL('goto(PyQt_PyObject)'), self.goto) self.connect(self.reference, SIGNAL('goto(PyQt_PyObject)'), self.goto)
self.bookmarks_menu = QMenu() self.bookmarks_menu = QMenu()
self.action_bookmark.setMenu(self.bookmarks_menu) self.action_bookmark.setMenu(self.bookmarks_menu)
self.set_bookmarks([]) self.set_bookmarks([])

View File

@ -37,7 +37,7 @@ recipe_modules = ['recipe_' + r for r in (
'new_york_review_of_books_no_sub', 'politico', 'adventuregamers', 'new_york_review_of_books_no_sub', 'politico', 'adventuregamers',
'mondedurable', 'instapaper', 'dnevnik_cro', 'vecernji_list', 'mondedurable', 'instapaper', 'dnevnik_cro', 'vecernji_list',
'nacional_cro', '24sata', 'dnevni_avaz', 'glas_srpske', '24sata_rs', 'nacional_cro', '24sata', 'dnevni_avaz', 'glas_srpske', '24sata_rs',
'krstarica', 'krstarica_en', 'tanjug', 'krstarica', 'krstarica_en', 'tanjug', 'laprensa_ni',
)] )]
import re, imp, inspect, time, os import re, imp, inspect, time, os

View File

@ -0,0 +1,96 @@
#!/usr/bin/env python
__license__ = 'GPL v3'
__copyright__ = '2009, Darko Miletic <darko.miletic at gmail.com>'
'''
laprensa.com.ni
'''
import locale
import time
from calibre.web.feeds.news import BasicNewsRecipe
class LaPrensa_ni(BasicNewsRecipe):
title = 'La Prensa - Nicaragua'
__author__ = 'Darko Miletic'
description = 'LA PRENSA - EL Diario de los Nicaraguenses'
publisher = 'La Prensa'
category = 'Nicaragua, nicaragua, la prensa, La Prensa, prensa, Prensa, diario, Diario, periodico, noticias, internacional, economia, dinero, opinion, ultimas noticias, deportes, politica, managua, Managua, ultima hora, daily, newspaper, news, breaking news, urgente, tecnologia, tiempo, weather, buscador, magazine, Magazine, nosotras, Nosotras, journalism, clasificados, avisos, classified, ads, media, publicidad, arroba, arroba de oro'
oldest_article = 1
max_articles_per_feed = 100
no_stylesheets = True
use_embedded_content = False
encoding = 'cp1252'
remove_javascript = True
language = _('Spanish')
#Locale setting to get appropriate date/month values in Spanish
try:
#Windows seting for locale
locale.setlocale(locale.LC_TIME,'Spanish_Nicaragua')
except locale.Error:
#Linux setting for locale -- choose one appropriate for your distribution
try:
locale.setlocale(locale.LC_TIME,'es_NI')
except locale.Error:
try:
locale.setlocale(locale.LC_TIME,'es_ES')
except:
pass
current_index = time.strftime("http://www.laprensa.com.ni/archivo/%Y/%B/%d/noticias/")
html2lrf_options = [
'--comment', description
, '--category', category
, '--publisher', publisher
, '--ignore-tables'
]
html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"\nlinearize_tables=True'
feeds = [(u'Portada', current_index + 'portada/')]
def print_version(self, url):
return url.replace('.shtml','_print.shtml')
def preprocess_html(self, soup):
del soup.body['onload']
mtag = '<meta http-equiv="Content-Language" content="es-NI"/>'
soup.head.insert(0,mtag)
atag = soup.find('span',attrs={'class':'mas_noticias'})
if atag:
atag.extract()
btag = soup.find('a',attrs={'href':'/archivo'})
if btag:
btag.extract()
for item in soup.findAll(style=True):
del item['style']
return soup
def parse_index(self):
totalfeeds = []
lfeeds = self.get_feeds()
for feedobj in lfeeds:
feedtitle, feedurl = feedobj
self.report_progress(0, _('Fetching feed')+' %s...'%(feedtitle if feedtitle else feedurl))
articles = []
soup = self.index_to_soup(feedurl)
for item in soup.findAll('a', attrs={'class':['titular','titulonotamed']}):
description = ''
url = feedurl + item['href']
title = self.tag_to_string(item)
date = time.strftime(self.timefmt)
articles.append({
'title' :title
,'date' :date
,'url' :url
,'description':description
})
totalfeeds.append((feedtitle, articles))
return totalfeeds
def cleanup(self):
#Going back to the default locale
locale.setlocale(locale.LC_TIME,'')

View File

@ -26,7 +26,8 @@ def initview(request):
5. The feeds for the site (ids) 5. The feeds for the site (ids)
""" """
site_id, cachekey = fjlib.getcurrentsite(request.META['HTTP_HOST'], \ site_id, cachekey = fjlib.getcurrentsite(request.META.get('HTTP_HOST',
'planet.calibre-ebook.com'), \
request.META.get('REQUEST_URI', request.META.get('PATH_INFO', '/')), \ request.META.get('REQUEST_URI', request.META.get('PATH_INFO', '/')), \
request.META['QUERY_STRING']) request.META['QUERY_STRING'])
response = fjcache.cache_get(site_id, cachekey) response = fjcache.cache_get(site_id, cachekey)

View File

@ -1,4 +1,4 @@
#!/bin/sh #!/bin/sh
ssh divok "cd /usr/local/calibre && bzr pull" ssh divok "cd /usr/local/calibre && bzr up"
ssh divok /etc/init.d/apache2 graceful ssh divok /etc/init.d/apache2 graceful

View File

@ -52,7 +52,7 @@
<img <img
src="{{ MEDIA_URL }}/img/faces/{{ item.subscriber.shortname}}.png" alt="" /> src="{{ MEDIA_URL }}/img/faces/{{ item.subscriber.shortname}}.png" alt="" />
<div class="url"> <div class="url">
{{ item.feed.title|safe }} {{ item.feed.name|safe }}
</div> </div>
</a> </a>
</div> </div>

View File

@ -667,9 +667,16 @@ class stage3(OptionlessCommand):
def misc(cls): def misc(cls):
check_call('ssh divok rm -f %s/calibre-\*.tar.gz'%DOWNLOADS, shell=True) check_call('ssh divok rm -f %s/calibre-\*.tar.gz'%DOWNLOADS, shell=True)
check_call('scp dist/calibre-*.tar.gz divok:%s/'%DOWNLOADS, shell=True) check_call('scp dist/calibre-*.tar.gz divok:%s/'%DOWNLOADS, shell=True)
check_call('gpg --armor --detach-sign dist/calibre-*.tar.gz',
shell=True)
check_call('scp dist/calibre-*.tar.gz.asc divok:%s/signatures/'%DOWNLOADS,
shell=True)
check_call('''rm -rf dist/* build/*''', shell=True) check_call('''rm -rf dist/* build/*''', shell=True)
check_call('ssh divok bzr update /var/www/calibre.kovidgoyal.net/calibre/', check_call('ssh divok bzr update /var/www/calibre.kovidgoyal.net/calibre/',
shell=True) shell=True)
check_call('ssh divok bzr update /usr/local/calibre',
shell=True)
def run(self): def run(self):
OptionlessCommand.run(self) OptionlessCommand.run(self)