Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Anders Blomdell
apa
Commits
ff37baca
Commit
ff37baca
authored
Jan 26, 2005
by
Anders Blomdell
Browse files
Initial commit
parents
Changes
1
Hide whitespace changes
Inline
Side-by-side
apa
0 → 100755
View file @
ff37baca
#!/usr/bin/python
"""
Anders Python Archiver
Copyright (C) 2004 Anders Blomdell <anders.blomdell@control.lth.se>
A small utility program to join a number of python modules
into a single executable python program.
http://www.control.lth.se/~andersb/software/apa
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
"""
import
optparse
import
os
import
re
import
string
import
sys
def
getModuleName
(
s
):
m
=
re
.
match
(
"^(.*)/__init__\.py$"
,
s
)
if
m
:
return
string
.
replace
(
m
.
group
(
1
),
"/"
,
"."
)
m
=
re
.
match
(
"^(.*)\.py$"
,
s
)
if
m
:
return
string
.
replace
(
m
.
group
(
1
),
"/"
,
"."
)
return
None
def
emitCode
(
f
,
module
,
name
,
filename
,
code
):
print
>>
sys
.
stderr
,
"EMIT:"
,
name
print
>>
f
,
'"%s" : ( "%s", "%s", """%s""")'
%
(
quote
(
module
),
quote
(
name
),
quote
(
filename
),
quote
(
code
))
def
quote
(
s
):
return
string
.
replace
(
string
.
replace
(
s
,
'
\\
'
,
'
\\\\
'
),
'"'
,
'
\\
"'
)
if
__name__
==
'__main__'
:
usage
=
"%prog [options] <main module> <additional modules>*"
optParser
=
optparse
.
OptionParser
(
usage
=
usage
)
optParser
.
add_option
(
'-d'
,
'--documentation'
,
action
=
'store_true'
,
help
=
'Show documentation'
)
optParser
.
add_option
(
'-o'
,
'--output'
,
action
=
'store'
,
help
=
'Name of archive'
)
(
options
,
args
)
=
optParser
.
parse_args
(
sys
.
argv
[
1
:])
if
options
.
documentation
:
print
__doc__
sys
.
exit
(
0
)
# Read all python files
code
=
[]
for
filename
in
args
:
name
=
getModuleName
(
filename
)
if
name
:
f
=
open
(
filename
)
code
.
append
((
name
,
filename
,
f
.
read
()))
f
.
close
()
else
:
print
"Illegal filename '%s'"
%
filename
sys
.
exit
(
1
)
if
options
.
output
:
apa
=
file
(
options
.
output
,
'w'
)
else
:
apa
=
None
# Emit code
interpreter
=
code
[
0
][
2
].
splitlines
()[
0
]
if
interpreter
.
find
(
"python"
)
>=
0
:
# Take interpreter version from main file
print
>>
apa
,
interpreter
else
:
# Default interpreter
print
>>
sys
.
stderr
,
"Interpreter defaulting to '#!/usr/bin/python'"
print
>>
apa
,
"#!/usr/bin/python"
print
>>
apa
,
"
\"\"\"
"
print
>>
apa
,
"Executable archive of '%s'"
%
code
[
0
][
0
]
print
>>
apa
,
"
\n
The following modules are archived:"
print
>>
apa
,
" %-20s %s"
%
(
'__main__'
,
code
[
0
][
1
])
for
(
n
,
f
,
c
)
in
code
[
1
:]:
print
>>
apa
,
" %-20s %s"
%
(
n
,
f
)
print
>>
apa
,
"""
Archive created by 'apa' (http://www.control.lth.se/~andersb/software/apa)
To extract as individual files:
* Add a .py suffix to the archive (if needed)
* Start a python interpreter
* Run the following commands:
import <archive name>
<archive name>.extract(<optional destination dir>)
\"\"\"
"""
print
>>
apa
,
"code = {"
(
n
,
f
,
c
)
=
code
[
0
]
emitCode
(
apa
,
'__apa__main__'
,
'__main__'
,
f
,
c
)
for
(
n
,
f
,
c
)
in
code
[
1
:]:
print
>>
apa
,
","
emitCode
(
apa
,
n
,
n
,
f
,
c
)
print
>>
apa
,
"}"
print
>>
apa
,
"""
import exceptions
import ihooks
import imp
import os
import os.path
import sys
import traceback
class StringImporter(ihooks.ModuleImporter, object):
\"\"\"
Loads modules from local code dictionary
\"\"\"
def __init__(self, code_dict):
super(StringImporter, self).__init__()
self.code_dict = code_dict;
self.loaded = {}
self.result = None
def import_it(self, partname, fqname, parent, force_load=0):
try:
# First shot, return part from parent module
return parent.__dict__[partname]
except (KeyError, AttributeError):
pass
try:
# Second shot, load it from already loaded code
return self.loaded[fqname]
except (KeyError, AttributeError):
pass
try:
# Third shot, load it from code_dictionary
(name, filename, code) = self.code_dict[fqname]
module = self.loader.hooks.add_module(fqname)
self.loaded[fqname] = module
module.__name__ = name
module.__file__ = filename
try:
comp = compile(code, filename, 'exec')
exec comp in module.__dict__
except exceptions.SystemExit, e:
# Silently propagate exit
raise e
except Exception, e:
# print module.__file__
# print "StringLoading '%s' failed: %s [%s]" % (fqname,
# e, e.__class__)
traceback.print_exc()
raise exceptions.SystemExit(1)
if parent != None:
parent.__dict__[partname] = module
return module
except (KeyError, AttributeError), e:
pass
# Fourth shot, default loader
return ihooks.ModuleImporter.import_it(self, partname, fqname, parent, force_load)
def reload(self, module):
for (n, m) in self.loaded.iteritems():
if m is module:
(filename, code) = self.code_dict[n]
exec code in module.__dict__
return
return super(StringImporter, self).reload(module)
def extract(dest='.'):
\"\"\"
Extracts archived files in dest directory ('.' is default)
\"\"\"
for (m, (n, f, c)) in code.iteritems():
filepath = '%s/%s' % (dest, f)
dirpath = os.path.dirname(filepath)
if os.path.exists(filepath):
raise Exception('File already exists: %s' % filepath)
if not os.path.exists(dirpath):
os.makedirs(dirpath)
f = file(filepath, 'w')
f.write(c)
f.close()
os.chmod(filepath, 0755)
if __name__ == '__main__':
importer = StringImporter(code)
importer.install()
# This will start actual execution
try:
import __apa__main__
except exceptions.SystemExit, e:
raise e
except:
sys.exit(1)
"""
if
apa
:
apa
.
close
()
os
.
chmod
(
options
.
output
,
0755
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment