cleaner fileutils and untarring/unzipping in fileutils, thanks Paolo
This commit is contained in:
+62
-76
@@ -18,12 +18,13 @@ import glob
|
|||||||
import time
|
import time
|
||||||
import datetime
|
import datetime
|
||||||
import logging
|
import logging
|
||||||
|
import shutil
|
||||||
from gluon.http import HTTP
|
from gluon.http import HTTP
|
||||||
from gzip import open as gzopen
|
from gzip import open as gzopen
|
||||||
from gluon.recfile import generate
|
from gluon.recfile import generate
|
||||||
from gluon._compat import PY2
|
from gluon._compat import PY2
|
||||||
|
|
||||||
__all__ = [
|
__all__ = (
|
||||||
'parse_version',
|
'parse_version',
|
||||||
'read_file',
|
'read_file',
|
||||||
'write_file',
|
'write_file',
|
||||||
@@ -41,11 +42,11 @@ __all__ = [
|
|||||||
'check_credentials',
|
'check_credentials',
|
||||||
'w2p_pack',
|
'w2p_pack',
|
||||||
'w2p_unpack',
|
'w2p_unpack',
|
||||||
|
'create_app',
|
||||||
'w2p_pack_plugin',
|
'w2p_pack_plugin',
|
||||||
'w2p_unpack_plugin',
|
'w2p_unpack_plugin',
|
||||||
'fix_newlines',
|
'fix_newlines',
|
||||||
'make_fake_file_like_object',
|
)
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
def parse_semantic(version="Version 1.99.0-rc.1+timestamp.2011.09.19.08.23.26"):
|
def parse_semantic(version="Version 1.99.0-rc.1+timestamp.2011.09.19.08.23.26"):
|
||||||
@@ -58,7 +59,7 @@ def parse_semantic(version="Version 1.99.0-rc.1+timestamp.2011.09.19.08.23.26"):
|
|||||||
tuple: Major, Minor, Patch, Release, Build Date
|
tuple: Major, Minor, Patch, Release, Build Date
|
||||||
|
|
||||||
"""
|
"""
|
||||||
re_version = re.compile('(\d+)\.(\d+)\.(\d+)(\-(?P<pre>[^\s+]*))?(\+(?P<build>\S*))')
|
re_version = re.compile(r'(\d+)\.(\d+)\.(\d+)(-(?P<pre>[^\s+]*))?(\+(?P<build>\S*))')
|
||||||
m = re_version.match(version.strip().split()[-1])
|
m = re_version.match(version.strip().split()[-1])
|
||||||
if not m:
|
if not m:
|
||||||
return None
|
return None
|
||||||
@@ -80,7 +81,7 @@ def parse_legacy(version="Version 1.99.0 (2011-09-19 08:23:26)"):
|
|||||||
tuple: Major, Minor, Patch, Release, Build Date
|
tuple: Major, Minor, Patch, Release, Build Date
|
||||||
|
|
||||||
"""
|
"""
|
||||||
re_version = re.compile('[^\d]+ (\d+)\.(\d+)\.(\d+)\s*\((?P<datetime>.+?)\)\s*(?P<type>[a-z]+)?')
|
re_version = re.compile(r'[^\d]+ (\d+)\.(\d+)\.(\d+)\s*\((?P<datetime>.+?)\)\s*(?P<type>[a-z]+)?')
|
||||||
m = re_version.match(version)
|
m = re_version.match(version)
|
||||||
a, b, c = int(m.group(1)), int(m.group(2)), int(m.group(3)),
|
a, b, c = int(m.group(1)), int(m.group(2)), int(m.group(3)),
|
||||||
pre_release = m.group('type') or 'dev'
|
pre_release = m.group('type') or 'dev'
|
||||||
@@ -109,22 +110,16 @@ def read_file(filename, mode='r'):
|
|||||||
"""Returns content from filename, making sure to close the file explicitly
|
"""Returns content from filename, making sure to close the file explicitly
|
||||||
on exit.
|
on exit.
|
||||||
"""
|
"""
|
||||||
f = open_file(filename, mode)
|
with open_file(filename, mode) as f:
|
||||||
try:
|
|
||||||
return f.read()
|
return f.read()
|
||||||
finally:
|
|
||||||
f.close()
|
|
||||||
|
|
||||||
|
|
||||||
def write_file(filename, value, mode='w'):
|
def write_file(filename, value, mode='w'):
|
||||||
"""Writes <value> to filename, making sure to close the file
|
"""Writes <value> to filename, making sure to close the file
|
||||||
explicitly on exit.
|
explicitly on exit.
|
||||||
"""
|
"""
|
||||||
f = open_file(filename, mode)
|
with open_file(filename, mode) as f:
|
||||||
try:
|
|
||||||
return f.write(value)
|
return f.write(value)
|
||||||
finally:
|
|
||||||
f.close()
|
|
||||||
|
|
||||||
|
|
||||||
def readlines_file(filename, mode='r'):
|
def readlines_file(filename, mode='r'):
|
||||||
@@ -200,10 +195,10 @@ def cleanpath(path):
|
|||||||
|
|
||||||
items = path.split('.')
|
items = path.split('.')
|
||||||
if len(items) > 1:
|
if len(items) > 1:
|
||||||
path = re.sub('[^\w\.]+', '_', '_'.join(items[:-1]) + '.'
|
path = re.sub(r'[^\w.]+', '_', '_'.join(items[:-1]) + '.'
|
||||||
+ ''.join(items[-1:]))
|
+ ''.join(items[-1:]))
|
||||||
else:
|
else:
|
||||||
path = re.sub('[^\w\.]+', '_', ''.join(items[-1:]))
|
path = re.sub(r'[^\w.]+', '_', ''.join(items[-1:]))
|
||||||
return path
|
return path
|
||||||
|
|
||||||
|
|
||||||
@@ -250,59 +245,64 @@ def w2p_pack(filename, path, compiled=False, filenames=None):
|
|||||||
path = abspath(path)
|
path = abspath(path)
|
||||||
tarname = filename + '.tar'
|
tarname = filename + '.tar'
|
||||||
if compiled:
|
if compiled:
|
||||||
tar_compiled(tarname, path, '^[\w\.\-]+$',
|
tar_compiled(tarname, path, r'^[\w.-]+$',
|
||||||
exclude_content_from=['cache', 'sessions', 'errors'])
|
exclude_content_from=['cache', 'sessions', 'errors'])
|
||||||
else:
|
else:
|
||||||
tar(tarname, path, '^[\w\.\-]+$', filenames=filenames,
|
tar(tarname, path, r'^[\w.-]+$', filenames=filenames,
|
||||||
exclude_content_from=['cache', 'sessions', 'errors'])
|
exclude_content_from=['cache', 'sessions', 'errors'])
|
||||||
w2pfp = gzopen(filename, 'wb')
|
with open(tarname, 'rb') as tarfp, gzopen(filename, 'wb') as gzfp:
|
||||||
tarfp = open(tarname, 'rb')
|
shutil.copyfileobj(tarfp, gzfp, 4194304) # 4 MB buffer
|
||||||
w2pfp.write(tarfp.read())
|
|
||||||
w2pfp.close()
|
|
||||||
tarfp.close()
|
|
||||||
os.unlink(tarname)
|
os.unlink(tarname)
|
||||||
|
|
||||||
|
|
||||||
def create_welcome_w2p():
|
def create_welcome_w2p():
|
||||||
is_newinstall_file = os.path.exists('NEWINSTALL')
|
is_newinstall = os.path.exists('NEWINSTALL')
|
||||||
if not os.path.exists('welcome.w2p') or is_newinstall_file:
|
if not os.path.exists('welcome.w2p') or is_newinstall:
|
||||||
|
logger = logging.getLogger("web2py")
|
||||||
try:
|
try:
|
||||||
w2p_pack('welcome.w2p', 'applications/welcome')
|
w2p_pack('welcome.w2p', 'applications/welcome')
|
||||||
logging.info("New installation: created welcome.w2p file")
|
logger.info("New installation: created welcome.w2p file")
|
||||||
except:
|
except:
|
||||||
logging.error("New installation error: unable to create welcome.w2p file")
|
logger.exception("New installation error: unable to create welcome.w2p file")
|
||||||
return
|
return
|
||||||
if is_newinstall_file:
|
if is_newinstall:
|
||||||
try:
|
try:
|
||||||
os.unlink('NEWINSTALL')
|
os.unlink('NEWINSTALL')
|
||||||
logging.info("New installation: removed NEWINSTALL file")
|
logger.info("New installation: removed NEWINSTALL file")
|
||||||
except:
|
except:
|
||||||
logging.error("New installation error: unable to remove NEWINSTALL file")
|
logger.exception("New installation error: unable to remove NEWINSTALL file")
|
||||||
|
|
||||||
|
|
||||||
def w2p_unpack(filename, path, delete_tar=True):
|
def w2p_unpack(filename, path, delete_tar=True):
|
||||||
|
|
||||||
if filename == 'welcome.w2p':
|
if filename == 'welcome.w2p':
|
||||||
create_welcome_w2p()
|
create_welcome_w2p()
|
||||||
filename = abspath(filename)
|
filename = abspath(filename)
|
||||||
path = abspath(path)
|
tarname = None
|
||||||
if filename[-4:] == '.w2p' or filename[-3:] == '.gz':
|
if filename.endswith('.w2p'):
|
||||||
if filename[-4:] == '.w2p':
|
tarname = filename[:-4] + '.tar'
|
||||||
tarname = filename[:-4] + '.tar'
|
elif filename.endswith('.gz'):
|
||||||
else:
|
tarname = filename[:-3] + '.tar'
|
||||||
tarname = filename[:-3] + '.tar'
|
if tarname is not None:
|
||||||
fgzipped = gzopen(filename, 'rb')
|
with gzopen(filename, 'rb') as gzfp, open(tarname, 'wb') as tarfp:
|
||||||
tarfile = open(tarname, 'wb')
|
shutil.copyfileobj(gzfp, tarfp, 4194304) # 4 MB buffer
|
||||||
tarfile.write(fgzipped.read())
|
|
||||||
tarfile.close()
|
|
||||||
fgzipped.close()
|
|
||||||
else:
|
else:
|
||||||
tarname = filename
|
tarname = filename
|
||||||
|
path = abspath(path)
|
||||||
untar(tarname, path)
|
untar(tarname, path)
|
||||||
if delete_tar:
|
if delete_tar:
|
||||||
os.unlink(tarname)
|
os.unlink(tarname)
|
||||||
|
|
||||||
|
|
||||||
|
def create_app(path):
|
||||||
|
w2p_unpack('welcome.w2p', path)
|
||||||
|
for subfolder in ('models', 'views', 'controllers', 'databases',
|
||||||
|
'modules', 'cron', 'errors', 'sessions',
|
||||||
|
'languages', 'static', 'private', 'uploads'):
|
||||||
|
subpath = os.path.join(path, subfolder)
|
||||||
|
if not os.path.exists(subpath):
|
||||||
|
os.mkdir(subpath)
|
||||||
|
|
||||||
|
|
||||||
def w2p_pack_plugin(filename, path, plugin_name):
|
def w2p_pack_plugin(filename, path, plugin_name):
|
||||||
"""Packs the given plugin into a w2p file.
|
"""Packs the given plugin into a w2p file.
|
||||||
Will match files at::
|
Will match files at::
|
||||||
@@ -314,11 +314,10 @@ def w2p_pack_plugin(filename, path, plugin_name):
|
|||||||
filename = abspath(filename)
|
filename = abspath(filename)
|
||||||
path = abspath(path)
|
path = abspath(path)
|
||||||
if not filename.endswith('web2py.plugin.%s.w2p' % plugin_name):
|
if not filename.endswith('web2py.plugin.%s.w2p' % plugin_name):
|
||||||
raise Exception("Not a web2py plugin name")
|
raise ValueError('Not a web2py plugin')
|
||||||
plugin_tarball = tarfile.open(filename, 'w:gz')
|
with tarfile.open(filename, 'w:gz') as plugin_tarball:
|
||||||
try:
|
|
||||||
app_dir = path
|
app_dir = path
|
||||||
while app_dir[-1] == '/':
|
while app_dir.endswith('/'):
|
||||||
app_dir = app_dir[:-1]
|
app_dir = app_dir[:-1]
|
||||||
files1 = glob.glob(
|
files1 = glob.glob(
|
||||||
os.path.join(app_dir, '*/plugin_%s.*' % plugin_name))
|
os.path.join(app_dir, '*/plugin_%s.*' % plugin_name))
|
||||||
@@ -326,15 +325,13 @@ def w2p_pack_plugin(filename, path, plugin_name):
|
|||||||
os.path.join(app_dir, '*/plugin_%s/*' % plugin_name))
|
os.path.join(app_dir, '*/plugin_%s/*' % plugin_name))
|
||||||
for file in files1 + files2:
|
for file in files1 + files2:
|
||||||
plugin_tarball.add(file, arcname=file[len(app_dir) + 1:])
|
plugin_tarball.add(file, arcname=file[len(app_dir) + 1:])
|
||||||
finally:
|
|
||||||
plugin_tarball.close()
|
|
||||||
|
|
||||||
|
|
||||||
def w2p_unpack_plugin(filename, path, delete_tar=True):
|
def w2p_unpack_plugin(filename, path, delete_tar=True):
|
||||||
filename = abspath(filename)
|
filename = abspath(filename)
|
||||||
path = abspath(path)
|
path = abspath(path)
|
||||||
if not os.path.basename(filename).startswith('web2py.plugin.'):
|
if not os.path.basename(filename).startswith('web2py.plugin.'):
|
||||||
raise Exception("Not a web2py plugin")
|
raise ValueError('Not a web2py plugin')
|
||||||
w2p_unpack(filename, path, delete_tar)
|
w2p_unpack(filename, path, delete_tar)
|
||||||
|
|
||||||
|
|
||||||
@@ -344,23 +341,22 @@ def tar_compiled(file, dir, expression='^.+$',
|
|||||||
The content of models, views, controllers is not stored in the tar file.
|
The content of models, views, controllers is not stored in the tar file.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
tar = tarfile.TarFile(file, 'w')
|
with tarfile.TarFile(file, 'w') as tar:
|
||||||
for file in listdir(dir, expression, add_dirs=True,
|
for file in listdir(dir, expression, add_dirs=True,
|
||||||
exclude_content_from=exclude_content_from):
|
exclude_content_from=exclude_content_from):
|
||||||
filename = os.path.join(dir, file)
|
filename = os.path.join(dir, file)
|
||||||
if os.path.islink(filename):
|
if os.path.islink(filename):
|
||||||
continue
|
|
||||||
if os.path.isfile(filename) and file[-4:] != '.pyc':
|
|
||||||
if file[:6] == 'models':
|
|
||||||
continue
|
continue
|
||||||
if file[:5] == 'views':
|
if os.path.isfile(filename) and not file.endswith('.pyc'):
|
||||||
continue
|
if file.startswith('models'):
|
||||||
if file[:11] == 'controllers':
|
continue
|
||||||
continue
|
if file.startswith('views'):
|
||||||
if file[:7] == 'modules':
|
continue
|
||||||
continue
|
if file.startswith('controllers'):
|
||||||
tar.add(filename, file, False)
|
continue
|
||||||
tar.close()
|
if file.startswith('modules'):
|
||||||
|
continue
|
||||||
|
tar.add(filename, file, False)
|
||||||
|
|
||||||
|
|
||||||
def up(path):
|
def up(path):
|
||||||
@@ -378,7 +374,7 @@ def get_session(request, other_application='admin'):
|
|||||||
if not os.path.exists(session_filename):
|
if not os.path.exists(session_filename):
|
||||||
session_filename = generate(session_filename)
|
session_filename = generate(session_filename)
|
||||||
osession = storage.load_storage(session_filename)
|
osession = storage.load_storage(session_filename)
|
||||||
except Exception as e:
|
except:
|
||||||
osession = storage.Storage()
|
osession = storage.Storage()
|
||||||
return osession
|
return osession
|
||||||
|
|
||||||
@@ -421,7 +417,7 @@ def fix_newlines(path):
|
|||||||
regex = re.compile(r'''(\r
|
regex = re.compile(r'''(\r
|
||||||
|\r|
|
|\r|
|
||||||
)''')
|
)''')
|
||||||
for filename in listdir(path, '.*\.(py|html)$', drop=False):
|
for filename in listdir(path, r'.*\.(py|html)$', drop=False):
|
||||||
rdata = read_file(filename, 'r')
|
rdata = read_file(filename, 'r')
|
||||||
wdata = regex.sub('\n', rdata)
|
wdata = regex.sub('\n', rdata)
|
||||||
if wdata != rdata:
|
if wdata != rdata:
|
||||||
@@ -455,16 +451,6 @@ def copystream(
|
|||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
def make_fake_file_like_object():
|
|
||||||
class LogFile(object):
|
|
||||||
def write(self, value):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def close(self):
|
|
||||||
pass
|
|
||||||
return LogFile()
|
|
||||||
|
|
||||||
|
|
||||||
from gluon.settings import global_settings # we need to import settings here because
|
from gluon.settings import global_settings # we need to import settings here because
|
||||||
# settings imports fileutils too
|
# settings imports fileutils too
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user