mirror of
https://github.com/ParisNeo/lollms-webui.git
synced 2024-12-23 14:22:22 +00:00
Merge branch 'lollms' into pers-mount
This commit is contained in:
commit
56051816d9
@ -294,13 +294,14 @@ class ModelProcess:
|
|||||||
elif len(failed_personalities)>0:
|
elif len(failed_personalities)>0:
|
||||||
self._set_config_result['status'] ='semi_failed'
|
self._set_config_result['status'] ='semi_failed'
|
||||||
self._set_config_result['personalities_status'] ='semi_failed'
|
self._set_config_result['personalities_status'] ='semi_failed'
|
||||||
|
|
||||||
if self.config['active_personality_id']<len(self.mounted_personalities):
|
if self.config['active_personality_id']<len(self.mounted_personalities):
|
||||||
self.personality = self.mounted_personalities[self.config['active_personality_id']]
|
self.personality = self.mounted_personalities[self.config['active_personality_id']]
|
||||||
ASCIIColors.success("Personality set successfully")
|
ASCIIColors.success("Personality set successfully")
|
||||||
else:
|
else:
|
||||||
|
|
||||||
ASCIIColors.error("Failed to set personality. Please select a valid one")
|
ASCIIColors.error("Failed to set personality. Please select a valid one")
|
||||||
|
|
||||||
def _run(self):
|
def _run(self):
|
||||||
self._rebuild_model()
|
self._rebuild_model()
|
||||||
self._rebuild_personalities()
|
self._rebuild_personalities()
|
||||||
@ -476,7 +477,10 @@ class LoLLMsAPPI():
|
|||||||
self.config = config
|
self.config = config
|
||||||
self.binding = self.process.rebuild_binding(self.config)
|
self.binding = self.process.rebuild_binding(self.config)
|
||||||
self.mounted_personalities = self.process.rebuild_personalities()
|
self.mounted_personalities = self.process.rebuild_personalities()
|
||||||
self.personality = self.mounted_personalities[self.config["active_personality_id"]]
|
if self.config["active_personality_id"]<len(self.mounted_personalities):
|
||||||
|
self.personality = self.mounted_personalities[self.config["active_personality_id"]]
|
||||||
|
else:
|
||||||
|
self.personality = None
|
||||||
if config["debug"]:
|
if config["debug"]:
|
||||||
print(print(f"{self.personality}"))
|
print(print(f"{self.personality}"))
|
||||||
self.config_file_path = config_file_path
|
self.config_file_path = config_file_path
|
||||||
|
27
app.py
27
app.py
@ -1109,8 +1109,7 @@ def sync_cfg(default_config, config):
|
|||||||
return config, added_entries, removed_entries
|
return config, added_entries, removed_entries
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
lollms_paths = LollmsPaths.find_paths(force_local=True, custom_default_cfg_path="configs/config.yaml")
|
||||||
lollms_paths = LollmsPaths.find_paths(force_local=True)
|
|
||||||
db_folder = lollms_paths.personal_path/"databases"
|
db_folder = lollms_paths.personal_path/"databases"
|
||||||
db_folder.mkdir(parents=True, exist_ok=True)
|
db_folder.mkdir(parents=True, exist_ok=True)
|
||||||
parser = argparse.ArgumentParser(description="Start the chatbot Flask app.")
|
parser = argparse.ArgumentParser(description="Start the chatbot Flask app.")
|
||||||
@ -1181,26 +1180,8 @@ if __name__ == "__main__":
|
|||||||
)
|
)
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
# The default configuration must be kept unchanged as it is committed to the repository,
|
# Configuration loading part
|
||||||
# so we have to make a copy that is not comitted
|
config = LOLLMSConfig.autoload(lollms_paths)
|
||||||
default_config = load_config("configs/config.yaml")
|
|
||||||
|
|
||||||
if args.config!="local_config":
|
|
||||||
args.config = "local_config"
|
|
||||||
if not lollms_paths.personal_configuration_path/f"local_config.yaml".exists():
|
|
||||||
print("No local configuration file found. Building from scratch")
|
|
||||||
shutil.copy(default_config, lollms_paths.personal_configuration_path/f"local_config.yaml")
|
|
||||||
|
|
||||||
config_file_path = lollms_paths.personal_configuration_path/f"local_config.yaml"
|
|
||||||
config = LOLLMSConfig(config_file_path)
|
|
||||||
|
|
||||||
|
|
||||||
if "version" not in config or int(config["version"])<int(default_config["version"]):
|
|
||||||
#Upgrade old configuration files to new format
|
|
||||||
ASCIIColors.error("Configuration file is very old.\nReplacing with default configuration")
|
|
||||||
config, added, removed = sync_cfg(default_config, config)
|
|
||||||
print(f"Added entries : {added}, removed entries:{removed}")
|
|
||||||
config.save_config(config_file_path)
|
|
||||||
|
|
||||||
# Override values in config with command-line arguments
|
# Override values in config with command-line arguments
|
||||||
for arg_name, arg_value in vars(args).items():
|
for arg_name, arg_value in vars(args).items():
|
||||||
@ -1209,7 +1190,7 @@ if __name__ == "__main__":
|
|||||||
|
|
||||||
# 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)
|
||||||
|
|
||||||
# chong Define custom WebSocketHandler with error handling
|
# chong Define custom WebSocketHandler with error handling
|
||||||
class CustomWebSocketHandler(WebSocketHandler):
|
class CustomWebSocketHandler(WebSocketHandler):
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# =================== Lord Of Large Language Models Configuration file ===========================
|
# =================== Lord Of Large Language Models Configuration file ===========================
|
||||||
version: 7
|
version: 7
|
||||||
binding_name: llama_cpp_official
|
binding_name: llama_cpp_official
|
||||||
model_name: Wizard-Vicuna-7B-Uncensored.ggmlv3.q4_0.bin
|
model_name: airoboros-13b-gpt4.ggmlv3.q4_0.bin
|
||||||
|
|
||||||
# Host information
|
# Host information
|
||||||
host: localhost
|
host: localhost
|
||||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
4
web/dist/index.html
vendored
4
web/dist/index.html
vendored
@ -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>GPT4All - WEBUI</title>
|
<title>GPT4All - WEBUI</title>
|
||||||
<script type="module" crossorigin src="/assets/index-ce2e3117.js"></script>
|
<script type="module" crossorigin src="/assets/index-9b72f28e.js"></script>
|
||||||
<link rel="stylesheet" href="/assets/index-29d93ec2.css">
|
<link rel="stylesheet" href="/assets/index-4e1807f7.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
|
1
web/src/clip
Submodule
1
web/src/clip
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit a9b1bf5920416aaeaec965c25dd9e8f98c864f16
|
@ -0,0 +1,74 @@
|
|||||||
|
<template>
|
||||||
|
<div v-if="show" class="fixed top-0 left-0 right-0 bottom-0 flex items-center justify-center bg-black bg-opacity-50">
|
||||||
|
<div class="relative w-full max-w-md max-h-full">
|
||||||
|
<div class="relative bg-white rounded-lg shadow dark:bg-gray-700">
|
||||||
|
<button type="button" @click="hide(false)"
|
||||||
|
class="absolute top-3 right-2.5 text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm p-1.5 ml-auto inline-flex items-center dark:hover:bg-gray-800 dark:hover:text-white">
|
||||||
|
<svg aria-hidden="true" class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20"
|
||||||
|
xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path fill-rule="evenodd"
|
||||||
|
d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z"
|
||||||
|
clip-rule="evenodd"></path>
|
||||||
|
</svg>
|
||||||
|
<span class="sr-only">Close modal</span>
|
||||||
|
</button>
|
||||||
|
<div class="p-4 text-center">
|
||||||
|
<svg aria-hidden="true" class="mx-auto mb-4 text-gray-400 w-14 h-14 dark:text-gray-200" fill="none"
|
||||||
|
stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
<div class="p-4 text-center mx-auto mb-4">
|
||||||
|
<label class="mr-2">Model path</label>
|
||||||
|
<input v-model="model_path" class="px-4 py-2 border border-gray-300 rounded-lg" type="text" />
|
||||||
|
</div>
|
||||||
|
<button @click="hide(true)" type="button"
|
||||||
|
class="text-white bg-green-600 hover:bg-green-800 focus:ring-4 focus:outline-none focus:ring-red-300 dark:focus:ring-red-800 font-medium rounded-lg text-sm inline-flex items-center px-5 py-2.5 text-center mr-2">
|
||||||
|
Add
|
||||||
|
</button>
|
||||||
|
<button @click="hide(false)" type="button"
|
||||||
|
class="text-gray-500 bg-white hover:bg-gray-100 focus:ring-4 focus:outline-none focus:ring-gray-200 rounded-lg border border-gray-200 text-sm font-medium px-5 py-2.5 hover:text-gray-900 focus:z-10 dark:bg-gray-700 dark:text-gray-300 dark:border-gray-500 dark:hover:text-white dark:hover:bg-gray-600 dark:focus:ring-gray-600">No,
|
||||||
|
cancel</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
show: false,
|
||||||
|
model_path: "",
|
||||||
|
resolve: null,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
cancel() {
|
||||||
|
this.resolve(null);
|
||||||
|
},
|
||||||
|
openInputBox() {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
this.resolve = resolve;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
hide(response) {
|
||||||
|
this.show = false;
|
||||||
|
if (this.resolve) {
|
||||||
|
this.resolve(response);
|
||||||
|
this.resolve = null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
showDialog(model_path) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
this.model_path = model_path;
|
||||||
|
this.show = true;
|
||||||
|
this.resolve = resolve;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
@ -226,20 +226,18 @@
|
|||||||
|
|
||||||
<div v-if="configFile.model_name" class="mr-2">|</div>
|
<div v-if="configFile.model_name" class="mr-2">|</div>
|
||||||
|
|
||||||
<div v-if="configFile.model_name"
|
<div v-if="configFile.model_name" class="text-base font-semibold cursor-pointer select-none items-center">
|
||||||
class="text-base font-semibold cursor-pointer select-none items-center">
|
<div class="flex gap-1 items-center">
|
||||||
<div class="flex gap-1 items-center">
|
<img :src="imgModel" class="w-8 h-8 rounded-lg object-fill">
|
||||||
<img :src="imgModel" class="w-8 h-8 rounded-lg object-fill">
|
<h3 class="font-bold font-large text-lg line-clamp-1">
|
||||||
<h3 class="font-bold font-large text-lg line-clamp-1">
|
{{ configFile.model_name }}
|
||||||
{{ configFile.model_name }}
|
</h3>
|
||||||
</h3>
|
<button @click.stop="showAddModelDialog" class="text-base hover:text-primary-dark ml-1 bg-bg-light-tone dark:bg-bg-dark-tone hover:bg-bg-dark-tone duration-200 rounded-lg px-2 py-1">
|
||||||
<button @click.stop="showInputDialog"
|
+
|
||||||
class="text-base hover:text-primary-dark ml-1 bg-bg-light-tone dark:bg-bg-dark-tone hover:bg-bg-dark-tone duration-200 rounded-lg px-2 py-1">
|
</button>
|
||||||
+
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -608,10 +606,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<YesNoDialog ref="yesNoDialog" />
|
<YesNoDialog ref="yesNoDialog" />
|
||||||
|
<AddModelDialog ref="addmodeldialog" />
|
||||||
<MessageBox ref="messageBox" />
|
<MessageBox ref="messageBox" />
|
||||||
<Toast ref="toast" />
|
<Toast ref="toast" />
|
||||||
</template>
|
</template>
|
||||||
@ -688,10 +687,12 @@ import BindingEntry from "../components/BindingEntry.vue";
|
|||||||
import socket from '@/services/websocket.js'
|
import socket from '@/services/websocket.js'
|
||||||
import defaultModelImgPlaceholder from "../assets/default_model.png"
|
import defaultModelImgPlaceholder from "../assets/default_model.png"
|
||||||
import defaultPersonalityImgPlaceholder from "../assets/logo.svg"
|
import defaultPersonalityImgPlaceholder from "../assets/logo.svg"
|
||||||
|
import AddModelDialog from "@/components/AddModelDialog.vue";
|
||||||
|
|
||||||
axios.defaults.baseURL = import.meta.env.VITE_GPT4ALL_API_BASEURL
|
axios.defaults.baseURL = import.meta.env.VITE_GPT4ALL_API_BASEURL
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
|
AddModelDialog,
|
||||||
MessageBox,
|
MessageBox,
|
||||||
YesNoDialog,
|
YesNoDialog,
|
||||||
ModelEntry,
|
ModelEntry,
|
||||||
@ -706,8 +707,8 @@ export default {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
// install custom model
|
// install custom model
|
||||||
showModelInputDialog: false,
|
addModelDialogVisibility: false,
|
||||||
modelPath: '',
|
modelPath: '',
|
||||||
// Zoo stuff
|
// Zoo stuff
|
||||||
models: [],
|
models: [],
|
||||||
personalities: [],
|
personalities: [],
|
||||||
@ -751,32 +752,25 @@ export default {
|
|||||||
created() {
|
created() {
|
||||||
|
|
||||||
}, methods: {
|
}, methods: {
|
||||||
showInputDialog() {
|
showAddModelDialog() {
|
||||||
console.log("Input dialog shown")
|
this.$refs.addmodeldialog.showDialog("").then(()=>{
|
||||||
this.showModelInputDialog = true;
|
console.log(this.$refs.addmodeldialog.model_path);
|
||||||
},
|
|
||||||
closeInputDialog() {
|
|
||||||
this.showModelInputDialog = false;
|
|
||||||
this.modelPath = '';
|
|
||||||
},
|
|
||||||
validateModelPath() {
|
|
||||||
// Perform validation of the model path (e.g., checking if it is a local file or internet link)
|
|
||||||
// ...
|
|
||||||
|
|
||||||
// Trigger the `download_model` endpoint with the path as a POST
|
// Make a POST request to the "install model" endpoint
|
||||||
this.$axios.post('/download_model', { path: this.modelPath })
|
const path = this.$refs.addmodeldialog.model_path;
|
||||||
.then(response => {
|
|
||||||
// Handle the response
|
// Emit an event to the Socket.IO server
|
||||||
// ...
|
socket.emit("install_model", { path: path }, (response) => {
|
||||||
})
|
// Handle the response from the server
|
||||||
.catch(error => {
|
console.log("Model installation successful:", response);
|
||||||
// Handle the error
|
|
||||||
// ...
|
|
||||||
});
|
});
|
||||||
|
console.log(this.$refs.addmodeldialog.model_path)
|
||||||
|
})
|
||||||
|
|
||||||
// Close the input dialog
|
|
||||||
this.closeInputDialog();
|
|
||||||
},
|
},
|
||||||
|
closeAddModelDialog() {
|
||||||
|
this.addModelDialogVisibility = false;
|
||||||
|
},
|
||||||
collapseAll(val) {
|
collapseAll(val) {
|
||||||
this.bec_collapsed = val
|
this.bec_collapsed = val
|
||||||
this.mzc_collapsed = val
|
this.mzc_collapsed = val
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
@echo off
|
@echo off
|
||||||
|
|
||||||
|
echo \u001b[34m
|
||||||
echo HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
|
echo HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
|
||||||
echo HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
|
echo HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
|
||||||
echo HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
|
echo HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
|
||||||
@ -34,7 +35,7 @@ echo HHHHHHHHHHHH.HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
|
|||||||
echo HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
|
echo HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
|
||||||
echo HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
|
echo HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
|
||||||
echo HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
|
echo HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
|
||||||
|
echo \u001b[0m
|
||||||
echo Checking internet connection
|
echo Checking internet connection
|
||||||
|
|
||||||
ping google.com -n 1 >nul 2>&1
|
ping google.com -n 1 >nul 2>&1
|
||||||
|
2
webui.sh
2
webui.sh
@ -1,4 +1,5 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
echo "\u001b[34m"
|
||||||
echo "HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH"
|
echo "HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH"
|
||||||
echo "HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH"
|
echo "HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH"
|
||||||
echo "HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH"
|
echo "HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH"
|
||||||
@ -33,6 +34,7 @@ echo "HHHHHHHHHHHH.HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
|
|||||||
echo "HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH"
|
echo "HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH"
|
||||||
echo "HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH"
|
echo "HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH"
|
||||||
echo "HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH"
|
echo "HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH"
|
||||||
|
echo "\u001b[0m"
|
||||||
|
|
||||||
if ping -q -c 1 google.com >/dev/null 2>&1; then
|
if ping -q -c 1 google.com >/dev/null 2>&1; then
|
||||||
echo -e "\e[32mInternet Connection working fine\e[0m"
|
echo -e "\e[32mInternet Connection working fine\e[0m"
|
||||||
|
Loading…
Reference in New Issue
Block a user