Я создаю GUI для приложения CLI, которое сжимает и извлекает файлы YAZ0 / SZS, и когда я пытаюсь сжать через GUI, я получаю это.
TypeError: '<' не поддерживается между экземплярами 'str' и 'int' </p>
Но когда я запускаю main.py через терминал с .\main.py -little -compress 3 -o compressed_dir.szs common/
, он работает нормально. Итак, исходя из этого, я предполагаю, что TypeError
происходит из-за GUI.py, но я не могу понять, что вызвало бы это.
Я считаю, что ошибка происходит в функции GUI_pack при выполнении функции pack из main.py.
Функция GUI_pack
def GUI_pack(src, out, endianness, compr_lvl):
try:
src = Path(src).resolve()
except FileNotFoundError:
messagebox.showerror("File Not Found", "The directory at " + src + " does not exist.")
return
try:
out = Path(out).resolve()
except FileNotFoundError:
messagebox.showerror("File Not Found", "The file at " + out + " does not exist.")
return
src = os.path.abspath(src)
pack(src, endianness, compr_lvl, out)
messagebox.showinfo("Finsihed", "Packing Complete\nSource: " + str(src) + "\nOutput: " + str(out))
функция main.py pack
def pack(root, endianness, level, outname):
"""
Pack the files and folders in the root folder.
"""
if "\\" in root:
root = "/".join(root.split("\\"))
if root[-1] == "/":
root = root[:-1]
arc = SarcLib.SARC_Archive(endianness=endianness)
lenroot = len(root.split("/"))
for path, dirs, files in os.walk(root):
if "\\" in path:
path = "/".join(path.split("\\"))
lenpath = len(path.split("/"))
if lenpath == lenroot:
path = ""
else:
path = "/".join(path.split("/")[lenroot - lenpath:])
for file in files:
if path:
filename = ''.join([path, "/", file])
else:
filename = file
print(filename)
fullname = ''.join([root, "/", filename])
i = 0
for folder in filename.split("/")[:-1]:
if not i:
exec("folder%i = SarcLib.Folder(folder + '/'); arc.addFolder(folder%i)".replace('%i', str(i)))
else:
exec("folder%i = SarcLib.Folder(folder + '/'); folder%m.addFolder(folder%i)".replace('%i', str(i)).replace('%m', str(i - 1)))
i += 1
with open(fullname, "rb") as f:
inb = f.read()
hasFilename = True
if file[:5] == "hash_":
hasFilename = False
if not i:
arc.addFile(SarcLib.File(file, inb, hasFilename))
else:
exec("folder%m.addFile(SarcLib.File(file, inb, hasFilename))".replace('%m', str(i - 1)))
data, maxAlignment = arc.save()
if level != -1:
outData = libyaz0.compress(data, maxAlignment, level)
del data
if not outname:
outname = ''.join([root, ".szs"])
else:
outData = data
if not outname:
outname = ''.join([root, ".sarc"])
with open(outname, "wb+") as output:
output.write(outData)
main.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# SARC Tool
# Version v0.4
# Copyright © 2017-2018 MasterVermilli0n / AboodXD
# This 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 3 of the License, or
# (at your option) any later version.
# This 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, see <http://www.gnu.org/licenses/>.
################################################################
################################################################
import os
import sys
import time
try:
import SarcLib
except ImportError:
print("SarcLib is not installed!")
ans = input("Do you want to install it now? (y/n)\t")
if ans.lower() == 'y':
import pip
pip.main(['install', 'SarcLib==0.2'])
del pip
import SarcLib
else:
sys.exit(1)
try:
import libyaz0
except ImportError:
print("libyaz0 is not installed!")
ans = input("Do you want to install it now? (y/n)\t")
if ans.lower() == 'y':
import pip
pip.main(['install', 'libyaz0==0.5'])
del pip
import libyaz0
else:
sys.exit(1)
def extract(file):
"""
Extrct the given archive
"""
with open(file, "rb") as inf:
inb = inf.read()
while libyaz0.IsYazCompressed(inb):
inb = libyaz0.decompress(inb)
name = os.path.splitext(file)[0]
ext = SarcLib.guessFileExt(inb)
if ext != ".sarc":
with open(''.join([name, ext]), "wb") as out:
out.write(inb)
else:
arc = SarcLib.SARC_Archive()
arc.load(inb)
root = os.path.join(os.path.dirname(file), name)
if not os.path.isdir(root):
os.mkdir(root)
files = []
def getAbsPath(folder, path):
nonlocal root
nonlocal files
for checkObj in folder.contents:
if isinstance(checkObj, SarcLib.File):
files.append(["/".join([path, checkObj.name]), checkObj.data])
else:
path_ = os.path.join(root, "/".join([path, checkObj.name]))
if not os.path.isdir(path_):
os.mkdir(path_)
getAbsPath(checkObj, "/".join([path, checkObj.name]))
for checkObj in arc.contents:
if isinstance(checkObj, SarcLib.File):
files.append([checkObj.name, checkObj.data])
else:
path = os.path.join(root, checkObj.name)
if not os.path.isdir(path):
os.mkdir(path)
getAbsPath(checkObj, checkObj.name)
for file, fileData in files:
print(file)
with open(os.path.join(root, file), "wb") as out:
out.write(fileData)
def pack(root, endianness, level, outname):
"""
Pack the files and folders in the root folder.
"""
if "\\" in root:
root = "/".join(root.split("\\"))
if root[-1] == "/":
root = root[:-1]
arc = SarcLib.SARC_Archive(endianness=endianness)
lenroot = len(root.split("/"))
for path, dirs, files in os.walk(root):
if "\\" in path:
path = "/".join(path.split("\\"))
lenpath = len(path.split("/"))
if lenpath == lenroot:
path = ""
else:
path = "/".join(path.split("/")[lenroot - lenpath:])
for file in files:
if path:
filename = ''.join([path, "/", file])
else:
filename = file
print(filename)
fullname = ''.join([root, "/", filename])
i = 0
for folder in filename.split("/")[:-1]:
if not i:
exec("folder%i = SarcLib.Folder(folder + '/'); arc.addFolder(folder%i)".replace('%i', str(i)))
else:
exec("folder%i = SarcLib.Folder(folder + '/'); folder%m.addFolder(folder%i)".replace('%i', str(i)).replace('%m', str(i - 1)))
i += 1
with open(fullname, "rb") as f:
inb = f.read()
hasFilename = True
if file[:5] == "hash_":
hasFilename = False
if not i:
arc.addFile(SarcLib.File(file, inb, hasFilename))
else:
exec("folder%m.addFile(SarcLib.File(file, inb, hasFilename))".replace('%m', str(i - 1)))
data, maxAlignment = arc.save()
if level != -1:
outData = libyaz0.compress(data, maxAlignment, level)
del data
if not outname:
outname = ''.join([root, ".szs"])
else:
outData = data
if not outname:
outname = ''.join([root, ".sarc"])
with open(outname, "wb+") as output:
output.write(outData)
def printInfo():
print("Usage:")
print(" main [option...] file/folder")
print("\nPacking Options:")
print(" -o <output> output file name (Optional)")
print(" -little output will be in little endian if this is used")
print(" -compress <level> Yaz0 (SZS) compress the output with the specified level(0-9) (1 is the default)")
print(" 0: No compression (Fastest)")
print(" 9: Best compression (Slowest)")
print("\nExiting in 5 seconds...")
time.sleep(5)
sys.exit(1)
def main():
print("SARC Tool v0.4")
print("(C) 2017-2018 MasterVermilli0n / AboodXD\n")
if len(sys.argv) < 2:
printInfo()
root = os.path.abspath(sys.argv[-1])
if os.path.isfile(root):
extract(root)
elif os.path.isdir(root):
endianness = '>'
level = -1
if "-little" in sys.argv:
endianness = '<'
if "-compress" in sys.argv:
try:
level = int(sys.argv[sys.argv.index("-compress") + 1], 0)
except ValueError:
level = 1
if not 0 <= level <= 9:
print("Invalid compression level!\n")
print("Exiting in 5 seconds...")
time.sleep(5)
sys.exit(1)
if "-o" in sys.argv:
outname = sys.argv[sys.argv.index("-o") + 1]
else:
outname = ""
pack(root, endianness, level, outname)
else:
print("File/Folder doesn't exist!")
print("\nExiting in 5 seconds...")
time.sleep(5)
sys.exit(1)
if __name__ == '__main__': main()
GUI.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# SARC Tool
# Version v0.4
# Copyright © 2017-2018 MasterVermilli0n / AboodXD
# GUI.py
# Author: Gigaboy-01 / Adam Oates
# Since: 5-15-2019
# This 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 3 of the License, or
# (at your option) any later version.
# This 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, see <http://www.gnu.org/licenses/>.
################################################################
################################################################
from main import extract
from main import pack
import platform
import sys
import time
import os
import shutil
from pathlib import Path
import tkinter as Tk
import tkinter.ttk as Ttk
from tkinter import filedialog
from tkinter import messagebox
# opens file dialog and sets an Tk.Entry object text to file source
def selFile(entryfield):
src = Tk.filedialog.askopenfilename(filetypes=[("SZS, SARC", "*.szs *.sarc")])
if src != None:
entryfield.delete(0, Tk.END)
entryfield.insert(0, src)
def saveFile(entryfield):
src = Tk.filedialog.asksaveasfilename(filetypes=[("SZS", "*.szs"),("SARC", "*.sarc")])
if src != None:
entryfield.delete(0, Tk.END)
entryfield.insert(0, src)
def selDir(entryfield):
src = Tk.filedialog.askdirectory()
if src != None:
entryfield.delete(0, Tk.END)
entryfield.insert(0, src)
# centers window on screen with X and Y offset
def center(win, offx=0, offy=0):
win.update_idletasks()
width = win.winfo_width()
height = win.winfo_height()
x = (win.winfo_screenwidth() // 2) - (width // 2)
y = (win.winfo_screenheight() // 2) - (height // 2)
win.geometry('{}x{}+{}+{}'.format(width, height, (x+offx), (y+offy)))
def GUI_extract(src, out):
try:
src = Path(src).resolve()
except FileNotFoundError:
messagebox.showerror("File Not Found", "The file at " + src + " does not exist.")
return
try:
out = Path(out).resolve()
except FileNotFoundError:
messagebox.showerror("File Not Found", "The directory at " + out + " does not exist.")
return
extract(src)
# if output directory is same directory as source, then we don't need to move the directory
if str(os.path.split(src)[0]) != str(out):
shutil.move(os.path.splitext(src)[0], out)
messagebox.showinfo("Finished", "Extraction Complete.\nSource: " + str(src) + "\nOutput: " + str(out))
def GUI_pack(src, out, endianness, compr_lvl):
try:
src = Path(src).resolve()
except FileNotFoundError:
messagebox.showerror("File Not Found", "The directory at " + src + " does not exist.")
return
try:
out = Path(out).resolve()
except FileNotFoundError:
messagebox.showerror("File Not Found", "The file at " + out + " does not exist.")
return
src = os.path.abspath(src)
pack(src, endianness, compr_lvl, out)
messagebox.showinfo("Finsihed", "Packing Complete\nSource: " + str(src) + "\nOutput: " + str(out))
def main():
# initialize variables
lbl_font = ("Times New Roman", 16)
# instantiates the primary window
primary = Tk.Tk()
primary.title("SARC Tool v0.4 GUI")
primary.resizable(False, False)
primary.option_add("*Dialog.msg.width", 600)
# configure styles
stl = Ttk.Style()
if platform.system() == "Windows":
stl.theme_use("vista")
elif platform.system() == "Darwin":
stl.theme_use("aqua")
elif platform.system == "Linux":
stl.theme_use("clam")
stl.configure("TButton",
padding=3,
font=("Calibri", 11, "italic", "bold"))
stl.configure("TEntry",
padding=[2, 1],
font=("Calibri", 11))
tabCtrl = Ttk.Notebook(primary)
########## EXTRACT FRAME START ##########
extract_frame = Ttk.Frame(tabCtrl)
# source Label
extract_src_lbl = Ttk.Label(extract_frame, text="Source File:", font=lbl_font)
extract_src_lbl.grid(row=0, column=0, sticky="W", padx=8, pady=(10, 0))
# source Entry
extract_src_entry = Ttk.Entry(extract_frame, width=55)
extract_src_entry.grid(row=1, column=0, padx=(10, 5), pady=3, ipady=3)
# source Button
extract_src_bttn = Ttk.Button(extract_frame, text="Select...", command=lambda: selFile(extract_src_entry))
extract_src_bttn.grid(row=1, column=1, padx=(5, 10), pady=3)
# output Label
extract_out_lbl = Ttk.Label(extract_frame, text="Output Directory:", font=lbl_font)
extract_out_lbl.grid(row=2, column=0, sticky="W", padx=8, pady=(10, 0))
# output Entry
extract_out_entry = Ttk.Entry(extract_frame, width=55)
extract_out_entry.grid(row=3, column=0, padx=(10, 5), pady=3, ipady=3)
#output Button
extract_out_bttn = Ttk.Button(extract_frame, text="Select...", command=lambda: selDir(extract_out_entry))
extract_out_bttn.grid(row=3, column=1, padx=(5, 10), pady=3)
# extract file button
extract_bttn = Ttk.Button(extract_frame, text="Extract", command=lambda: GUI_extract(extract_src_entry.get(), extract_out_entry.get()))
extract_bttn.grid(row=4, column=0, sticky="W", padx=10, pady=(3, 6))
########## EXTRACT FRAME END ##########
########## PACK FRAME START #########
pack_frame = Ttk.Frame(tabCtrl)
# source Label
pack_src_lbl = Ttk.Label(pack_frame, text="Source Directory:", font=lbl_font)
pack_src_lbl.grid(row=0, column=0, sticky="W", padx=8, pady=(10, 0))
# source Entry
pack_src_entry = Ttk.Entry(pack_frame, width=55)
pack_src_entry.grid(row=1, column=0, sticky="W", padx=(10, 5), pady=3, ipady=3)
# source Button
pack_src_bttn = Ttk.Button(pack_frame, text="Select...", command=lambda: selDir(pack_src_entry))
pack_src_bttn.grid(row=1, column=1, sticky="W", padx=(5, 10), pady=3)
# endianness Label
endianness_lbl = Ttk.Label(pack_frame, text="Console:", font=lbl_font)
endianness_lbl.grid(row=2, column=0, sticky="W", padx=8, pady=(10, 0))
pack_rb_val = Tk.StringVar(None, '<')
# Switch/3DS Radiobutton
endianness_switch3ds_rb = Ttk.Radiobutton(pack_frame, text="Switch/3DS", value='<', variable=pack_rb_val)
endianness_switch3ds_rb.grid(row=3, column=0, sticky="W", padx=8, pady=3)
# Wii U Radiobutton
endianness_wiiu_rb = Ttk.Radiobutton(pack_frame, text="Wii U", value='>', variable=pack_rb_val)
endianness_wiiu_rb.grid(row=4, column=0, sticky="W", padx=8, pady=3)
# compression level Label
compr_lvl_lbl = Ttk.Label(pack_frame, text="Compression [0 - fastest/largest; 9 - slowest/smallest]:", font=lbl_font)
compr_lvl_lbl.grid(row=5, column=0, columnspan=2, sticky="W", padx=8, pady=(10, 0))
# compression level Spinbox
compr_lvl_spnr = Ttk.Spinbox(pack_frame, from_=0, to=9, state="readonly", justify="center", font=("Serif", 11), width=10)
compr_lvl_spnr.grid(row=6, column=0, sticky="W", padx=(10, 5), pady=3)
# output Label
pack_out_lbl = Ttk.Label(pack_frame, text="Output File:", font=lbl_font)
pack_out_lbl.grid(row=7, column=0, sticky="W", padx=8, pady=(10, 0))
# output Entry
pack_out_entry = Ttk.Entry(pack_frame, width=55)
pack_out_entry.grid(row=8, column=0, sticky="W", padx=(10, 5), pady=3, ipady=3)
# output Button
pack_out_bttn = Ttk.Button(pack_frame, text="Select...", command=lambda: saveFile(pack_out_entry))
pack_out_bttn.grid(row=8, column=1, sticky="W", padx=(5, 10), pady=3)
# pack Button
pack_bttn = Ttk.Button(pack_frame, text="Pack", command=lambda: GUI_pack(pack_src_entry.get(), pack_out_entry.get(), pack_rb_val.get(), compr_lvl_spnr.get()))
pack_bttn.grid(row=9, column=0, sticky="W", padx=10, pady=(3, 6))
########## PACK FRAME END ###########
tabCtrl.add(extract_frame, text="Extract")
tabCtrl.add(pack_frame, text="Pack")
tabCtrl.pack(expand=True, fill="both")
center(primary, 0, -50)
Tk.mainloop()
if __name__ == '__main__':
main()