mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
More commands ported tot he new setup framework
This commit is contained in:
parent
66a6887fc1
commit
1a532ea242
218
jsmin.py
218
jsmin.py
@ -1,218 +0,0 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
# This code is original from jsmin by Douglas Crockford, it was translated to
|
||||
# Python by Baruch Even. The original code had the following copyright and
|
||||
# license.
|
||||
#
|
||||
# /* jsmin.c
|
||||
# 2007-05-22
|
||||
#
|
||||
# Copyright (c) 2002 Douglas Crockford (www.crockford.com)
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
# this software and associated documentation files (the "Software"), to deal in
|
||||
# the Software without restriction, including without limitation the rights to
|
||||
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
# of the Software, and to permit persons to whom the Software is furnished to do
|
||||
# so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
#
|
||||
# The Software shall be used for Good, not Evil.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
# */
|
||||
|
||||
from StringIO import StringIO
|
||||
|
||||
def jsmin(js):
|
||||
ins = StringIO(js)
|
||||
outs = StringIO()
|
||||
JavascriptMinify().minify(ins, outs)
|
||||
str = outs.getvalue()
|
||||
if len(str) > 0 and str[0] == '\n':
|
||||
str = str[1:]
|
||||
return str
|
||||
|
||||
def isAlphanum(c):
|
||||
"""return true if the character is a letter, digit, underscore,
|
||||
dollar sign, or non-ASCII character.
|
||||
"""
|
||||
return ((c >= 'a' and c <= 'z') or (c >= '0' and c <= '9') or
|
||||
(c >= 'A' and c <= 'Z') or c == '_' or c == '$' or c == '\\' or (c is not None and ord(c) > 126));
|
||||
|
||||
class UnterminatedComment(Exception):
|
||||
pass
|
||||
|
||||
class UnterminatedStringLiteral(Exception):
|
||||
pass
|
||||
|
||||
class UnterminatedRegularExpression(Exception):
|
||||
pass
|
||||
|
||||
class JavascriptMinify(object):
|
||||
|
||||
def _outA(self):
|
||||
self.outstream.write(self.theA)
|
||||
def _outB(self):
|
||||
self.outstream.write(self.theB)
|
||||
|
||||
def _get(self):
|
||||
"""return the next character from stdin. Watch out for lookahead. If
|
||||
the character is a control character, translate it to a space or
|
||||
linefeed.
|
||||
"""
|
||||
c = self.theLookahead
|
||||
self.theLookahead = None
|
||||
if c == None:
|
||||
c = self.instream.read(1)
|
||||
if c >= ' ' or c == '\n':
|
||||
return c
|
||||
if c == '': # EOF
|
||||
return '\000'
|
||||
if c == '\r':
|
||||
return '\n'
|
||||
return ' '
|
||||
|
||||
def _peek(self):
|
||||
self.theLookahead = self._get()
|
||||
return self.theLookahead
|
||||
|
||||
def _next(self):
|
||||
"""get the next character, excluding comments. peek() is used to see
|
||||
if an unescaped '/' is followed by a '/' or '*'.
|
||||
"""
|
||||
c = self._get()
|
||||
if c == '/' and self.theA != '\\':
|
||||
p = self._peek()
|
||||
if p == '/':
|
||||
c = self._get()
|
||||
while c > '\n':
|
||||
c = self._get()
|
||||
return c
|
||||
if p == '*':
|
||||
c = self._get()
|
||||
while 1:
|
||||
c = self._get()
|
||||
if c == '*':
|
||||
if self._peek() == '/':
|
||||
self._get()
|
||||
return ' '
|
||||
if c == '\000':
|
||||
raise UnterminatedComment()
|
||||
|
||||
return c
|
||||
|
||||
def _action(self, action):
|
||||
"""do something! What you do is determined by the argument:
|
||||
1 Output A. Copy B to A. Get the next B.
|
||||
2 Copy B to A. Get the next B. (Delete A).
|
||||
3 Get the next B. (Delete B).
|
||||
action treats a string as a single character. Wow!
|
||||
action recognizes a regular expression if it is preceded by ( or , or =.
|
||||
"""
|
||||
if action <= 1:
|
||||
self._outA()
|
||||
|
||||
if action <= 2:
|
||||
self.theA = self.theB
|
||||
if self.theA == "'" or self.theA == '"':
|
||||
while 1:
|
||||
self._outA()
|
||||
self.theA = self._get()
|
||||
if self.theA == self.theB:
|
||||
break
|
||||
if self.theA <= '\n':
|
||||
raise UnterminatedStringLiteral()
|
||||
if self.theA == '\\':
|
||||
self._outA()
|
||||
self.theA = self._get()
|
||||
|
||||
|
||||
if action <= 3:
|
||||
self.theB = self._next()
|
||||
if self.theB == '/' and (self.theA == '(' or self.theA == ',' or
|
||||
self.theA == '=' or self.theA == ':' or
|
||||
self.theA == '[' or self.theA == '?' or
|
||||
self.theA == '!' or self.theA == '&' or
|
||||
self.theA == '|' or self.theA == ';' or
|
||||
self.theA == '{' or self.theA == '}' or
|
||||
self.theA == '\n'):
|
||||
self._outA()
|
||||
self._outB()
|
||||
while 1:
|
||||
self.theA = self._get()
|
||||
if self.theA == '/':
|
||||
break
|
||||
elif self.theA == '\\':
|
||||
self._outA()
|
||||
self.theA = self._get()
|
||||
elif self.theA <= '\n':
|
||||
raise UnterminatedRegularExpression()
|
||||
self._outA()
|
||||
self.theB = self._next()
|
||||
|
||||
|
||||
def _jsmin(self):
|
||||
"""Copy the input to the output, deleting the characters which are
|
||||
insignificant to JavaScript. Comments will be removed. Tabs will be
|
||||
replaced with spaces. Carriage returns will be replaced with linefeeds.
|
||||
Most spaces and linefeeds will be removed.
|
||||
"""
|
||||
self.theA = '\n'
|
||||
self._action(3)
|
||||
|
||||
while self.theA != '\000':
|
||||
if self.theA == ' ':
|
||||
if isAlphanum(self.theB):
|
||||
self._action(1)
|
||||
else:
|
||||
self._action(2)
|
||||
elif self.theA == '\n':
|
||||
if self.theB in ['{', '[', '(', '+', '-']:
|
||||
self._action(1)
|
||||
elif self.theB == ' ':
|
||||
self._action(3)
|
||||
else:
|
||||
if isAlphanum(self.theB):
|
||||
self._action(1)
|
||||
else:
|
||||
self._action(2)
|
||||
else:
|
||||
if self.theB == ' ':
|
||||
if isAlphanum(self.theA):
|
||||
self._action(1)
|
||||
else:
|
||||
self._action(3)
|
||||
elif self.theB == '\n':
|
||||
if self.theA in ['}', ']', ')', '+', '-', '"', '\'']:
|
||||
self._action(1)
|
||||
else:
|
||||
if isAlphanum(self.theA):
|
||||
self._action(1)
|
||||
else:
|
||||
self._action(3)
|
||||
else:
|
||||
self._action(1)
|
||||
|
||||
def minify(self, instream, outstream):
|
||||
self.instream = instream
|
||||
self.outstream = outstream
|
||||
self.theA = '\n'
|
||||
self.theB = None
|
||||
self.theLookahead = None
|
||||
|
||||
self._jsmin()
|
||||
self.instream.close()
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
jsm = JavascriptMinify()
|
||||
jsm.minify(sys.stdin, sys.stdout)
|
@ -134,13 +134,19 @@ class Command(object):
|
||||
def pre_sub_commands(self, opts):
|
||||
pass
|
||||
|
||||
def running(self, cmd):
|
||||
from setup.commands import command_names
|
||||
self.info('\n*')
|
||||
self.info('* Running', command_names[cmd])
|
||||
self.info('*\n')
|
||||
|
||||
def run_all(self, opts):
|
||||
self.pre_sub_commands(opts)
|
||||
for cmd in self.sub_commands:
|
||||
self.info('Running', cmd.__class__.__name__)
|
||||
self.running(cmd)
|
||||
cmd.run(opts)
|
||||
|
||||
self.info('Running', self.__class__.__name__)
|
||||
self.running(self)
|
||||
self.run(opts)
|
||||
|
||||
def add_all_options(self, parser):
|
||||
|
@ -10,9 +10,11 @@ __all__ = [
|
||||
'pot', 'translations', 'get_translations', 'iso639',
|
||||
'build',
|
||||
'gui',
|
||||
'develop',
|
||||
'develop', 'install',
|
||||
'resources',
|
||||
'check',
|
||||
'sdist',
|
||||
'manual',
|
||||
]
|
||||
|
||||
|
||||
@ -25,8 +27,10 @@ iso639 = ISO639()
|
||||
from setup.extensions import Build
|
||||
build = Build()
|
||||
|
||||
from setup.install import Develop
|
||||
from setup.install import Develop, Install, Sdist
|
||||
develop = Develop()
|
||||
install = Install()
|
||||
sdist = Sdist()
|
||||
|
||||
from setup.gui import GUI
|
||||
gui = GUI()
|
||||
@ -37,6 +41,9 @@ check = Check()
|
||||
from setup.resources import Resources
|
||||
resources = Resources()
|
||||
|
||||
from setup.publish import Manual
|
||||
manual = Manual()
|
||||
|
||||
commands = {}
|
||||
for x in __all__:
|
||||
commands[x] = locals()[x]
|
||||
|
@ -38,8 +38,8 @@ class GUI(Command):
|
||||
try:
|
||||
os.chdir(self.RESOURCES)
|
||||
sources, files = [], []
|
||||
for root, _, files in os.walk('images'):
|
||||
for name in files:
|
||||
for root, _, files2 in os.walk('images'):
|
||||
for name in files2:
|
||||
sources.append(os.path.join(root, name))
|
||||
if self.newer(self.QRC, sources):
|
||||
self.info('Creating images.qrc')
|
||||
|
@ -6,9 +6,10 @@ __license__ = 'GPL v3'
|
||||
__copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
import sys, os, textwrap, subprocess
|
||||
import sys, os, textwrap, subprocess, shutil, tempfile, atexit
|
||||
|
||||
from setup import Command, islinux, basenames, modules, functions
|
||||
from setup import Command, islinux, basenames, modules, functions, \
|
||||
__appname__, __version__
|
||||
|
||||
TEMPLATE = '''\
|
||||
#!/usr/bin/env python
|
||||
@ -39,7 +40,7 @@ class Develop(Command):
|
||||
''')
|
||||
MODE = 0755
|
||||
|
||||
sub_commands = ['build', 'translations']
|
||||
sub_commands = ['build', 'resources', 'gui']
|
||||
|
||||
def add_options(self, parser):
|
||||
parser.add_option('--prefix',
|
||||
@ -61,9 +62,13 @@ class Develop(Command):
|
||||
self.regain_privileges()
|
||||
self.find_locations(opts)
|
||||
self.write_templates(opts)
|
||||
self.install_files(opts)
|
||||
self.run_postinstall()
|
||||
self.success()
|
||||
|
||||
def install_files(self, opts):
|
||||
pass
|
||||
|
||||
def run_postinstall(self):
|
||||
subprocess.check_call(['calibre_postinstall'])
|
||||
|
||||
@ -79,6 +84,11 @@ class Develop(Command):
|
||||
for typ in ('console', 'gui'):
|
||||
for name, mod, func in zip(basenames[typ], modules[typ],
|
||||
functions[typ]):
|
||||
self.write_template(opts, name, mod, func)
|
||||
if islinux:
|
||||
self.write_template(opts, 'calibre_postinstall', 'calibre.linux', 'main')
|
||||
|
||||
def write_template(self, opts, name, mod, func):
|
||||
script = TEMPLATE.format(
|
||||
module=mod, func=func,
|
||||
path=self.path, resources=self.resources,
|
||||
@ -91,3 +101,82 @@ class Develop(Command):
|
||||
open(path, 'wb').write(script)
|
||||
os.chmod(path, self.MODE)
|
||||
|
||||
|
||||
class Install(Develop):
|
||||
|
||||
description = textwrap.dedent('''\
|
||||
Install calibre to your system. By default, calibre
|
||||
is installed to <prefix>/bin, <prefix>/lib/calibre,
|
||||
<prefix>/share/calibre. These can all be controlled via options.
|
||||
|
||||
The default <prefix> is the prefix of your python installation.
|
||||
''')
|
||||
|
||||
sub_commands = ['build']
|
||||
|
||||
def add_options(self, parser):
|
||||
parser.add_option('--prefix', help='Installation prefix')
|
||||
parser.add_option('--libdir', help='Where to put calibre library files')
|
||||
parser.add_option('--bindir', help='Where to install calibre binaries')
|
||||
parser.add_option('--sharedir', help='Where to install calibre data files')
|
||||
|
||||
def find_locations(self, opts):
|
||||
if opts.prefix is None:
|
||||
opts.prefix = sys.prefix
|
||||
if opts.libdir is None:
|
||||
opts.libdir = self.j(opts.prefix, 'lib', 'calibre')
|
||||
if opts.bindir is None:
|
||||
opts.bindir = self.j(opts.prefix, 'bin')
|
||||
if opts.sharedir is None:
|
||||
opts.sharedir = self.j(opts.prefix, 'share', 'calibre')
|
||||
self.path = opts.libdir
|
||||
self.resources = opts.sharedir
|
||||
self.extensions = self.j(self.path, 'calibre', 'plugins')
|
||||
|
||||
def install_files(self, opts):
|
||||
dest = self.path
|
||||
if os.path.exists(dest):
|
||||
shutil.rmtree(dest)
|
||||
shutil.copytree(self.SRC, dest)
|
||||
dest = self.resources
|
||||
if os.path.exists(dest):
|
||||
shutil.rmtree(dest)
|
||||
shutil.copytree(self.RESOURCES, dest)
|
||||
|
||||
def success(self):
|
||||
self.info('\n\ncalibre successfully installed. You can start'
|
||||
' it by running the command calibre')
|
||||
|
||||
class Sdist(Command):
|
||||
|
||||
description = 'Create a source distribution'
|
||||
DEST = os.path.join('dist', '%s-%s.tar.gz'%(__appname__, __version__))
|
||||
|
||||
|
||||
def run(self, opts):
|
||||
if not self.e(self.d(self.DEST)):
|
||||
os.makedirs(self.d(self.DEST))
|
||||
tdir = tempfile.mkdtemp()
|
||||
atexit.register(shutil.rmtree, tdir)
|
||||
self.info('\tRunning bzr export...')
|
||||
subprocess.check_call(['bzr', 'export', '--format', 'dir', tdir])
|
||||
for x in open('.bzrignore').readlines():
|
||||
if not x.startswith('resources/'): continue
|
||||
p = x.strip().replace('/', os.sep)
|
||||
d = self.j(tdir, os.path.dirname(p))
|
||||
if not self.e(d):
|
||||
os.makedirs(d)
|
||||
if os.path.isdir(p):
|
||||
shutil.copytree(p, self.j(tdir, p))
|
||||
else:
|
||||
shutil.copy2(p, d)
|
||||
self.info('\tCreating tarfile...')
|
||||
subprocess.check_call(' '.join(['tar', '-czf', self.a(self.DEST), '*']),
|
||||
cwd=tdir, shell=True)
|
||||
|
||||
def clean(self):
|
||||
if os.path.exists(self.DEST):
|
||||
os.remove(self.DEST)
|
||||
|
||||
|
||||
|
||||
|
43
setup/publish.py
Normal file
43
setup/publish.py
Normal file
@ -0,0 +1,43 @@
|
||||
#!/usr/bin/env python
|
||||
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
|
||||
from __future__ import with_statement
|
||||
|
||||
__license__ = 'GPL v3'
|
||||
__copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
import os, shutil, subprocess
|
||||
|
||||
from setup import Command, __appname__, __version__
|
||||
|
||||
class Manual(Command):
|
||||
|
||||
description='''Build the User Manual '''
|
||||
|
||||
def run(self, opts):
|
||||
cwd = os.path.abspath(os.getcwd())
|
||||
os.chdir(os.path.join(self.SRC, 'calibre', 'manual'))
|
||||
try:
|
||||
for d in ('.build', 'cli'):
|
||||
if os.path.exists(d):
|
||||
shutil.rmtree(d)
|
||||
os.makedirs(d)
|
||||
if not os.path.exists('.build'+os.sep+'html'):
|
||||
os.makedirs('.build'+os.sep+'html')
|
||||
os.environ['__appname__']= __appname__
|
||||
os.environ['__version__']= __version__
|
||||
subprocess.check_call(['sphinx-build', '-b', 'custom', '-t', 'online',
|
||||
'-d', '.build/doctrees', '.', '.build/html'])
|
||||
subprocess.check_call(['sphinx-build', '-b', 'epub', '-d',
|
||||
'.build/doctrees', '.', '.build/epub'])
|
||||
shutil.copyfile(self.j('.build', 'epub', 'calibre.epub'), self.j('.build',
|
||||
'html', 'calibre.epub'))
|
||||
finally:
|
||||
os.chdir(cwd)
|
||||
|
||||
def clean(self):
|
||||
path = os.path.join(self.SRC, 'calibre', 'manual', '.build')
|
||||
if os.path.exists(path):
|
||||
shutil.rmtree(path)
|
||||
|
||||
|
@ -16,7 +16,8 @@ import sys, os
|
||||
# If your extensions are in another directory, add it here.
|
||||
sys.path.append(os.path.abspath('../../../'))
|
||||
sys.path.append(os.path.abspath('.'))
|
||||
from calibre import __appname__, __version__
|
||||
__appname__ = os.environ.get('__appname__', 'calibre')
|
||||
__version__ = os.environ.get('__version__', '0.0.0')
|
||||
import custom
|
||||
custom
|
||||
# General configuration
|
||||
|
@ -5,6 +5,10 @@ __license__ = 'GPL v3'
|
||||
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
|
||||
import sys, os, inspect, re, textwrap
|
||||
|
||||
sys.path.insert(0, os.path.abspath('../../'))
|
||||
sys.extensions_location = '../plugins'
|
||||
sys.resources_location = '../../../resources'
|
||||
|
||||
from sphinx.builder import StandaloneHTMLBuilder
|
||||
from qthelp import QtHelpBuilder
|
||||
from epub import EPUBHelpBuilder
|
||||
|
@ -9,12 +9,15 @@ __docformat__ = 'restructuredtext en'
|
||||
|
||||
import __builtin__, sys, os
|
||||
|
||||
def get_path(path):
|
||||
def get_path(path, data=False):
|
||||
path = path.replace(os.sep, '/')
|
||||
return os.path.join(sys.resources_location, *path.split('/'))
|
||||
path = os.path.join(sys.resources_location, *path.split('/'))
|
||||
if data:
|
||||
return open(path, 'rb').read()
|
||||
return path
|
||||
|
||||
def get_image_path(path):
|
||||
return get_path('images/'+path)
|
||||
def get_image_path(path, data=False):
|
||||
return get_path('images/'+path, data=data)
|
||||
|
||||
__builtin__.__dict__['P'] = get_path
|
||||
__builtin__.__dict__['I'] = get_image_path
|
||||
|
Loading…
x
Reference in New Issue
Block a user