1
0
mirror of https://github.com/ciromattia/kcc synced 2025-12-23 06:31:54 +00:00

Merge pull request #119 from ciromattia/4.x

4.3.1
This commit is contained in:
Paweł Jastrzębski
2014-11-24 20:13:17 +01:00
13 changed files with 128 additions and 58 deletions

View File

@@ -377,6 +377,13 @@ The app relies and includes the following scripts:
* Added missing features to CLI version * Added missing features to CLI version
* Other minor bug fixes * Other minor bug fixes
####4.3.1:
* Fixed Kindle Voyage profile
* Fixed some bugs in OS X release
* CLI version now support multiple input files at once
* Disabled MCB support
* Other minor tweaks
## KNOWN ISSUES ## KNOWN ISSUES
Please check [wiki page](https://github.com/ciromattia/kcc/wiki/Known-issues). Please check [wiki page](https://github.com/ciromattia/kcc/wiki/Known-issues).

View File

@@ -18,7 +18,7 @@
# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE. # PERFORMANCE OF THIS SOFTWARE.
__version__ = '4.3' __version__ = '4.3.1'
__license__ = 'ISC' __license__ = 'ISC'
__copyright__ = '2012-2014, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@iosphe.re>' __copyright__ = '2012-2014, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@iosphe.re>'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'

View File

@@ -18,7 +18,7 @@
# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE. # PERFORMANCE OF THIS SOFTWARE.
__version__ = '4.3' __version__ = '4.3.1'
__license__ = 'ISC' __license__ = 'ISC'
__copyright__ = '2012-2014, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@iosphe.re>' __copyright__ = '2012-2014, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@iosphe.re>'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'

View File

@@ -1,5 +1,5 @@
#define MyAppName "Kindle Comic Converter" #define MyAppName "Kindle Comic Converter"
#define MyAppVersion "4.3" #define MyAppVersion "4.3.1"
#define MyAppPublisher "Ciro Mattia Gonano, Paweł Jastrzębski" #define MyAppPublisher "Ciro Mattia Gonano, Paweł Jastrzębski"
#define MyAppURL "http://kcc.iosphe.re/" #define MyAppURL "http://kcc.iosphe.re/"
#define MyAppExeName "KCC.exe" #define MyAppExeName "KCC.exe"

9
kcc.py
View File

@@ -18,7 +18,7 @@
# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE. # PERFORMANCE OF THIS SOFTWARE.
__version__ = '4.3' __version__ = '4.3.1'
__license__ = 'ISC' __license__ = 'ISC'
__copyright__ = '2012-2014, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@iosphe.re>' __copyright__ = '2012-2014, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@iosphe.re>'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'
@@ -74,11 +74,8 @@ from multiprocessing import freeze_support
from kcc import KCC_gui from kcc import KCC_gui
# OS specific PATH variable workarounds # OS specific PATH variable workarounds
if sys.platform.startswith('darwin'): if sys.platform.startswith('darwin') and 'RESOURCEPATH' not in os.environ:
if 'RESOURCEPATH' in os.environ: os.environ['PATH'] = os.path.dirname(os.path.abspath(__file__)) + '/other/:' + os.environ['PATH']
os.environ['PATH'] = os.environ['RESOURCEPATH'] + ':' + os.environ['PATH']
else:
os.environ['PATH'] = os.path.dirname(os.path.abspath(__file__)) + '/other/:' + os.environ['PATH']
elif sys.platform.startswith('win'): elif sys.platform.startswith('win'):
if getattr(sys, 'frozen', False): if getattr(sys, 'frozen', False):
os.chdir(os.path.dirname(os.path.abspath(sys.executable))) os.chdir(os.path.dirname(os.path.abspath(sys.executable)))

View File

@@ -17,7 +17,7 @@
# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE. # PERFORMANCE OF THIS SOFTWARE.
__version__ = '4.3' __version__ = '4.3.1'
__license__ = 'ISC' __license__ = 'ISC'
__copyright__ = '2012-2014, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@iosphe.re>' __copyright__ = '2012-2014, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@iosphe.re>'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'
@@ -111,15 +111,15 @@ class WebServerHandler(BaseHTTPRequestHandler):
self.send_header('Content-type', 'text/html') self.send_header('Content-type', 'text/html')
self.end_headers() self.end_headers()
self.wfile.write(bytes('<!DOCTYPE html>\n' self.wfile.write(bytes('<!DOCTYPE html>\n'
'<html lang="en">\n' '<html lang="en">\n'
'<head><meta charset="utf-8">\n' '<head><meta charset="utf-8">\n'
'<link href="' + GUI.webContent.favicon + '" rel="icon" type="image/x-icon" />\n' '<link href="' + GUI.webContent.favicon + '" rel="icon" type="image/x-icon" />\n'
'<title>Kindle Comic Converter</title>\n' '<title>Kindle Comic Converter</title>\n'
'</head>\n' '</head>\n'
'<body>\n' '<body>\n'
'<div style="text-align: center; font-size:25px">\n' '<div style="text-align: center; font-size:25px">\n'
'<p style="font-size:50px">- <img style="vertical-align: middle" ' '<p style="font-size:50px">- <img style="vertical-align: middle" '
'alt="KCC Logo" src="' + GUI.webContent.logo + '" /> -</p>\n', 'UTF-8')) 'alt="KCC Logo" src="' + GUI.webContent.logo + '" /> -</p>\n', 'UTF-8'))
if len(GUI.completedWork) > 0 and not GUI.conversionAlive: if len(GUI.completedWork) > 0 and not GUI.conversionAlive:
for key in sorted(GUI.completedWork.keys()): for key in sorted(GUI.completedWork.keys()):
self.wfile.write(bytes('<p><a href="' + key + '">' + key.split('.')[0] + '</a></p>\n', 'UTF-8')) self.wfile.write(bytes('<p><a href="' + key + '">' + key.split('.')[0] + '</a></p>\n', 'UTF-8'))
@@ -127,8 +127,8 @@ class WebServerHandler(BaseHTTPRequestHandler):
self.wfile.write(bytes('<p style="font-weight: bold">No downloads are available.<br/>' self.wfile.write(bytes('<p style="font-weight: bold">No downloads are available.<br/>'
'Convert some files and refresh this page.</p>\n', 'UTF-8')) 'Convert some files and refresh this page.</p>\n', 'UTF-8'))
self.wfile.write(bytes('</div>\n' self.wfile.write(bytes('</div>\n'
'</body>\n' '</body>\n'
'</html>\n', 'UTF-8')) '</html>\n', 'UTF-8'))
elif sendReply: elif sendReply:
outputFile = GUI.completedWork[unquote(self.path[1:])] outputFile = GUI.completedWork[unquote(self.path[1:])]
fp = open(outputFile, 'rb') fp = open(outputFile, 'rb')
@@ -1016,7 +1016,9 @@ class KCCGUI(KCC_ui.Ui_KCC):
self.listFontSize = 11 self.listFontSize = 11
self.statusBarFontSize = 10 self.statusBarFontSize = 10
self.statusBarStyle = 'QLabel{padding-top:2px;padding-bottom:3px;}' self.statusBarStyle = 'QLabel{padding-top:2px;padding-bottom:3px;}'
self.ProgressBar.setStyleSheet('QProgressBar{padding-top:5px;text-align:center;}') self.ProgressBar.setStyleSheet('QProgressBar{font-size:13px;text-align:center;'
'border:2px solid grey;border-radius:5px;}'
'QProgressBar::chunk{background-color:steelblue;width:20px;}')
elif sys.platform.startswith('linux'): elif sys.platform.startswith('linux'):
self.listFontSize = 8 self.listFontSize = 8
self.statusBarFontSize = 8 self.statusBarFontSize = 8

View File

@@ -1,4 +1,4 @@
__version__ = '4.3' __version__ = '4.3.1'
__license__ = 'ISC' __license__ = 'ISC'
__copyright__ = '2012-2014, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@iosphe.re>' __copyright__ = '2012-2014, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@iosphe.re>'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'

View File

@@ -18,16 +18,18 @@
# PERFORMANCE OF THIS SOFTWARE. # PERFORMANCE OF THIS SOFTWARE.
# #
__version__ = '4.3' __version__ = '4.3.1'
__license__ = 'ISC' __license__ = 'ISC'
__copyright__ = '2012-2014, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@iosphe.re>' __copyright__ = '2012-2014, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@iosphe.re>'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'
import os import os
import sys import sys
from copy import copy
from glob import glob
from json import loads from json import loads
from urllib.request import Request, urlopen from urllib.request import Request, urlopen
from re import split, sub, compile from re import split, sub
from stat import S_IWRITE, S_IREAD, S_IEXEC from stat import S_IWRITE, S_IREAD, S_IEXEC
from zipfile import ZipFile, ZIP_STORED, ZIP_DEFLATED from zipfile import ZipFile, ZIP_STORED, ZIP_DEFLATED
from tempfile import mkdtemp from tempfile import mkdtemp
@@ -55,12 +57,21 @@ from . import dualmetafix
def main(argv=None): def main(argv=None):
global options global options
parser = makeParser() parser = makeParser()
options, args = parser.parse_args(argv) optionstemplate, args = parser.parse_args(argv)
checkOptions() if len(args) == 0:
if len(args) != 1:
parser.print_help() parser.print_help()
return return
outputPath = makeBook(args[0]) sources = set([source for arg in args for source in glob(arg)])
outputPath = []
if len(sources) == 0:
print('No matching files found.')
return
for source in sources:
options = copy(optionstemplate)
checkOptions()
if len(sources) > 1:
print('\nWorking on ' + source)
outputPath = makeBook(source)
return outputPath return outputPath
@@ -409,7 +420,7 @@ def buildEPUB(path, chapterNames, tomeNumber):
chapter = False chapter = False
for afile in filenames: for afile in filenames:
filename = getImageFileName(afile) filename = getImageFileName(afile)
if not '-kcc-hq' in filename[0]: if '-kcc-hq' not in filename[0]:
filelist.append(buildHTML(dirpath, afile, os.path.join(dirpath, afile))) filelist.append(buildHTML(dirpath, afile, os.path.join(dirpath, afile)))
if not chapter: if not chapter:
chapterlist.append((dirpath.replace('Images', 'Text'), filelist[-1][1])) chapterlist.append((dirpath.replace('Images', 'Text'), filelist[-1][1]))
@@ -667,11 +678,12 @@ def getComicInfo(path, originalPath):
options.authors.sort() options.authors.sort()
else: else:
options.authors = ['KCC'] options.authors = ['KCC']
if len(xml.getElementsByTagName('ScanInformation')) != 0: # Disabled due to closure of MCD
coverId = xml.getElementsByTagName('ScanInformation')[0].firstChild.nodeValue # if len(xml.getElementsByTagName('ScanInformation')) != 0:
coverId = compile('(MCD\\()(\\d+)(\\))').search(coverId) # coverId = xml.getElementsByTagName('ScanInformation')[0].firstChild.nodeValue
if coverId: # coverId = compile('(MCD\\()(\\d+)(\\))').search(coverId)
options.remoteCovers = getCoversFromMCB(coverId.group(2)) # if coverId:
# options.remoteCovers = getCoversFromMCB(coverId.group(2))
os.remove(xmlPath) os.remove(xmlPath)
@@ -1144,7 +1156,10 @@ def makeBook(source, qtGUI=None):
GUI.progressBarTick.emit('tick') GUI.progressBarTick.emit('tick')
options.baseTitle = options.title options.baseTitle = options.title
for tome in tomes: for tome in tomes:
if len(tomes) > 1: if len(tomes) > 9:
tomeNumber += 1
options.title = options.baseTitle + ' [' + str(tomeNumber).zfill(2) + '/' + str(len(tomes)).zfill(2) + ']'
elif len(tomes) > 1:
tomeNumber += 1 tomeNumber += 1
options.title = options.baseTitle + ' [' + str(tomeNumber) + '/' + str(len(tomes)) + ']' options.title = options.baseTitle + ' [' + str(tomeNumber) + '/' + str(len(tomes)) + ']'
if options.format == 'CBZ': if options.format == 'CBZ':
@@ -1254,4 +1269,4 @@ def makeMOBI(work, qtGUI=None):
makeMOBIWorkerPool.apply_async(func=makeMOBIWorker, args=(i, ), callback=makeMOBIWorkerTick) makeMOBIWorkerPool.apply_async(func=makeMOBIWorker, args=(i, ), callback=makeMOBIWorkerTick)
makeMOBIWorkerPool.close() makeMOBIWorkerPool.close()
makeMOBIWorkerPool.join() makeMOBIWorkerPool.join()
return makeMOBIWorkerOutput return makeMOBIWorkerOutput

View File

@@ -18,7 +18,7 @@
# PERFORMANCE OF THIS SOFTWARE. # PERFORMANCE OF THIS SOFTWARE.
# #
__version__ = '4.3' __version__ = '4.3.1'
__license__ = 'ISC' __license__ = 'ISC'
__copyright__ = '2012-2014, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@iosphe.re>' __copyright__ = '2012-2014, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@iosphe.re>'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'

View File

@@ -16,7 +16,7 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
__version__ = '4.3' __version__ = '4.3.1'
__license__ = 'ISC' __license__ = 'ISC'
__copyright__ = '2012-2014, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@iosphe.re>' __copyright__ = '2012-2014, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@iosphe.re>'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'
@@ -87,7 +87,7 @@ class ProfileData:
'K345': ("Kindle", (600, 800), Palette16, 1.8, (900, 1200)), 'K345': ("Kindle", (600, 800), Palette16, 1.8, (900, 1200)),
'KDX': ("Kindle DX/DXG", (824, 1000), Palette16, 1.8, (1236, 1500)), 'KDX': ("Kindle DX/DXG", (824, 1000), Palette16, 1.8, (1236, 1500)),
'KPW': ("Kindle Paperwhite", (758, 1024), Palette16, 1.8, (1137, 1536)), 'KPW': ("Kindle Paperwhite", (758, 1024), Palette16, 1.8, (1137, 1536)),
'KV': ("Kindle Voyage", (1080, 1440), Palette16, 1.8, (1620, 2160)), 'KV': ("Kindle Voyage", (1072, 1448), Palette16, 1.8, (1608, 2172)),
'KFHD': ("K. Fire HD", (800, 1280), PalleteNull, 1.0, (1200, 1920)), 'KFHD': ("K. Fire HD", (800, 1280), PalleteNull, 1.0, (1200, 1920)),
'KFHDX': ("K. Fire HDX", (1200, 1920), PalleteNull, 1.0, (1800, 2880)), 'KFHDX': ("K. Fire HDX", (1200, 1920), PalleteNull, 1.0, (1800, 2880)),
'KFHDX8': ("K. Fire HDX 8.9", (1600, 2560), PalleteNull, 1.0, (2400, 3840)), 'KFHDX8': ("K. Fire HDX 8.9", (1600, 2560), PalleteNull, 1.0, (2400, 3840)),

View File

@@ -178,6 +178,23 @@ EXTRACT_ARGS = ('x', '-y', '-idq')
#: args for testrar() #: args for testrar()
TEST_ARGS = ('t', '-idq') TEST_ARGS = ('t', '-idq')
#
# Allow use of tool that is not compatible with unrar.
#
# By default use 'bsdtar' which is 'tar' program that
# sits on top of libarchive.
#
# Problems with libarchive RAR backend:
# - Does not support solid archives.
# - Does not support password-protected archives.
#
ALT_TOOL = 'bsdtar'
ALT_OPEN_ARGS = ('-x', '--to-stdout', '-f')
ALT_EXTRACT_ARGS = ('-x', '-f')
ALT_TEST_ARGS = ('-t', '-f')
ALT_CHECK_ARGS = ('--help',)
#: whether to speed up decompression by using tmp archive #: whether to speed up decompression by using tmp archive
USE_EXTRACT_HACK = 1 USE_EXTRACT_HACK = 1
@@ -336,6 +353,8 @@ class RarUnknownError(RarExecError):
"""Unknown exit code""" """Unknown exit code"""
class RarSignalExit(RarExecError): class RarSignalExit(RarExecError):
"""Unrar exited with signal""" """Unrar exited with signal"""
class RarCannotExec(RarExecError):
"""Executable not found."""
def is_rarfile(xfile): def is_rarfile(xfile):
@@ -693,10 +712,7 @@ class RarFile(object):
"""Let 'unrar' test the archive. """Let 'unrar' test the archive.
""" """
cmd = [UNRAR_TOOL] + list(TEST_ARGS) cmd = [UNRAR_TOOL] + list(TEST_ARGS)
if self._password is not None: add_password_arg(cmd, self._password)
cmd.append('-p' + self._password)
else:
cmd.append('-p-')
cmd.append(self.rarfile) cmd.append(self.rarfile)
p = custom_popen(cmd) p = custom_popen(cmd)
output = p.communicate()[0] output = p.communicate()[0]
@@ -1172,8 +1188,7 @@ class RarFile(object):
if is_filelike(rarfile): if is_filelike(rarfile):
raise ValueError("Cannot use unrar directly on memory buffer") raise ValueError("Cannot use unrar directly on memory buffer")
cmd = [UNRAR_TOOL] + list(OPEN_ARGS) cmd = [UNRAR_TOOL] + list(OPEN_ARGS)
if psw is not None: add_password_arg(cmd, psw)
cmd.append("-p" + psw)
cmd.append(rarfile) cmd.append(rarfile)
# not giving filename avoids encoding related problems # not giving filename avoids encoding related problems
@@ -1205,10 +1220,7 @@ class RarFile(object):
# pasoword # pasoword
psw = psw or self._password psw = psw or self._password
if psw is not None: add_password_arg(cmd, psw)
cmd.append('-p' + psw)
else:
cmd.append('-p-')
# rar file # rar file
cmd.append(self.rarfile) cmd.append(self.rarfile)
@@ -1830,10 +1842,7 @@ def rar_decompress(vers, meth, data, declen=0, flags=0, crc=0, psw=None, salt=No
tmpf.close() tmpf.close()
cmd = [UNRAR_TOOL] + list(OPEN_ARGS) cmd = [UNRAR_TOOL] + list(OPEN_ARGS)
if psw is not None and (flags & RAR_FILE_PASSWORD): add_password_arg(cmd, psw, (flags & RAR_FILE_PASSWORD))
cmd.append("-p" + psw)
else:
cmd.append("-p-")
cmd.append(tmpname) cmd.append(tmpname)
p = custom_popen(cmd) p = custom_popen(cmd)
@@ -1902,10 +1911,27 @@ def custom_popen(cmd):
except OSError: except OSError:
ex = sys.exc_info()[1] ex = sys.exc_info()[1]
if ex.errno == errno.ENOENT: if ex.errno == errno.ENOENT:
raise RarExecError("Unrar not installed? (rarfile.UNRAR_TOOL=%r)" % UNRAR_TOOL) raise RarCannotExec("Unrar not installed? (rarfile.UNRAR_TOOL=%r)" % UNRAR_TOOL)
raise raise
return p return p
def custom_check(cmd, ignore_retcode=False):
"""Run command, collect output, raise error if needed."""
p = custom_popen(cmd)
out, err = p.communicate()
if p.returncode and not ignore_retcode:
raise RarExecError("Check-run failed")
return out
def add_password_arg(cmd, psw, required=False):
"""Append password switch to commandline."""
if UNRAR_TOOL == ALT_TOOL:
return
if psw is not None:
cmd.append('-p' + psw)
else:
cmd.append('-p-')
def check_returncode(p, out): def check_returncode(p, out):
"""Raise exception according to unrar exit code""" """Raise exception according to unrar exit code"""
@@ -1920,6 +1946,8 @@ def check_returncode(p, out):
RarWarning, RarFatalError, RarCRCError, RarLockedArchiveError, RarWarning, RarFatalError, RarCRCError, RarLockedArchiveError,
RarWriteError, RarOpenError, RarUserError, RarMemoryError, RarWriteError, RarOpenError, RarUserError, RarMemoryError,
RarCreateError, RarNoFilesError] # codes from rar.txt RarCreateError, RarNoFilesError] # codes from rar.txt
if UNRAR_TOOL == ALT_TOOL:
errmap = [None]
if code > 0 and code < len(errmap): if code > 0 and code < len(errmap):
exc = errmap[code] exc = errmap[code]
elif code == 255: elif code == 255:
@@ -1936,3 +1964,24 @@ def check_returncode(p, out):
msg = "%s [%d]" % (exc.__doc__, p.returncode) msg = "%s [%d]" % (exc.__doc__, p.returncode)
raise exc(msg) raise exc(msg)
#
# Check if unrar works
#
try:
# does UNRAR_TOOL work?
custom_check([UNRAR_TOOL], True)
except RarCannotExec:
try:
# does ALT_TOOL work?
custom_check([ALT_TOOL] + list(ALT_CHECK_ARGS), True)
# replace config
UNRAR_TOOL = ALT_TOOL
OPEN_ARGS = ALT_OPEN_ARGS
EXTRACT_ARGS = ALT_EXTRACT_ARGS
TEST_ARGS = ALT_TEST_ARGS
except RarCannotExec:
# no usable tool, only uncompressed archives work
pass

View File

@@ -14,7 +14,7 @@ if version_info[0] != 3:
exit(1) exit(1)
NAME = "KindleComicConverter" NAME = "KindleComicConverter"
VERSION = "4.3" VERSION = "4.3.1"
MAIN = "kcc.py" MAIN = "kcc.py"
if platform == "darwin": if platform == "darwin":
@@ -47,7 +47,7 @@ if platform == "darwin":
], ],
LSMinimumSystemVersion='10.8.0', LSMinimumSystemVersion='10.8.0',
LSEnvironment=dict( LSEnvironment=dict(
PATH='/usr/local/bin:/usr/bin:/bin' PATH='./../Resources:/usr/local/bin:/usr/bin:/bin'
), ),
NSHumanReadableCopyright='ISC License (ISCL)' NSHumanReadableCopyright='ISC License (ISCL)'
) )

View File

@@ -1,7 +1,7 @@
#!/bin/bash #!/bin/bash
# Linux Python package build script # Linux Python package build script
VERSION="4.3" VERSION="4.3.1"
cp kcc.py __main__.py cp kcc.py __main__.py
zip kcc.zip __main__.py kcc/*.py zip kcc.zip __main__.py kcc/*.py