Skip to content

Dev alphav1.3.2 E1 #14

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -130,3 +130,5 @@ dmypy.json

.vscode
.vscode/*

alias.user.conf
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ Ice Shell(简称IShell,中文名“冰壳”),是一个Python编写的

**2024,回归更新咕咕咕!**

![Run Shell](./docs/img/runShell.png)

(老版图片)



## IShell设计初衷
往往我们在用Python完成某个小功能时,我们都会直接新建单个Python文件,写完之后就放在一个不知名的小角落,然后使用的时候直接双击运行。

Expand Down Expand Up @@ -95,6 +101,7 @@ IShell本质上作为一个模块化Shell,装载了一些小工具。
- 报错易寻找具体位置
......


# 使用方法

1. 下载最新版Release [点我前往Release](https://github.com/lanbinshijie/IceShell/releases)
Expand All @@ -121,13 +128,20 @@ Demo输出

![Demo Screen](./docs/img/bashDemo.png)

## Star History

[![Star History Chart](https://api.star-history.com/svg?repos=lanbinshijie/iceshell&type=Date)](https://star-history.com/#lanbinshijie/iceshell&Date)



# 参与开发

您可以联系我的
- 邮箱:[[email protected]](mailto:[email protected])

或者直接提交issue


## 近期任务

- [X] 一键检测依赖并询问是否安装
Expand Down
58 changes: 54 additions & 4 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,37 +14,87 @@
from tools.Phraser import PS1
from tools.Phraser import alias
from misc.Info import StartAction
from tools.Configure import *
# from models.bash import Ish



ALIAS = alias()
PS1O = PS1()
CONFIGURATION = Configuration()
# ish = Ish()

def ExecuteModel(args, moduleName):
if SelfCheck.CheckModel(moduleName):
os.chdir(rf"{ProgramInfo.basedir}/models")
if os.path.exists(f"{moduleName}.py"):
command = sys.executable + f" ./{moduleName}.py " + args
command = f"\"{sys.executable}\"" + f" ./{moduleName}.py " + args
elif os.path.exists(f"./{moduleName}/main.py"):
os.chdir(rf"./{moduleName}")
command = sys.executable + f" ./main.py " + args
command = f"\"{sys.executable}\"" + f" ./main.py " + args
else:
if ALIAS.exsist(moduleName):
command = ALIAS.get(moduleName)
command = sys.executable + f" ./{command}.py " + args
command = f"\"{sys.executable}\"" + f" ./{command}.py " + args
os.system(command)
os.chdir(rf"{ProgramInfo.basedir}")
# elif moduleName in
else:
# 因为 checkModel 会给出提示信息,所以就不用给出了
...

def SafetyMode(lock):
if int(lock):
print(Colors.RED + Logo.div_line_n_m + Colors.END)
print(Colors.RED + "Safety Mode is on." + Colors.END)
print(Colors.RED + "Please input your password to continue." + Colors.END)
print(Colors.RED + Logo.div_line_n_m + Colors.END + "\n")

while True:
try:
userName = input("Username: >> ")
password = input("Password: >> ")
passwordHashed = Hash(password)
if userName == CONFIGURATION.userName and passwordHashed == str(CONFIGURATION.passwordHashed).split("%%")[0]:
print()
print(Colors.GREEN + Logo.div_line_n_m + Colors.END)
print(Colors.GREEN + "Welcome back, " + userName + "!" + Colors.END)
print(Colors.GREEN + Logo.div_line_n_m + Colors.END + "\n")
break
else:
print()
print(Colors.RED + Logo.div_line_n_m + Colors.END)
print(Colors.RED + "Wrong username or password!" + Colors.END)
print(Colors.RED + Logo.div_line_n_m + Colors.END + "\n")
continue
except KeyboardInterrupt:
print("\nBye~")
exit(0)

def IceShell():
extra = ""
commandN = input(Colors.RED + extra + PS1.paraphraser() + Colors.END)
command = commandN.split(" ")
SECLEVEL = 0
if command[0] == "q":
print("Bye~")
exit(0)
elif CONFIGURATION.ifexist(str(commandN.split("=")[0]).strip()[1:]) and commandN.startswith("$"):
conf = commandN.split("=")
conf = [str(item).strip() for item in conf]
conf[0] = conf[0][1:]
sec = CONFIGURATION.get(conf[0]).split("%%") # 安全等级,如果越大,需要的等级越高
sec = int(sec[1]) if len(sec) > 1 else 0
if sec > SECLEVEL:
Error.printError(30001)
print()
return
if len(conf) == 2:
CONFIGURATION.set_value(conf[0], conf[1])
CONFIGURATION.save()
print(Colors.GREEN + "Configuration saved." + Colors.END)
elif len(conf) == 1:
print(CONFIGURATION.get(conf[0]))
elif command[0] in ProgramInfo.registered_modules or "*" in ProgramInfo.registered_modules:
ExecuteModel(" ".join(command[1:]), command[0])
else:
Expand All @@ -62,7 +112,7 @@ def IceShell():
if os.path.exists(mfol_stp):
ExecuteModel(mdls_stp, "bash")
print(Colors.BLUE + Logo.div_line_n_m + Colors.END + "\n")

pass_ = SafetyMode(CONFIGURATION.lock)
while True:
try:
IceShell()
Expand Down
6 changes: 6 additions & 0 deletions misc/Error.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ class Error:
"title": "Deleting error!",
"solve": "Please check pip\'s environment"
},
30001: {
"typer": "error",
"model": "SECURITY",
"title": "PERMISSION DENIED!",
"solve": "UPGRADE YOUR PERMISSION"
},
}
def printError(code: int):
err = Error.error_list[code]
Expand Down
2 changes: 1 addition & 1 deletion misc/Info.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class ProgramInfo:
# Program Version
version = "v1.0.0-alphav1.2.1"
author = "Lanbin"
using_libs = ["os", "sys"]
using_libs = ["os", "sys", "re"]
models_path = r"./models/"
registered_modules = ["print", "downlib", "dellib", "scan", "models", "shell", "alias", "bash", "*"]
debug_mode = True
Expand Down
33 changes: 22 additions & 11 deletions models/alias.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,27 +13,38 @@ class Aliaser:
"""
This class manages command aliases stored in a configuration file.
"""
def __init__(self, path=ProgramInfo.basedir + "/tools/alias.conf"):
def __init__(self, path=ProgramInfo.basedir + "/tools/alias.conf", userPath=ProgramInfo.basedir + "/tools/alias.user.conf"):
self.path = path
self.userPath = userPath
self.alias = alias(path)

def _update_file(self, config):
def _update_file(self, config, user=True):
"""Writes the updated configuration to the file."""
with open(self.path, "w") as f:
for alias, command in config.items():
f.write(f"{alias}={command}\n")
if user:
with open(self.userPath, "w") as f:
for alias, command in config.items():
f.write(f"{alias}={command}\n")
else:
with open(self.path, "w") as f:
for alias, command in config.items():
f.write(f"{alias}={command}\n")

def add(self, alias, command):
def add(self, alias, command, user=True):
"""Adds a new alias."""
if self.alias.exist(alias):
if self.alias.exsist(alias):
print(f"Alias {alias} already exists!")
return
with open(self.path, "a") as f:
f.write(f"\n{alias}={command}")

if user:
with open(self.userPath, "a") as f:
f.write(f"\n{alias}={command}")
else:
with open(self.path, "a") as f:
f.write(f"\n{alias}={command}")

def set(self, alias, command):
"""Sets an existing alias to a new command."""
if not self.alias.exist(alias):
if not self.alias.exsist(alias):
print(f"Alias {alias} does not exist!")
return
config = self.alias.getAll()
Expand All @@ -42,7 +53,7 @@ def set(self, alias, command):

def delete(self, alias):
"""Deletes an existing alias."""
if not self.alias.exist(alias):
if not self.alias.exsist(alias):
print(f"Alias {alias} does not exist!")
return
config = self.alias.getAll()
Expand Down
124 changes: 124 additions & 0 deletions tools/Configure.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
from misc.Info import ProgramInfo
import hashlib

def Hash(password: str, salt: str = "IceShell"):
return hashlib.sha256((password + salt).encode("utf-8")).hexdigest()

class ConfigurationData:
def __init__(self, userName="root", passwordHashed=Hash("root"), config={}):
self.userName = userName
self.passwordHashed = passwordHashed

self.variables = []

self.config = config
self.phrase()
if self.config is not {}:
self.loadConfig(config)
self.updateVarList()

def phrase(self):
# 设置config内容
self.config = {
"userName": self.userName, # 设置用户名
"passwordHashed": self.passwordHashed, # 设置密码
"lock": "0",
"variables": self.variables,
}
self.updateVarList()

def updateVarList(self):
# self.variables设置为config的key
self.variables = []
for key in self.config.keys():
self.variables.append(key)
self.config["variables"] = self.variables


def loadConfig(self, config):
# 传入的config是configuration读取的key=value
for key, value in config.items():
self.config[key] = value
return self.config

def setKeyValue(self, key: str, value):
# 设置key的值为value
self.config[key] = value

def __call__(self):
return self.config

def update_internal_attributes(self, key, value):
if hasattr(self, key):
setattr(self, key, value)

class Configuration:
def __init__(self, configPath=ProgramInfo.basedir + "/tools/configure.conf", configurationData: ConfigurationData | None = None):
self.__dict__['configPath'] = configPath
if configurationData is None:
self.readConfig(configPath)
else:
self.__dict__['config'] = configurationData
self.save()

def readConfig(self, configPath):
# 数据格式:key=value
# 读取配置文件,然后创建一个ConfigurationData数据,尝试填入数据
try:
with open(configPath, "r", encoding="utf-8") as f:
config = f.read().split("\n")
# 删除所有config为空或者没有等号在中间的行
config = [line for line in config if "=" in line]

config = {
key: value for key, value in [line.split("=") for line in config]
}
self.config = ConfigurationData(config=config)
except FileNotFoundError as e:
print(e)
self.config = ConfigurationData()
except Exception as e:
print(e)
self.config = ConfigurationData()


def get(self, name):
return self.config()[name]

def __call__(self):
return self.config()

def __getattr__(self, name):
if 'config' in self.__dict__:
return self.__dict__['config']()[name]
else:
raise AttributeError(f"No such attribute: {name}")

def __setattr__(self, name, value):
if name in ['config', 'configPath'] or '_config' not in self.__dict__:
self.__dict__[name] = value
elif name in self.__dict__['config']():
self.__dict__['config'].setKeyValue(name, value)
self.__dict__['config'].update_internal_attributes(name, value)
else:
object.__setattr__(self, name, value)
def save(self):
with open(self.configPath, "w", encoding="utf-8") as f:
for key, value in self.config().items():
value = str(value)
f.write(key + "=" + value + "\n")
f.flush()

def ifexist(self, configKey):
if configKey in self.config():
return True
else:
return False

def set_value(self, key, value):
if key in self.config():
self.config.setKeyValue(key, value)
self.config.update_internal_attributes(key, value)
else:
raise KeyError(f"No such configuration key: {key}")

24 changes: 18 additions & 6 deletions tools/Phraser.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,17 @@ def paraphraser(prompt="[IShell] %u> "):
return prompt

class alias:
def __init__(self, path=ProgramInfo.basedir + "/tools/alias.conf"):
with open(path, "r") as f:
conf = f.read()
def __init__(self, path=ProgramInfo.basedir + "/tools/alias.conf", userPath=ProgramInfo.basedir + "/tools/alias.user.conf", user=True):
if user:
try:
with open(userPath, "r") as f:
conf = f.read()
except:
with open(path, "r") as f:
conf = f.read()
else:
with open(path, "r") as f:
conf = f.read()

conf = conf.split("\n")
self.conf_dict = {}
Expand All @@ -44,9 +52,13 @@ def getAll(self):
self.reRead()
return self.conf_dict

def reRead(self, path="../tools/alias.conf"):
with open(path, "r") as f:
conf = f.read()
def reRead(self, path="../tools/alias.conf", userPath="../tools/alias.user.conf", user=True):
if user:
with open(userPath, "r") as f:
conf = f.read()
else:
with open(path, "r") as f:
conf = f.read()

conf = conf.split("\n")
self.conf_dict = {}
Expand Down
4 changes: 4 additions & 0 deletions tools/configure.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
userName=Lanbin
passwordHashed=8ac8c452cf1deb9785b4d8a3a778f5b8d80a096f8acc9968b4e54234881a4463%%1
lock=0
variables=['userName', 'passwordHashed', 'lock', 'variables']