This commit is contained in:
Saifeddine ALOUI 2023-07-17 13:03:42 +02:00
parent 9568b79e1e
commit 89a52963fc
6 changed files with 182 additions and 61 deletions

67
app.py
View File

@ -123,6 +123,7 @@ class LoLLMsWebUI(LoLLMsAPPI):
self.add_endpoint("/reload_binding", "reload_binding", self.reload_binding, methods=["POST"]) self.add_endpoint("/reload_binding", "reload_binding", self.reload_binding, methods=["POST"])
self.add_endpoint("/update_software", "update_software", self.update_software, methods=["GET"]) self.add_endpoint("/update_software", "update_software", self.update_software, methods=["GET"])
self.add_endpoint("/clear_uploads", "clear_uploads", self.clear_uploads, methods=["GET"])
self.add_endpoint("/selectdb", "selectdb", self.selectdb, methods=["GET"]) self.add_endpoint("/selectdb", "selectdb", self.selectdb, methods=["GET"])
self.add_endpoint("/restart_program", "restart_program", self.restart_program, methods=["GET"]) self.add_endpoint("/restart_program", "restart_program", self.restart_program, methods=["GET"])
@ -198,6 +199,7 @@ class LoLLMsWebUI(LoLLMsAPPI):
self.add_endpoint("/", "", self.index, methods=["GET"]) self.add_endpoint("/", "", self.index, methods=["GET"])
self.add_endpoint("/<path:filename>", "serve_static", self.serve_static, methods=["GET"]) self.add_endpoint("/<path:filename>", "serve_static", self.serve_static, methods=["GET"])
self.add_endpoint("/user_infos/<path:filename>", "serve_user_infos", self.serve_user_infos, methods=["GET"])
self.add_endpoint("/images/<path:filename>", "serve_images", self.serve_images, methods=["GET"]) self.add_endpoint("/images/<path:filename>", "serve_images", self.serve_images, methods=["GET"])
self.add_endpoint("/bindings/<path:filename>", "serve_bindings", self.serve_bindings, methods=["GET"]) self.add_endpoint("/bindings/<path:filename>", "serve_bindings", self.serve_bindings, methods=["GET"])
@ -765,6 +767,14 @@ class LoLLMsWebUI(LoLLMsAPPI):
fn = filename.split("/")[-1] fn = filename.split("/")[-1]
return send_from_directory(path, fn) return send_from_directory(path, fn)
def serve_user_infos(self, filename):
path = str(self.lollms_paths.personal_user_infos_path/("/".join(filename.split("/")[:-1])))
fn = filename.split("/")[-1]
return send_from_directory(path, fn)
def serve_personalities(self, filename): def serve_personalities(self, filename):
path = str(self.lollms_paths.personalities_zoo_path/("/".join(filename.split("/")[:-1]))) path = str(self.lollms_paths.personalities_zoo_path/("/".join(filename.split("/")[:-1])))
@ -946,7 +956,44 @@ class LoLLMsWebUI(LoLLMsAPPI):
print(f"Couldn't build binding: [{ex}]") print(f"Couldn't build binding: [{ex}]")
return jsonify({"status":False, 'error':str(ex)}) return jsonify({"status":False, 'error':str(ex)})
def clear_uploads(self):
ASCIIColors.info("")
ASCIIColors.info("")
ASCIIColors.info("")
ASCIIColors.info(" ╔══════════════════════════════════════════════════╗")
ASCIIColors.info(" ║ Removing all uploads ║")
ASCIIColors.info(" ╚══════════════════════════════════════════════════╝")
ASCIIColors.info("")
ASCIIColors.info("")
ASCIIColors.info("")
try:
folder_path = self.lollms_paths.personal_uploads_path
# Iterate over all files and directories in the folder
for entry in folder_path.iterdir():
if entry.is_file():
# Remove file
entry.unlink()
elif entry.is_dir():
# Remove directory (recursively)
shutil.rmtree(entry)
print(f"All files and directories inside '{folder_path}' have been removed successfully.")
return {"status": True}
except OSError as e:
ASCIIColors.error(f"Couldn't clear the upload folder.\nMaybe some files are opened somewhere else.\Try doing it manually")
return {"status": False, 'error': "Couldn't clear the upload folder.\nMaybe some files are opened somewhere else.\Try doing it manually"}
def update_software(self): def update_software(self):
ASCIIColors.info("")
ASCIIColors.info("")
ASCIIColors.info("")
ASCIIColors.info(" ╔══════════════════════════════════════════════════╗")
ASCIIColors.info(" ║ Upgrading backend ║")
ASCIIColors.info(" ╚══════════════════════════════════════════════════╝")
ASCIIColors.info("")
ASCIIColors.info("")
ASCIIColors.info("")
# Perform a 'git pull' to check for updates # Perform a 'git pull' to check for updates
try: try:
# Execute 'git pull' and redirect the output to the console # Execute 'git pull' and redirect the output to the console
@ -981,10 +1028,17 @@ class LoLLMsWebUI(LoLLMsAPPI):
# Show file selection dialog # Show file selection dialog
file_path = filedialog.askopenfilename() file_path = filedialog.askopenfilename()
def restart_program(self): def restart_program(self):
ASCIIColors.info("Restarting backen ")
ASCIIColors.info("") ASCIIColors.info("")
ASCIIColors.info("Restarting backen ") ASCIIColors.info("")
ASCIIColors.info("")
ASCIIColors.info(" ╔══════════════════════════════════════════════════╗")
ASCIIColors.info(" ║ Restarting backend ║")
ASCIIColors.info(" ╚══════════════════════════════════════════════════╝")
ASCIIColors.info("")
ASCIIColors.info("")
ASCIIColors.info("")
python = sys.executable python = sys.executable
os.execl(python, python, *sys.argv) os.execl(python, python, *sys.argv)
@ -1573,6 +1627,15 @@ if __name__ == "__main__":
if arg_value is not None: if arg_value is not None:
config[arg_name] = arg_value config[arg_name] = arg_value
# Copy user
# Assuming the current file's directory contains the 'assets' subfolder
current_file_dir = Path(__file__).parent
assets_dir = current_file_dir / "assets"
default_user_avatar = assets_dir / "default_user.svg"
user_avatar_path = lollms_paths.personal_user_infos_path / "default_user.svg"
if not user_avatar_path.exists():
# If the user avatar doesn't exist, copy the default avatar from the assets folder
shutil.copy(default_user_avatar, user_avatar_path)
# executor = ThreadPoolExecutor(max_workers=1) # executor = ThreadPoolExecutor(max_workers=1)
# app.config['executor'] = executor # app.config['executor'] = executor
bot = LoLLMsWebUI(app, socketio, config, config.file_path, lollms_paths) bot = LoLLMsWebUI(app, socketio, config, config.file_path, lollms_paths)

32
assets/default_user.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 7.5 KiB

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,4 @@
.dot{width:10px;height:10px;border-radius:50%}.dot-green{background-color:green}.dot-red{background-color:red}.scrollbar[data-v-3cb88319]{scrollbar-width:thin;scrollbar-color:var(--scrollbar-thumb-color) var(--scrollbar-track-color);white-space:pre-wrap;overflow-wrap:break-word}.scrollbar[data-v-3cb88319]::-webkit-scrollbar{width:8px}.scrollbar[data-v-3cb88319]::-webkit-scrollbar-track{background-color:var(--scrollbar-track-color)}.scrollbar[data-v-3cb88319]::-webkit-scrollbar-thumb{background-color:var(--scrollbar-thumb-color);border-radius:4px}.scrollbar[data-v-3cb88319]::-webkit-scrollbar-thumb:hover{background-color:var(--scrollbar-thumb-hover-color)}.toastItem-enter-active[data-v-3ffdabf3],.toastItem-leave-active[data-v-3ffdabf3]{transition:all .5s ease}.toastItem-enter-from[data-v-3ffdabf3],.toastItem-leave-to[data-v-3ffdabf3]{opacity:0;transform:translate(-30px)}.list-move[data-v-cdb9dcf7],.list-enter-active[data-v-cdb9dcf7],.list-leave-active[data-v-cdb9dcf7]{transition:all .5s ease}.list-enter-from[data-v-cdb9dcf7]{transform:translatey(-30px)}.list-leave-to[data-v-cdb9dcf7]{opacity:0;transform:translatey(30px)}.list-leave-active[data-v-cdb9dcf7]{position:absolute}.bounce-enter-active[data-v-cdb9dcf7]{animation:bounce-in-cdb9dcf7 .5s}.bounce-leave-active[data-v-cdb9dcf7]{animation:bounce-in-cdb9dcf7 .5s reverse}@keyframes bounce-in-cdb9dcf7{0%{transform:scale(0)}50%{transform:scale(1.25)}to{transform:scale(1)}}.bg-primary-light[data-v-cdb9dcf7]{background-color:#0ff}.hover[data-v-cdb9dcf7]:bg-primary-light:hover{background-color:#7fffd4}.font-bold[data-v-cdb9dcf7]{font-weight:700}.hljs-comment,.hljs-quote{color:#7285b7}.hljs-deletion,.hljs-name,.hljs-regexp,.hljs-selector-class,.hljs-selector-id,.hljs-tag,.hljs-template-variable,.hljs-variable{color:#ff9da4}.hljs-built_in,.hljs-link,.hljs-literal,.hljs-meta,.hljs-number,.hljs-params,.hljs-type{color:#ffc58f}.hljs-attribute{color:#ffeead}.hljs-addition,.hljs-bullet,.hljs-string,.hljs-symbol{color:#d1f1a9}.hljs-section,.hljs-title{color:#bbdaff}.hljs-keyword,.hljs-selector-tag{color:#ebbbff}.hljs{background:#002451;color:#fff}pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*! .dot{width:10px;height:10px;border-radius:50%}.dot-green{background-color:green}.dot-red{background-color:red}.scrollbar[data-v-3cb88319]{scrollbar-width:thin;scrollbar-color:var(--scrollbar-thumb-color) var(--scrollbar-track-color);white-space:pre-wrap;overflow-wrap:break-word}.scrollbar[data-v-3cb88319]::-webkit-scrollbar{width:8px}.scrollbar[data-v-3cb88319]::-webkit-scrollbar-track{background-color:var(--scrollbar-track-color)}.scrollbar[data-v-3cb88319]::-webkit-scrollbar-thumb{background-color:var(--scrollbar-thumb-color);border-radius:4px}.scrollbar[data-v-3cb88319]::-webkit-scrollbar-thumb:hover{background-color:var(--scrollbar-thumb-hover-color)}.toastItem-enter-active[data-v-3ffdabf3],.toastItem-leave-active[data-v-3ffdabf3]{transition:all .5s ease}.toastItem-enter-from[data-v-3ffdabf3],.toastItem-leave-to[data-v-3ffdabf3]{opacity:0;transform:translate(-30px)}.list-move[data-v-ec3927a6],.list-enter-active[data-v-ec3927a6],.list-leave-active[data-v-ec3927a6]{transition:all .5s ease}.list-enter-from[data-v-ec3927a6]{transform:translatey(-30px)}.list-leave-to[data-v-ec3927a6]{opacity:0;transform:translatey(30px)}.list-leave-active[data-v-ec3927a6]{position:absolute}.bounce-enter-active[data-v-ec3927a6]{animation:bounce-in-ec3927a6 .5s}.bounce-leave-active[data-v-ec3927a6]{animation:bounce-in-ec3927a6 .5s reverse}@keyframes bounce-in-ec3927a6{0%{transform:scale(0)}50%{transform:scale(1.25)}to{transform:scale(1)}}.bg-primary-light[data-v-ec3927a6]{background-color:#0ff}.hover[data-v-ec3927a6]:bg-primary-light:hover{background-color:#7fffd4}.font-bold[data-v-ec3927a6]{font-weight:700}.hljs-comment,.hljs-quote{color:#7285b7}.hljs-deletion,.hljs-name,.hljs-regexp,.hljs-selector-class,.hljs-selector-id,.hljs-tag,.hljs-template-variable,.hljs-variable{color:#ff9da4}.hljs-built_in,.hljs-link,.hljs-literal,.hljs-meta,.hljs-number,.hljs-params,.hljs-type{color:#ffc58f}.hljs-attribute{color:#ffeead}.hljs-addition,.hljs-bullet,.hljs-string,.hljs-symbol{color:#d1f1a9}.hljs-section,.hljs-title{color:#bbdaff}.hljs-keyword,.hljs-selector-tag{color:#ebbbff}.hljs{background:#002451;color:#fff}pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*!
Theme: Tokyo-night-Dark Theme: Tokyo-night-Dark
origin: https://github.com/enkia/tokyo-night-vscode-theme origin: https://github.com/enkia/tokyo-night-vscode-theme
Description: Original highlight.js style Description: Original highlight.js style

4
web/dist/index.html vendored
View File

@ -6,8 +6,8 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>LoLLMS WebUI - Welcome</title> <title>LoLLMS WebUI - Welcome</title>
<script type="module" crossorigin src="/assets/index-ad06c29f.js"></script> <script type="module" crossorigin src="/assets/index-5eee0659.js"></script>
<link rel="stylesheet" href="/assets/index-7a82d60e.css"> <link rel="stylesheet" href="/assets/index-bec8b3bc.css">
</head> </head>
<body> <body>
<div id="app"></div> <div id="app"></div>

View File

@ -610,7 +610,7 @@
<label for="user_name" class="text-sm font-bold" style="margin-right: 1rem;">User avatar:</label> <label for="user_name" class="text-sm font-bold" style="margin-right: 1rem;">User avatar:</label>
</td> </td>
<td style="width: 100%;"> <td style="width: 100%;">
<img :src="avatar"> <img :src="user_avatar">
</td> </td>
<td style="min-width: 300px;"> <td style="min-width: 300px;">
<button <button
@ -643,18 +643,35 @@
Validate Validate
</button> </button>
</td> </td>
</tr> </tr>
<!-- Row 0 -->
<tr class="w-full">
<button
class="hover:text-secondary w-full bg-red-100 m-2 p-2 duration-75 flex justify-center w-full hover:bg-bg-light-tone hover:dark:bg-bg-dark-tone rounded-lg"
@click="api_get_req('restart_program').then((res)=>{this.$refs.toast.showToast('Success!', 4, true)})"
>
Restart program
</button>
</tr>
</table> </table>
<!-- Row 0 -->
<div class="w-full">
<button
class="hover:text-secondary w-full bg-red-100 m-2 p-2 duration-75 flex justify-center w-full hover:bg-bg-light-tone hover:dark:bg-bg-dark-tone rounded-lg"
@click="api_get_req('clear_uploads').then((res)=>{if(res.status){this.$refs.toast.showToast('Success!', 4, true)}else{this.$refs.toast.showToast(['failed!'], 4, false)}})"
>
Clear uploads
</button>
</div>
<div class="w-full">
<button
class="hover:text-secondary w-full bg-red-100 m-2 p-2 duration-75 flex justify-center w-full hover:bg-bg-light-tone hover:dark:bg-bg-dark-tone rounded-lg"
@click="api_get_req('restart_program').then((res)=>{if(res.status){this.$refs.toast.showToast('Success!', 4, true)}else{this.$refs.toast.showToast(['failed!'], 4, false)}})"
>
Restart program
</button>
</div>
<!-- Row 0 -->
<div class="w-full">
<button
class="hover:text-secondary w-full bg-red-100 m-2 p-2 duration-75 flex justify-center w-full hover:bg-bg-light-tone hover:dark:bg-bg-dark-tone rounded-lg"
@click="api_get_req('update_software').then((res)=>{if(res.status){this.$refs.toast.showToast('Success!', 4, true)}else{this.$refs.toast.showToast('Success!', 4, true)}})"
>
Upgrade program
</button>
</div>
@ -2785,6 +2802,15 @@ export default {
this.$store.state.config.user_name = value this.$store.state.config.user_name = value
}, },
}, },
user_avatar:{
get() {
return "/user_infos/"+this.$store.state.config.user_avatar;
},
set(value) {
// You should not set the value directly here; use the updateSetting method instead
this.$store.state.config.user_avatar = value
},
},
auto_update:{ auto_update:{
get() { get() {
return this.$store.state.config.auto_update; return this.$store.state.config.auto_update;