Added rar,zip support to html2lrf and squashed a few more html processing bugs. Version bump.

This commit is contained in:
Kovid Goyal 2007-04-21 18:44:04 +00:00
parent bc4e05a417
commit b1a02af907
10 changed files with 253 additions and 244 deletions

View File

@ -1,14 +0,0 @@
APIDOCS=/var/www/libprs500.kovidgoyal.net/htdocs/apidocs
targets:
@echo Targets are: installer doc
installer:
@scp dist/libprs500-*.exe castalia:/var/www/vhosts/kovidgoyal.net/subdomains/libprs500/httpdocs/downloads/
@ssh castalia chmod a+r /var/www/vhosts/kovidgoyal.net/subdomains/libprs500/httpdocs/downloads/\*
@echo Update link on the libprs500 wiki
doc:
epydoc --config epydoc.conf
cp -r docs/html ${APIDOCS}/
epydoc -v --config epydoc-pdf.conf
cp docs/pdf/api.pdf ${APIDOCS}/

View File

@ -15,10 +15,11 @@ Var MUI_TEMP
!define PRODUCT_NAME "libprs500"
!define XPUI_BRANDINGTEXT "${PRODUCT_NAME} created by Kovid Goyal"
!define PRODUCT_VERSION "0.3.12"
!define PRODUCT_VERSION "0.3.13"
!define WEBSITE "https://libprs500.kovidgoyal.net"
!define PY2EXE_DIR "C:\libprs500"
!define LIBUSB_DIR "C:\libusb-prs500"
!define LIBUNRAR_DIR "C:\Program Files\UnrarDLL"
!define QT_DIR "C:\Qt\4.2.3\bin"
;------------------------------------------------------------------------------------------------------
@ -98,6 +99,7 @@ Section "libprs500" Seclibprs500
SetOutPath "$SYSDIR"
File "${LIBUSB_DIR}\libusb0.dll"
File "${LIBUNRAR_DIR}\unrar.dll"
DetailPrint " "
DetailPrint "Installing USB driver (this may take a few seconds) ..."

View File

@ -21,6 +21,8 @@ import ez_setup
ez_setup.use_setuptools()
from setuptools import setup, find_packages
################################# py2exe #######################################
py2exe_options = {}
if sys.argv[1] == 'py2exe':
py2exe_dir = 'C:\libprs500'
@ -33,10 +35,13 @@ if sys.argv[1] == 'py2exe':
f.close()
try:
import py2exe
console = [{
'script' : 'src/libprs500/cli/main.py', 'dest_base':'prs500',
'script' : 'src/libprs500/lrf/html/convert_from.py', 'dest_base':'html2lrf'
}]
console = [
{'script' : 'src/libprs500/cli/main.py', 'dest_base':'prs500'},
{'script' : 'src/libprs500/lrf/html/convert_from.py', 'dest_base':'html2lrf'},
{'script' : 'src/libprs500/lrf/txt/convert_from.py', 'dest_base':'txt2lrf'},
{'script' : 'src/libprs500/lrf/meta.py', 'dest_base':'lrf-meta'},
{'script' : 'src/libprs500/metadata/rtf.py', 'dest_base':'rtf-meta'},
]
windows = [{'script' : 'src/libprs500/gui/main.py', 'dest_base':'prs500-gui',
'icon_resources':[(1,'icons/library.ico')]}]
excludes = ["Tkconstants", "Tkinter", "tcl", "_imagingtk",
@ -50,29 +55,9 @@ if sys.argv[1] == 'py2exe':
except ImportError:
print >>sys.stderr, 'Must be in Windows to run py2exe'
sys.exit(1)
################################################################################
# Try to install the Python imaging library as the package name (PIL) doesn't
# match the distribution file name, thus declaring itas a dependency is useless
from setuptools.command.easy_install import main as easy_install
try:
try:
import Image
except ImportError:
if sys.platform.lower()[:5] not in ['win32', 'darwin']:
print "Trying to install the Python Imaging Library"
easy_install(["-f", "http://www.pythonware.com/products/pil/", "Imaging"])
else:
raise Exception('Please install the Python Imaging library manually from '\
'http://www.pythonware.com/products/pil/')
except Exception, e:
print >> sys.stderr, e
print >> sys.stderr, \
"WARNING: Could not install the Python Imaging Library.", \
"Some functionality will be unavailable"
if sys.hexversion < 0x2050000:
print >> sys.stderr, "You must use python >= 2.5 Try invoking this script as python2.5 setup.py."
print >> sys.stderr, "If you are using easy_install, try easy_install-2.5"
@ -110,20 +95,17 @@ setup(
""",
long_description =
"""
libprs500 is library to interface with the
`SONY Portable Reader`_ over USB_.
It provides methods to list the contents of the file system on the device,
as well as copy files from and to the device.
It also provides a command line and a graphical user interface via
the commands prs500 and
prs500-gui. The graphical user interface is designed to
manage an ebook library and allows for easy
syncing between the library and the ebook reader.
In addition libprs500 has a utility to read/write the metadata
from LRF files (unencrypted books in the SONY BBeB format). A command line
interface to this is provided via the command lrf-meta.
libprs500 is a ebook management application. It maintains an ebook library
and allows for easy transfer of books from the library to an ebook reader.
At the moment, it supports the `SONY Portable Reader`_.
A windows installer is available from https://libprs500.kovidgoyal.net
It can also convert various popular ebook formats into LRF, the native
ebook format of the SONY Reader.
For screenshots: https://libprs500.kovidgoyal.net/wiki/Screenshots
For installation/usage instructions please see
https://libprs500.kovidgoyal.net/wiki/WikiStart#Installation
For SVN access: svn co https://svn.kovidgoyal.net/code/libprs500

View File

@ -33,10 +33,24 @@ You may have to adjust the GROUP and the location of the rules file to
suit your distribution.
"""
__version__ = "0.3.12"
__version__ = "0.3.13"
__docformat__ = "epytext"
__author__ = "Kovid Goyal <kovid@kovidgoyal.net>"
import sys
iswindows = 'win32' in sys.platform.lower()
isosx = 'darwin' in sys.platform.lower()
def extract(path, dir):
import os
ext = os.path.splitext(path)[1][1:].lower()
extractor = None
if ext == 'zip':
from libprs500.libunzip import extract
extractor = extract
elif ext == 'rar':
from libprs500.libunrar import extract
extractor = extract
if not extract:
raise Exception('Unknown archive type')
extractor(path, dir)

View File

@ -17,6 +17,7 @@ This module provides a thin ctypes based wrapper around libunrar.
See ftp://ftp.rarlabs.com/rar/unrarsrc-3.7.5.tar.gz
"""
import os
from ctypes import Structure, c_char_p, c_uint, c_void_p, POINTER, \
byref, c_wchar_p, CFUNCTYPE, c_int, c_long, c_char, c_wchar
from StringIO import StringIO
@ -164,14 +165,21 @@ def get_archive_info(flags):
print >>ios, 'First Volume:\t', 'yes' if (flags & 256) else 'no or older than 3.0'
return ios.getvalue()
def extract(path):
def extract(path, dir):
"""
Extract archive C{filename} into directory C{dir}
"""
open_archive_data = RAROpenArchiveDataEx(ArcName=path, OpenMode=RAR_OM_EXTRACT, CmtBuf=None)
arc_data = _libunrar.RAROpenArchiveEx(byref(open_archive_data))
cwd = os.getcwd()
if not os.path.isdir( dir ):
os.mkdir( dir )
os.chdir( dir )
try:
if open_archive_data.OpenResult != 0:
raise UnRARException(_interpret_open_error(open_archive_data.OpenResult, path))
print 'Archive:', path
print get_archive_info(open_archive_data.Flags)
#print get_archive_info(open_archive_data.Flags)
header_data = RARHeaderDataEx(CmtBuf=None)
#_libunrar.RARSetCallback(arc_data, callback_func, mode)
while True:
@ -184,7 +192,5 @@ def extract(path):
if RHCode == ERAR_BAD_DATA:
raise UnRARException('File header broken')
finally:
os.chdir(cwd)
_libunrar.RARCloseArchive(arc_data)
extract(r'z:\home\test.rar')
#extract('/home/kovid/ero/Fansadox Collections/C21 Ponygirl Inferno.rar')

52
src/libprs500/libunzip.py Normal file
View File

@ -0,0 +1,52 @@
## Copyright (C) 2006 Kovid Goyal kovid@kovidgoyal.net
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 2 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License along
## with this program; if not, write to the Free Software Foundation, Inc.,
## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
import os, zipfile
from cStringIO import StringIO
def extract(filename, dir):
"""
Extract archive C{filename} into directory C{dir}
"""
zf = zipfile.ZipFile( filename )
namelist = zf.namelist()
dirlist = filter( lambda x: x.endswith( '/' ), namelist )
filelist = filter( lambda x: not x.endswith( '/' ), namelist )
# make base
pushd = os.getcwd()
if not os.path.isdir( dir ):
os.mkdir( dir )
os.chdir( dir )
# create directory structure
dirlist.sort()
for dirs in dirlist:
dirs = dirs.split( '/' )
prefix = ''
for dir in dirs:
dirname = os.path.join( prefix, dir )
if dir and not os.path.isdir( dirname ):
os.mkdir( dirname )
prefix = dirname
# extract files
for fn in filelist:
out = open( fn, 'wb' )
buffer = StringIO( zf.read( fn ))
buflen = 2 ** 20
datum = buffer.read( buflen )
while datum:
out.write( datum )
datum = buffer.read( buflen )
out.close()
os.chdir( pushd )

View File

@ -20,6 +20,7 @@ At the time fo writing, this package only supports reading and writing LRF meat
from optparse import OptionParser
from libprs500.lrf.pylrs.pylrs import Book as _Book
from libprs500 import __version__ as VERSION
__docformat__ = "epytext"
__author__ = "Kovid Goyal <kovid@kovidgoyal.net>"
@ -28,7 +29,7 @@ class ConversionError(Exception):
pass
def option_parser(usage):
parser = OptionParser(usage=usage)
parser = OptionParser(usage=usage, version='libprs500 '+VERSION)
parser.add_option("-t", "--title", action="store", type="string", \
dest="title", help="Set the title")
parser.add_option("-a", "--author", action="store", type="string", \

View File

@ -21,16 +21,20 @@ Code to convert HTML ebooks into LRF ebooks.
I am indebted to esperanc for the CSS->Xylog Style conversion routines
and to Falstaff for pylrs.
"""
import os, re, sys
import os, re, sys, shutil
from htmlentitydefs import name2codepoint
from urllib import urlopen
from urlparse import urlparse
from tempfile import mkdtemp
from operator import itemgetter
from libprs500.lrf.html.BeautifulSoup import BeautifulSoup, Comment, Tag, NavigableString
from libprs500.lrf.html.BeautifulSoup import BeautifulSoup, Comment, Tag, \
NavigableString, Declaration
from libprs500.lrf.pylrs.pylrs import Paragraph, CR, Italic, ImageStream, TextBlock, \
ImageBlock, JumpButton, CharButton, Page
from libprs500.lrf.pylrs.pylrs import Span as _Span
from libprs500.lrf import ConversionError, option_parser, Book
from libprs500 import extract
def ImagePage():
return Page(evensidemargin=0, oddsidemargin=0, topmargin=0, \
@ -150,7 +154,7 @@ class Span(_Span):
elif key == 'font-weight':
ans = font_weight(val)
if ans:
t['fontweight'] = val
t['fontweight'] = ans
elif key.startswith("margin"):
if key == "margin":
u = []
@ -186,8 +190,6 @@ class Span(_Span):
t["align"] = "head"
else:
print >>sys.stderr, 'Unhandled/malformed CSS key:', key, d[key]
if 'small' in t.values():
print d, 'font-size' in d.keys()
return t
def __init__(self, ns, css, font_delta=0):
@ -252,7 +254,7 @@ class HTMLConverter(object):
self.current_page = None
self.current_para = None
self.current_style = {}
self.parse_file(self.soup.html)
self.parse_file()
HTMLConverter.processed_files[path] = self
print 'done'
@ -318,14 +320,15 @@ class HTMLConverter(object):
prop.update(self.parse_style_properties(tag["style"]))
return prop
def parse_file(self, html):
def parse_file(self):
self.current_page = Page()
self.current_block = TextBlock()
self.current_para = Paragraph()
if self.cover:
self.add_image_block(self.cover)
self.top = self.current_block
self.parse_tag(html, {})
self.top = self.current_block
self.process_children(self.soup, {})
if self.current_para:
self.current_block.append(self.current_para)
if self.current_block:
@ -409,12 +412,12 @@ class HTMLConverter(object):
"""
if self.current_para.contents:
self.current_block.append(self.current_para)
self.current_para = Paragraph()
if self.current_block.contents:
self.current_page.append(self.current_block)
self.current_block = TextBlock()
if self.current_page.contents:
self.book.append(self.current_page)
self.current_para = Paragraph()
self.current_block = TextBlock()
self.current_page = Page()
@ -423,40 +426,42 @@ class HTMLConverter(object):
self.end_page()
page = ImagePage()
if not self.images.has_key(path):
self.images[path] = ImageBlock(ImageStream(path))
page.append(self.images[path])
self.images[path] = ImageStream(path)
page.append(ImageBlock(self.images[path]))
self.book.append(page)
def parse_tag(self, tag, parent_css):
def sanctify_css(css):
""" Make css safe for use in a SPAM Xylog tag """
for key in css.keys():
test = key.lower()
if test.startswith('margin') or 'indent' in test or \
'padding' in test or 'border' in test or 'page-break' in test \
or test.startswith('mso') \
or test in ['color', 'display', 'text-decoration', \
'letter-spacing', 'text-autospace', 'text-transform']:
css.pop(key)
return css
def process_children(self, ptag, pcss):
""" Process the children of ptag """
for c in ptag.contents:
if isinstance(c, (Comment, Declaration)):
continue
elif isinstance(c, Tag):
self.parse_tag(c, pcss)
elif isinstance(c, NavigableString):
self.add_text(c, pcss)
def add_text(tag, css):
try:
self.current_para.append(Span(tag, sanctify_css(css), \
font_delta=self.font_delta))
except ConversionError, err:
if self.verbose:
print >>sys.stderr, err
def add_text(self, tag, css):
try:
self.current_para.append(Span(tag, self.sanctify_css(css), \
font_delta=self.font_delta))
except ConversionError, err:
if self.verbose:
print >>sys.stderr, err
def process_children(ptag, pcss):
""" Process the children of ptag """
for c in ptag.contents:
if isinstance(c, Comment):
continue
elif isinstance(c, Tag):
self.parse_tag(c, pcss)
elif isinstance(c, NavigableString):
add_text(c, pcss)
def sanctify_css(self, css):
""" Make css safe for use in a SPAM Xylog tag """
for key in css.keys():
test = key.lower()
if test.startswith('margin') or 'indent' in test or \
'padding' in test or 'border' in test or 'page-break' in test \
or test.startswith('mso') \
or test in ['color', 'display', 'text-decoration', \
'letter-spacing', 'text-autospace', 'text-transform']:
css.pop(key)
return css
def parse_tag(self, tag, parent_css):
def process_text_tag(tag, tag_css):
if 'page-break-before' in tag_css.keys():
@ -467,16 +472,14 @@ class HTMLConverter(object):
if 'page-break-after' in tag_css.keys():
end_page = True
tag_css.pop('page-break-after')
process_children(tag, tag_css)
self.process_children(tag, tag_css)
if end_page:
self.end_page()
try:
tagname = tag.name.lower()
except AttributeError:
add_text(tag, parent_css)
self.add_text(tag, parent_css)
return
tag_css = self.tag_css(tag, parent_css=parent_css)
try: # Skip element if its display attribute is set to none
@ -494,7 +497,7 @@ class HTMLConverter(object):
self.current_block = tb
self.current_para = Paragraph()
self.targets[tag['name']] = tb
process_children(tag, tag_css)
self.process_children(tag, tag_css)
elif tag.has_key('href'):
purl = urlparse(tag['href'])
path = purl[2]
@ -516,12 +519,15 @@ class HTMLConverter(object):
elif tag.has_key('type') and tag['type'] == "text/css" \
and tag.has_key('href'):
url = tag['href']
if url.startswith('http://'):
f = urlopen(url)
else:
f = open(url)
self.parse_css(f.read())
f.close()
try:
if url.startswith('http://'):
f = urlopen(url)
else:
f = open(url)
self.parse_css(f.read())
f.close()
except IOError:
pass
elif tagname in ['p', 'div', 'ul', 'ol', 'tr', 'li', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6']:
# TODO: Implement ol
indent = tag_css.pop('text-indent', '')
@ -536,34 +542,33 @@ class HTMLConverter(object):
elif tagname in ['b', 'strong', 'i', 'em', 'span']:
process_text_tag(tag, tag_css)
elif tagname == 'font':
pass
elif tagname == 'link':
pass
elif tagname == 'style':
pass
if tag.has_key('face'):
tag_css['font-family'] = tag['face']
process_text_tag(tag, tag_css)
elif tagname == 'br':
self.current_para.append(CR())
elif tagname == 'hr':
self.current_para.append(CR())
# TODO: Horizontal line?
else:
process_children(tag, tag_css)
self.process_children(tag, tag_css)
def writeto(self, path, lrs=False):
self.book.renderLrs(path) if lrs else self.book.renderLrf(path)
def process_file(path, options):
cwd = os.getcwd()
cwd = os.getcwd()
dirpath = None
try:
path = os.path.abspath(path)
dirpath, path = get_path(path)
cpath, tpath = options.cover, ''
if options.cover and os.access(options.cover, os.R_OK):
try:
from PIL import Image
from libprs500.prs500 import PRS500
from libprs500.ptempfile import PersistentTemporaryFile
im = Image.open(cpath)
im = Image.open(os.path.join(cwd, cpath))
cim = im.resize((600, 800), Image.BICUBIC)
cf = PersistentTemporaryFile(prefix="html2lrf_", suffix=".jpg")
cf.close()
@ -596,6 +601,8 @@ def process_file(path, options):
print 'Output written to', oname
finally:
os.chdir(cwd)
if dirpath:
shutil.rmtree(dirpath, True)
def main():
""" CLI for html -> lrf conversions """
@ -618,6 +625,67 @@ def main():
options.title = os.path.splitext(os.path.basename(src))[0]
process_file(src, options)
def console_query(dirpath, candidate, docs):
if len(docs) == 1:
return 0
try:
import readline
except ImportError:
pass
i = 0
for doc in docs:
prefix = '>' if i == candidate else ''
print prefix+str(i)+'.\t', doc[0]
i += 1
print
while True:
try:
choice = raw_input('Choose file to convert (0-'+str(i-1) + \
'). Current choice is ['+ str(candidate) + ']:')
if not choice:
return candidate
choice = int(choice)
if choice < 0 or choice >= i:
continue
candidate = choice
except EOFError, KeyboardInterrupt:
sys.exit()
except:
continue
break
return candidate
def get_path(path, query=console_query):
path = os.path.abspath(path)
ext = os.path.splitext(path)[1][1:].lower()
if ext in ['htm', 'html', 'xhtml']:
return None, path
dirpath = mkdtemp('','html2lrf')
extract(path, dirpath)
candidate, docs = None, []
for root, dirs, files in os.walk(dirpath):
for name in files:
ext = os.path.splitext(name)[1][1:].lower()
if ext not in ['html', 'xhtml', 'htm', 'xhtm']:
continue
docs.append((name, root, os.stat(os.path.join(root, name)).st_size))
if 'toc' in name.lower():
candidate = name
docs.sort(key=itemgetter(2))
if candidate:
for i in range(len(docs)):
if docs[i][0] == candidate:
candidate = i
break
else:
candidate = len(docs) - 1
if len(docs) == 0:
raise ConversionError('No suitable files found in archive')
if len(docs) > 0:
candidate = query(dirpath, candidate, docs)
return dirpath, os.path.join(docs[candidate][1], docs[candidate][0])
if __name__ == '__main__':
main()

View File

@ -1,123 +0,0 @@
## Copyright (C) 2006 Kovid Goyal kovid@kovidgoyal.net
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 2 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License along
## with this program; if not, write to the Free Software Foundation, Inc.,
## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
import os
import shutil
import sys
import hashlib
import re
import pkg_resources
import subprocess
from tempfile import mkdtemp
from optparse import OptionParser
from libprs500.lrf import ConversionError
from libprs500.lrf.meta import LRFException, LRFMetaFile
from libprs500.ptempfile import PersistentTemporaryFile
def generate_thumbnail(path):
""" Generate a JPEG thumbnail of size ~ 128x128 (aspect ratio preserved)"""
try:
from PIL import Image
except ImportError:
raise LRFException("Unable to initialize Python Imaging Library." \
"Thumbnail generation is disabled")
im = Image.open(path)
im.thumbnail((128, 128), Image.ANTIALIAS)
thumb = PersistentTemporaryFile(prefix="makelrf_", suffix=".jpeg")
thumb.close()
im = im.convert()
im.save(thumb.name)
return thumb
def makelrf(author=None, title=None, \
thumbnail=None, src=None, odir=".",\
rasterize=True, cover=None):
src = os.path.normpath(os.path.abspath(src))
bbebook = pkg_resources.resource_filename(__name__, _bbebook)
if not os.access(src, os.R_OK):
raise LRFException("Unable to read from file: " + src)
if thumbnail:
thumb = os.path.abspath(thumbnail)
if not os.access(thumb, os.R_OK):
raise LRFException("Unable to read from " + thumb)
else:
thumb = pkg_resources.resource_filename(__name__, 'cover.jpg')
if not author:
author = "Unknown"
if not title:
title = os.path.basename(src)
label = os.path.basename(src)
id = 'FB' + hashlib.md5(os.path.basename(label)).hexdigest()[:14]
name, ext = os.path.splitext(label)
cwd = os.path.dirname(src)
dirpath = None
try:
if ext == ".rar":
dirpath = mkdtemp('','makelrf')
cwd = dirpath
cmd = " ".join(["unrar", "e", '"'+src+'"'])
proc = subprocess.Popen(cmd, cwd=cwd, shell=True, stderr=subprocess.PIPE)
if proc.wait():
raise LRFException("unrar failed with error:\n\n" + \
proc.stderr.read())
path, msize = None, 0
for root, dirs, files in os.walk(dirpath):
for name in files:
if os.path.splitext(name)[1] == ".html":
size = os.stat(os.path.join(root, name)).st_size
if size > msize:
msize, path = size, os.path.join(root, name)
if not path:
raise LRFException("Could not find .html file in rar archive")
src = path
name = re.sub("\s", "_", name)
name = os.path.abspath(os.path.join(odir, name)) + ".lrf"
cfg = { 'File' : src, 'Output' : name, 'Label' : label, 'BookID' : id, \
'Author' : author, 'Title' : title, 'Publisher' : 'Unknown' \
}
if cover:
cover = os.path.normpath(os.path.abspath(cover))
try:
thumbf = generate_thumbnail(cover)
thumb = thumbf.name
except Exception, e:
print >> sys.stderr, "WARNING: Unable to generate thumbnail:\n", \
str(e)
thumb = cover
cfg['Cover'] = cover
cfg['Icon'] = thumb
config = PersistentTemporaryFile(prefix='makelrf_', suffix='.xml')
config.write(create_xml(cfg))
config.close()
jar = '-jar "' + bbebook + '"'
cmd = " ".join(["java", jar, "-r" if rasterize else "", '"'+config.name+'"'])
proc = subprocess.Popen(cmd, \
cwd=cwd, shell=True, stderr=subprocess.PIPE)
if proc.wait():
raise LRFException("BBeBook failed with error:\n\n" + \
proc.stderr.read())
# Needed as BBeBook-0.2 doesn't handle non GIF thumbnails correctly.
lrf = open(name, "r+b")
LRFMetaFile(lrf).fix_thumbnail_type()
lrf.close()
return name
finally:
if dirpath:
shutil.rmtree(dirpath, True)

21
upload Normal file
View File

@ -0,0 +1,21 @@
#!/bin/bash
# Script to upload libprs500 to pypi, the installer to libprs500.kovidgoyal.net and update the api documentation
PREFIX=/var/www/vhosts/kovidgoyal.net/subdomains/libprs500
DOWNLOADS=$PREFIX/httpdocs/downloads
DOCS=$PREFIX/httpdocs/apidocs
exe=`cd dist && ls -1 libprs500-*.exe | tail -n1 && cd ..`
ssh castalia rm -f $DOWNLOADS/libprs500\*.exe
scp dist/$exe castalia:$DOWNLOADS/
ssh castalia chmod a+r $DOWNLOADS/\*
ssh castalia /root/bin/update-installer-link $exe
epydoc --config epydoc.conf
scp -r docs/html castalia:$DOCS/
epydoc -v --config epydoc-pdf.conf
scp docs/pdf/api.pdf castalia:$DOCS/
python setup.py register sdist bdist_egg upload
rm -rf dist/* build/*