Initial commit
This commit is contained in:
commit
9c872636d6
|
@ -0,0 +1,19 @@
|
||||||
|
Copyright (c) 2023
|
||||||
|
|
||||||
|
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 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.
|
|
@ -0,0 +1,35 @@
|
||||||
|
A script that can list/extract files from archives, by automatically choosing the correct tool and translating the tool's input/output into the same format, when it comes to listing files.
|
||||||
|
|
||||||
|
This isn't really meant to be used by people. It's supposed to act as an API for other programs that interact with archives.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Syntax: spitzip <action> <flags> <archive>
|
||||||
|
|
||||||
|
Available actions:
|
||||||
|
* help - Prints this help
|
||||||
|
* list - Outputs each file of archive as a json table
|
||||||
|
* extract - Copy a file/folder from the archive into another folder. -if= sets
|
||||||
|
the path to copy from the archive (DO NOT use wildcards!), -of= sets the output
|
||||||
|
folder. The output folder has to exist. Files are replaced without asking.
|
||||||
|
|
||||||
|
Universal flags:
|
||||||
|
* -tool= - Which tool to use for the archive. By default, the program guesses
|
||||||
|
the best tool for the job. Available: 7z, tar
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Prerequisites:
|
||||||
|
* Python 3 (Version 3.4 or up)
|
||||||
|
* 7-zip (on Linux, p7zip)
|
||||||
|
* tar
|
||||||
|
* Optional: file (for detecting mimetype)
|
||||||
|
|
||||||
|
Installation:
|
||||||
|
* sudo ./install
|
||||||
|
* Note: Installation is not required. You can run the program portably by using ./app
|
||||||
|
|
||||||
|
Uninstallation:
|
||||||
|
* sudo /opt/spitzip/uninstall
|
||||||
|
|
||||||
|
You can change the name of the program using appname.txt, and change other settings like installation directory and bin directory from config.txt.
|
|
@ -0,0 +1,28 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
def init():
|
||||||
|
app = mfp.require("main")
|
||||||
|
|
||||||
|
def main():
|
||||||
|
mfp.setProgramName(open(mfp.p(mfp.sd,"appname.txt"),"r",encoding="utf-8").read().strip(" \t\r\n"))
|
||||||
|
app = mfp.require("main")
|
||||||
|
app.main()
|
||||||
|
|
||||||
|
def bootstrap(name,modName):
|
||||||
|
if name in globals(): return
|
||||||
|
import sys, os, importlib
|
||||||
|
if getattr(sys, 'frozen', False) and hasattr(sys, '_MEIPASS'):
|
||||||
|
s = os.path.realpath(sys.executable)
|
||||||
|
else:
|
||||||
|
s = os.path.realpath(__file__)
|
||||||
|
|
||||||
|
if not os.path.join(os.path.dirname(s),"module","py") in sys.path:
|
||||||
|
sys.path = [os.path.join(os.path.dirname(s),"module","py")] + sys.path
|
||||||
|
|
||||||
|
mod = importlib.import_module(modName); modl = mod.Bunch()
|
||||||
|
mod.init(mod,modl,s,name)
|
||||||
|
globals()[name] = mod; globals()[name + "l"] = modl
|
||||||
|
|
||||||
|
bootstrap("mfp","me.fier.python")
|
||||||
|
init()
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
|
@ -0,0 +1 @@
|
||||||
|
spitzip
|
|
@ -0,0 +1,3 @@
|
||||||
|
APP_NAME="$(cat $MY_DIR/appname.txt)"
|
||||||
|
APP_DIR="/opt/$APP_NAME"
|
||||||
|
APP_BIN_DIR="/usr/local/bin"
|
|
@ -0,0 +1,29 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
MY_DIR="$(dirname "$(realpath "$BASH_SOURCE")")"
|
||||||
|
source "$MY_DIR/config.txt"
|
||||||
|
|
||||||
|
if ! [ "$UNINSTALL" == "1" ]; then
|
||||||
|
if [ "$APP_DIR" == "$MY_DIR" ]; then
|
||||||
|
echo "This copy is already installed."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -d "$APP_DIR" ]; then
|
||||||
|
rm -r "$APP_DIR"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -L "$APP_BIN_DIR/$APP_NAME" ]; then
|
||||||
|
rm "$APP_BIN_DIR/$APP_NAME"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$UNINSTALL" == "1" ]; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$APP_DIR"
|
||||||
|
cp -r "$MY_DIR/." "$APP_DIR"
|
||||||
|
mkdir -p "$APP_BIN_DIR"
|
||||||
|
ln -s "$APP_DIR/app" "$APP_BIN_DIR/$APP_NAME"
|
||||||
|
chmod +x "$APP_BIN_DIR/$APP_NAME"
|
|
@ -0,0 +1,16 @@
|
||||||
|
import copy
|
||||||
|
_file = {
|
||||||
|
"isdir": False,
|
||||||
|
"date": [0,0,0],
|
||||||
|
"time": [0,0,0],
|
||||||
|
"size": 0,
|
||||||
|
"sizeCompressed": 0,
|
||||||
|
"name": "",
|
||||||
|
|
||||||
|
"ownerGroup": -1,
|
||||||
|
"ownerUser": -1,
|
||||||
|
"permissions": "---------"
|
||||||
|
}
|
||||||
|
|
||||||
|
def getDefaultFile():
|
||||||
|
return copy.deepcopy(_file)
|
|
@ -0,0 +1,13 @@
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
import time
|
||||||
|
|
||||||
|
def rmtree(path):
|
||||||
|
shutil.rmtree(path)
|
||||||
|
if not os.path.isdir(path): return
|
||||||
|
waited = 0
|
||||||
|
while waited < 100:
|
||||||
|
if not os.path.isdir(path): return
|
||||||
|
time.sleep(0.1)
|
||||||
|
waited += 1
|
||||||
|
raise Exception("Directory survived shutil.rmtree")
|
|
@ -0,0 +1,124 @@
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
prochelper = mfp.require("prochelper")
|
||||||
|
prochelper.setLanguage("C")
|
||||||
|
eprint = mfp.require("printhelper").eprint
|
||||||
|
|
||||||
|
def getFlag(flags,flag):
|
||||||
|
if not flag in flags: return None
|
||||||
|
return flags[flag]
|
||||||
|
|
||||||
|
def getArchiveTool(archiveFile):
|
||||||
|
tool = "7z"
|
||||||
|
|
||||||
|
while True:
|
||||||
|
# Method 1: file command
|
||||||
|
try:
|
||||||
|
mimetype = prochelper.pcallStr(["file","-b","--mime-type","--uncompress",archiveFile])
|
||||||
|
if mimetype == "application/x-tar":
|
||||||
|
tool = "tar"
|
||||||
|
break
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
eprint("Warning: 'file' exited with error " +str(e.returncode))
|
||||||
|
|
||||||
|
# Method 2: file extension
|
||||||
|
archiveFileSplit = archiveFile.rsplit(".",2)
|
||||||
|
if len(archiveFileSplit) < 2:
|
||||||
|
eprint("Warning: No file extension.")
|
||||||
|
break
|
||||||
|
|
||||||
|
if archiveFileSplit[-1].lower() == "tar":
|
||||||
|
tool = "tar"
|
||||||
|
break
|
||||||
|
|
||||||
|
if len(archiveFileSplit) > 2 and archiveFileSplit[-2].lower() == "tar":
|
||||||
|
tool = "tar"
|
||||||
|
break
|
||||||
|
|
||||||
|
break
|
||||||
|
|
||||||
|
return tool
|
||||||
|
|
||||||
|
def printHelp(exitCode):
|
||||||
|
eprint('''\
|
||||||
|
Syntax: "''' +sys.argv[0]+ '''" <action> <flags> <archive>
|
||||||
|
|
||||||
|
Available actions:
|
||||||
|
* help - Prints this help
|
||||||
|
* list - Outputs each file of archive as a json table
|
||||||
|
* extract - Copy a file/folder from the archive into another folder. -if= sets
|
||||||
|
the path to copy from the archive (DO NOT use wildcards!), -of= sets the output
|
||||||
|
folder. The output folder has to exist. Files are replaced without asking.
|
||||||
|
|
||||||
|
Universal flags:
|
||||||
|
* -tool= - Which tool to use for the archive. By default, the program guesses
|
||||||
|
the best tool for the job. Available: 7z, tar\
|
||||||
|
''')
|
||||||
|
sys.exit(exitCode)
|
||||||
|
|
||||||
|
def main():
|
||||||
|
args = sys.argv[1:]
|
||||||
|
if len(args) > 0:
|
||||||
|
action = args.pop(0)
|
||||||
|
else:
|
||||||
|
eprint("ERROR: No action given.\n")
|
||||||
|
printHelp(1)
|
||||||
|
|
||||||
|
flags = {}
|
||||||
|
index = 0
|
||||||
|
length = len(args)
|
||||||
|
while index < length:
|
||||||
|
arg = args[index]
|
||||||
|
if arg.startswith("-") and "=" in arg:
|
||||||
|
arg = arg[1:].split("=",1)
|
||||||
|
flags[arg[0]] = arg[1]
|
||||||
|
del args[index]
|
||||||
|
length -= 1
|
||||||
|
continue
|
||||||
|
index += 1
|
||||||
|
|
||||||
|
if length > 1:
|
||||||
|
eprint("ERROR: Too many, or malformed arguments.\n")
|
||||||
|
printHelp(1)
|
||||||
|
|
||||||
|
if length < 1:
|
||||||
|
eprint("ERROR: No archive file in arguments.\n")
|
||||||
|
printHelp(1)
|
||||||
|
|
||||||
|
archiveFile = args[0]
|
||||||
|
if not os.path.isfile(archiveFile):
|
||||||
|
eprint("ERROR: " +archiveFile+ " not found.")
|
||||||
|
printHelp(1)
|
||||||
|
|
||||||
|
if action == "help": printHelp(0)
|
||||||
|
|
||||||
|
tool = getFlag(flags,"tool")
|
||||||
|
if tool == None:
|
||||||
|
tool = getArchiveTool(archiveFile)
|
||||||
|
toolApi = mfp.require("tools/" +tool)
|
||||||
|
|
||||||
|
if action == "list":
|
||||||
|
import json
|
||||||
|
for apiFile in toolApi.action_list(archiveFile,flags):
|
||||||
|
print(json.dumps(apiFile))
|
||||||
|
return
|
||||||
|
|
||||||
|
if action == "extract":
|
||||||
|
if not "if" in flags:
|
||||||
|
eprint("ERROR: -if flag is not set.\n")
|
||||||
|
printHelp(1)
|
||||||
|
|
||||||
|
if not "of" in flags:
|
||||||
|
eprint("ERROR: -of flag is not set.\n")
|
||||||
|
printHelp(1)
|
||||||
|
|
||||||
|
if not os.path.isdir(flags["of"]):
|
||||||
|
eprint("ERROR: -of '" + str(flags["of"]) + "' is not a directory.")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
toolApi.action_extract(archiveFile,flags)
|
||||||
|
return
|
||||||
|
|
||||||
|
eprint("ERROR: Invalid action.\n")
|
||||||
|
printHelp()
|
||||||
|
sys.exit(1)
|
|
@ -0,0 +1,3 @@
|
||||||
|
import sys
|
||||||
|
def eprint(*args, **kwargs):
|
||||||
|
print(*args,file=sys.stderr,**kwargs)
|
|
@ -0,0 +1,69 @@
|
||||||
|
import subprocess
|
||||||
|
import os
|
||||||
|
def perr(rtn,cmd = None,op = None):
|
||||||
|
if rtn == 0: return
|
||||||
|
if cmd == None: cmd = []
|
||||||
|
exc = subprocess.CalledProcessError(rtn,cmd,op)
|
||||||
|
raise exc
|
||||||
|
|
||||||
|
def pcall(*args,**kwargs):
|
||||||
|
rtn = subprocess.Popen(*args,**kwargs).wait()
|
||||||
|
perr(rtn,args[0])
|
||||||
|
|
||||||
|
def pcallStr(*args,**kwargs):
|
||||||
|
proc = subprocess.Popen(*args,**kwargs, stdout=subprocess.PIPE)
|
||||||
|
response = proc.stdout.read().decode("utf-8").strip("\n")
|
||||||
|
rtn = proc.wait()
|
||||||
|
perr(rtn,args[0])
|
||||||
|
return response
|
||||||
|
|
||||||
|
def pcallLines(*args,**kwargs):
|
||||||
|
proc = subprocess.Popen(*args,**kwargs, stdout=subprocess.PIPE)
|
||||||
|
line = b""
|
||||||
|
while True:
|
||||||
|
b = proc.stdout.read(1)
|
||||||
|
if b == b"":
|
||||||
|
yield line.decode("utf-8")
|
||||||
|
break
|
||||||
|
if b == b"\n":
|
||||||
|
yield line.decode("utf-8")
|
||||||
|
line = b""
|
||||||
|
continue
|
||||||
|
line = line + b
|
||||||
|
rtn = proc.wait()
|
||||||
|
perr(rtn,args[0])
|
||||||
|
|
||||||
|
langStore = False
|
||||||
|
def setLanguage(lang = None):
|
||||||
|
def getLanguageEnvs():
|
||||||
|
envs = []
|
||||||
|
for env in os.environ:
|
||||||
|
if env.startswith("LC_"):
|
||||||
|
envs.append(env)
|
||||||
|
continue
|
||||||
|
|
||||||
|
if env in ["LANGUAGE","LANG"]:
|
||||||
|
envs.append(env)
|
||||||
|
continue
|
||||||
|
|
||||||
|
return envs
|
||||||
|
|
||||||
|
def unsetLanguage():
|
||||||
|
for env in getLanguageEnvs():
|
||||||
|
del os.environ[env]
|
||||||
|
|
||||||
|
if lang == None:
|
||||||
|
if langStore == False: return
|
||||||
|
unsetLanguage()
|
||||||
|
for env in langStore: os.environ[env] = langStore[env]
|
||||||
|
langStore = False
|
||||||
|
return
|
||||||
|
|
||||||
|
langStore = {}
|
||||||
|
for env in getLanguageEnvs():
|
||||||
|
langStore[env] = os.environ[env]
|
||||||
|
|
||||||
|
unsetLanguage()
|
||||||
|
os.environ["LANGUAGE"] = lang
|
||||||
|
os.environ["LC_ALL"] = lang
|
||||||
|
os.environ["LANG"] = lang
|
|
@ -0,0 +1,82 @@
|
||||||
|
import os
|
||||||
|
|
||||||
|
# BUNCH
|
||||||
|
try:
|
||||||
|
import munch
|
||||||
|
Bunch = munch.Munch
|
||||||
|
bunchify = munch.munchify
|
||||||
|
unbunchify = munch.unmunchify
|
||||||
|
except Exception:
|
||||||
|
import bunch
|
||||||
|
Bunch = munch.Bunch
|
||||||
|
bunchify = munch.bunchify
|
||||||
|
unbunchify = munch.unbunchify
|
||||||
|
|
||||||
|
# GLOBALS
|
||||||
|
g = Bunch()
|
||||||
|
|
||||||
|
# SCRIPTS
|
||||||
|
paths = []
|
||||||
|
loaded = Bunch()
|
||||||
|
|
||||||
|
def docode(st,name = "Unknown"):
|
||||||
|
code = compile(st,name,"exec")
|
||||||
|
glb = Bunch()
|
||||||
|
glb[distro] = me
|
||||||
|
glb[distro + "l"] = Bunch()
|
||||||
|
glb[distro + "l"].s = name
|
||||||
|
try:
|
||||||
|
glb[distro + "l"].sd = pUp(name)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
glb[distro + "l"].g = glb
|
||||||
|
exec(code,glb)
|
||||||
|
return glb
|
||||||
|
|
||||||
|
def dofile(path):
|
||||||
|
return docode(open(path,"rb").read(),path)
|
||||||
|
|
||||||
|
def dorequire(name,*args,**kwargs):
|
||||||
|
name = name.replace("/",".").replace("\\",".")
|
||||||
|
for path in paths:
|
||||||
|
path = path.replace("?",name.replace(".",os.path.sep))
|
||||||
|
if os.path.isfile(path):
|
||||||
|
return dofile(path,*args,**kwargs)
|
||||||
|
raise Exception("Library " +name+ " not found.")
|
||||||
|
|
||||||
|
def require(name,*args,**kwargs):
|
||||||
|
if not name in loaded:
|
||||||
|
loaded[name] = dorequire(name,*args,**kwargs)
|
||||||
|
return loaded[name]
|
||||||
|
|
||||||
|
# PROGRAM
|
||||||
|
programName = None
|
||||||
|
programNameSet = False
|
||||||
|
def setProgramName(name):
|
||||||
|
global programName,programNameSet
|
||||||
|
if programNameSet: return
|
||||||
|
programNameSet = True
|
||||||
|
programName = name
|
||||||
|
|
||||||
|
# INIT
|
||||||
|
inited = False
|
||||||
|
def init(mod,modl,sp,d):
|
||||||
|
global inited
|
||||||
|
if inited: return
|
||||||
|
global distro,me,p,pUp,programName,programNameSet,s,sd,distro
|
||||||
|
import sys
|
||||||
|
inited = True
|
||||||
|
distro = d
|
||||||
|
me = mod
|
||||||
|
|
||||||
|
p = os.path.join
|
||||||
|
pUp = os.path.dirname
|
||||||
|
s = sp
|
||||||
|
sd = pUp(sp)
|
||||||
|
modl.s = s
|
||||||
|
modl.sd = sd
|
||||||
|
programName = distro + "." + s.replace(modl.sd + os.path.sep,"",1).rsplit(".",1)[0]
|
||||||
|
programNameSet = False
|
||||||
|
|
||||||
|
paths.append(p(modl.sd,"module","?.py"))
|
||||||
|
paths.append(p(modl.sd,"module","?","_main.py"))
|
Binary file not shown.
|
@ -0,0 +1,102 @@
|
||||||
|
import os
|
||||||
|
api = mfp.require("api")
|
||||||
|
prochelper = mfp.require("prochelper")
|
||||||
|
filehelper = mfp.require("filehelper")
|
||||||
|
|
||||||
|
def split7zLine(line):
|
||||||
|
arg = 0
|
||||||
|
args = []
|
||||||
|
argchars = ""
|
||||||
|
for c in line:
|
||||||
|
if arg == 5:
|
||||||
|
argchars = argchars + c
|
||||||
|
continue
|
||||||
|
if c in [" ","\t"]:
|
||||||
|
if argchars == "": continue
|
||||||
|
if arg == 0: # Date
|
||||||
|
if argchars.count("-") != 2: # Not a date, assume time is missing as well. Add both.
|
||||||
|
args.append("0000-00-00")
|
||||||
|
args.append("00:00:00")
|
||||||
|
arg += 2
|
||||||
|
|
||||||
|
args.append(argchars)
|
||||||
|
|
||||||
|
if arg == 2: # Attr
|
||||||
|
if argchars[0] == "D": # Is directory, insert 0 (compressed) size
|
||||||
|
args.append("0")
|
||||||
|
args.append("0")
|
||||||
|
arg += 2
|
||||||
|
|
||||||
|
argchars = ""
|
||||||
|
arg += 1
|
||||||
|
else:
|
||||||
|
argchars = argchars + c
|
||||||
|
|
||||||
|
if argchars != "":
|
||||||
|
args.append(argchars)
|
||||||
|
|
||||||
|
return args
|
||||||
|
|
||||||
|
def action_list(archiveFile,flags):
|
||||||
|
status = 0
|
||||||
|
for line in prochelper.pcallLines(["7z","l",archiveFile]):
|
||||||
|
if status == 0:
|
||||||
|
if line.lstrip(" \t").startswith("Date"):
|
||||||
|
status = 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
if status == 1:
|
||||||
|
status = 2
|
||||||
|
continue
|
||||||
|
|
||||||
|
if status == 2:
|
||||||
|
if line.startswith("-"): return
|
||||||
|
lineSplit = split7zLine(line)
|
||||||
|
|
||||||
|
apiFile = api.getDefaultFile()
|
||||||
|
apiFile["isdir"] = lineSplit[2].startswith("D")
|
||||||
|
apiFile["date"] = list(map(int,lineSplit[0].split("-")))
|
||||||
|
apiFile["time"] = list(map(int,lineSplit[1].split(":")))
|
||||||
|
apiFile["size"] = int(lineSplit[3])
|
||||||
|
apiFile["sizeCompressed"] = int(lineSplit[4])
|
||||||
|
apiFile["name"] = lineSplit[5]
|
||||||
|
|
||||||
|
apiFile["ownerGroup"] = -1
|
||||||
|
apiFile["ownerUser"] = -1
|
||||||
|
apiFile["permissions"] = "---------"
|
||||||
|
|
||||||
|
yield apiFile
|
||||||
|
|
||||||
|
def action_extract(archiveFile,flags):
|
||||||
|
import shutil
|
||||||
|
if flags["if"] == "":
|
||||||
|
prochelper.pcall(["7z","x",archiveFile,"-y","-aoa","-o" + flags["of"]])
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
tempdir = mfp.p(flags["of"],"7z." +str(os.getpid())+ ".tmp")
|
||||||
|
outdir = mfp.p(tempdir,mfp.pUp(flags["if"].replace("\\",os.path.sep).replace("/",os.path.sep)))
|
||||||
|
os.mkdir(tempdir)
|
||||||
|
prochelper.pcall(["7z","x",archiveFile,"-y","-aoa","-o" + tempdir,flags["if"]])
|
||||||
|
|
||||||
|
if os.path.isdir(outdir):
|
||||||
|
for root,dirs,files in os.walk(outdir):
|
||||||
|
for file in dirs:
|
||||||
|
ffile = mfp.p(root,file)
|
||||||
|
nfile = mfp.p(flags["of"],ffile.replace(outdir + os.path.sep,"",1))
|
||||||
|
if not os.path.isdir(nfile): os.mkdir(nfile)
|
||||||
|
|
||||||
|
for file in files:
|
||||||
|
ffile = mfp.p(root,file)
|
||||||
|
nfile = mfp.p(flags["of"],ffile.replace(outdir + os.path.sep,"",1))
|
||||||
|
if os.path.isfile(nfile): os.remove(nfile)
|
||||||
|
os.rename(ffile,nfile)
|
||||||
|
else:
|
||||||
|
nfile = mfp.p(flags["of"],outdir.replace(mfp.pUp(outdir) + os.path.sep,"",1))
|
||||||
|
if os.path.isfile(nfile): os.remove(nfile)
|
||||||
|
os.rename(outdir,nfile)
|
||||||
|
|
||||||
|
filehelper.rmtree(tempdir)
|
||||||
|
except:
|
||||||
|
filehelper.rmtree(tempdir)
|
||||||
|
raise
|
|
@ -0,0 +1,82 @@
|
||||||
|
import os
|
||||||
|
api = mfp.require("api")
|
||||||
|
prochelper = mfp.require("prochelper")
|
||||||
|
filehelper = mfp.require("filehelper")
|
||||||
|
|
||||||
|
def splitTarLine(line):
|
||||||
|
args = []
|
||||||
|
argchars = ""
|
||||||
|
arg = 0
|
||||||
|
for c in line:
|
||||||
|
if arg == 5:
|
||||||
|
argchars += c
|
||||||
|
continue
|
||||||
|
|
||||||
|
if c in [" ","\t"]:
|
||||||
|
if argchars != "":
|
||||||
|
args.append(argchars)
|
||||||
|
argchars = ""
|
||||||
|
continue
|
||||||
|
argchars = argchars + c
|
||||||
|
|
||||||
|
if argchars != "":
|
||||||
|
args.append(argchars)
|
||||||
|
|
||||||
|
return args
|
||||||
|
|
||||||
|
def action_list(archiveFile,flags):
|
||||||
|
status = 0
|
||||||
|
for line in prochelper.pcallLines(["tar","--numeric-owner","-tvf",archiveFile]):
|
||||||
|
if line.strip(" \t\r") == "": continue
|
||||||
|
lineSplit = splitTarLine(line)
|
||||||
|
|
||||||
|
apiFile = api.getDefaultFile()
|
||||||
|
apiFile["isdir"] = (lineSplit[0][0] == "d")
|
||||||
|
apiFile["date"] = list(map(int,lineSplit[3].split("-")))
|
||||||
|
apiFile["time"] = list(map(int,lineSplit[4].split(":"))) + [0]
|
||||||
|
apiFile["size"] = int(lineSplit[2])
|
||||||
|
apiFile["sizeCompressed"] = int(lineSplit[2])
|
||||||
|
if not apiFile["isdir"]:
|
||||||
|
apiFile["name"] = lineSplit[5]
|
||||||
|
else:
|
||||||
|
apiFile["name"] = lineSplit[5][:-1]
|
||||||
|
|
||||||
|
apiFile["ownerGroup"] = lineSplit[1].split("/")[0]
|
||||||
|
apiFile["ownerUser"] = lineSplit[1].split("/")[1]
|
||||||
|
apiFile["permissions"] = lineSplit[0][1:]
|
||||||
|
|
||||||
|
yield apiFile
|
||||||
|
|
||||||
|
def action_extract(archiveFile,flags):
|
||||||
|
import shutil
|
||||||
|
if flags["if"] == "":
|
||||||
|
prochelper.pcall(["tar","-xvf",archiveFile,"--overwrite","-C",flags["of"]])
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
tempdir = mfp.p(flags["of"],"tar." +str(os.getpid())+ ".tmp")
|
||||||
|
outdir = mfp.p(tempdir,mfp.pUp(flags["if"].replace("\\",os.path.sep).replace("/",os.path.sep)))
|
||||||
|
os.mkdir(tempdir)
|
||||||
|
prochelper.pcall(["tar","-xvf",archiveFile,"--overwrite","-C",tempdir,flags["if"]])
|
||||||
|
|
||||||
|
if os.path.isdir(outdir):
|
||||||
|
for root,dirs,files in os.walk(outdir):
|
||||||
|
for file in dirs:
|
||||||
|
ffile = mfp.p(root,file)
|
||||||
|
nfile = mfp.p(flags["of"],ffile.replace(outdir + os.path.sep,"",1))
|
||||||
|
if not os.path.isdir(nfile): os.mkdir(nfile)
|
||||||
|
|
||||||
|
for file in files:
|
||||||
|
ffile = mfp.p(root,file)
|
||||||
|
nfile = mfp.p(flags["of"],ffile.replace(outdir + os.path.sep,"",1))
|
||||||
|
if os.path.isfile(nfile): os.remove(nfile)
|
||||||
|
os.rename(ffile,nfile)
|
||||||
|
else:
|
||||||
|
nfile = mfp.p(flags["of"],outdir.replace(mfp.pUp(outdir) + os.path.sep,"",1))
|
||||||
|
if os.path.isfile(nfile): os.remove(nfile)
|
||||||
|
os.rename(outdir,nfile)
|
||||||
|
|
||||||
|
filehelper.rmtree(tempdir)
|
||||||
|
except:
|
||||||
|
filehelper.rmtree(tempdir)
|
||||||
|
raise
|
Loading…
Reference in New Issue