added working settings page

This commit is contained in:
partisan 2024-08-15 13:31:15 +02:00
parent 7127b3ee88
commit 2f23b32fa7
17 changed files with 561 additions and 97 deletions

View file

@ -32,13 +32,17 @@ A self-hosted private and anonymous [metasearch engine](https://en.wikipedia.org
## Comparison to other search engines
| Name | Works without JavaScript | Music search | Torrent search | API | Scalable | Not Resource Hungry | Dynamic Page Loading |
| ------------- | ------------------ | --------------------------- | ----------------- | ------ | ------------------- | ---------------------------------------------- | ---------------------- |
| Whoogle [1] | ✅ | ❓ | ❌ | ❌ | ❌ | ❓ Moderate | ❓ Not specified |
| Araa-Search | ✅ | ❌ | ✅ | ✅ [2] | ❌ | ❌ Very resource hungry | ❌ |
| LibreY | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ Moderate 200-400mb~ | ❌ |
| 4get | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ Moderate 200-400mb~ | ❌ |
| Warp | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ about 15-20MiB at idle, 17-22MiB when searching | ✅ |
| Feature | Whoogle | Araa-Search | LibreY | 4get | *Warp* |
| :----------------------------------- | ------------------ | ------------------------- | ------------------------ | ------------------------ | ---------------------------------------------------- |
| Works without JavaScript | ✅ | ✅ | ✅ | ✅ | ✅ |
| Music search | ❓ | ❌ | ❌ | ✅ | ✅ |
| Torrent search | ❌ | ✅ | ✅ | ❌ | ✅ |
| API | ❌ | ✅ | ✅ | ✅ | ✅ |
| Scalable | ❌ | ❌ | ❌ | ❌ | ✅ |
| Not Resource Hungry | ❓ Moderate | ❌ Very resource hungry | ❌ Moderate 200-400mb~ | ❌ Moderate 200-400mb~ | ✅ about 15-20MiB at idle, 17-22MiB when searching |
| Dynamic Page Loading | ❓ Not specified | ❌ | ❌ | ❌ | ✅ |
| User themable | ❌ | ✅ | ❌ | ❌ | ✅ |
| It has dildo as logo, unironically | ❌ | ❌ | ❌ | ✅ | ❌ |
[1]: I was not able to check this since their site does not work, same for the community instances.

View file

@ -169,9 +169,8 @@ func runServer() {
http.HandleFunc("/search", handleSearch)
http.HandleFunc("/img_proxy", handleImageProxy)
http.HandleFunc("/node", handleNodeRequest)
http.HandleFunc("/settings", func(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, "templates/settings.html")
})
http.HandleFunc("/settings", handleSettings)
http.HandleFunc("/save-settings", handleSaveSettings)
http.HandleFunc("/opensearch.xml", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/opensearchdescription+xml")
http.ServeFile(w, r, "static/opensearch.xml")

74
static/css/black.css Normal file
View file

@ -0,0 +1,74 @@
:root {
--html-bg: #000000;
--font-fg: #fafafa;
--fg: #BABCBE;
--search-bg: #000000;
--search-bg-input: #000000;
--search-bg-input-border: #5f6368;
--search-select: #282828;
--border: #707070;
--link: #8ab4f8;
--link-visited: #c58af9;
--snip-border: #303134;
--snip-background: #282828;
--snip-text: #f1f3f4;
--settings-border: #5f6368;
--button: #000000;
--footer-bg: #161616;
--footer-font: #999da2;
--highlight: #bcc0c3;
--blue: #8ab4f8;
--green: #31b06e;
--search-button: #BABCBE;
--image-view: #161616;
--image-view-titlebar: #161616;
--view-image-color: #000000;
--image-select: #303030;
--fff: #fff;
--publish-info: #7f869e;
color-scheme: dark;
}
.calc-btn:hover {
box-shadow: 0 14px 28px rgba(0, 0, 0, 0.25), 0 10px 10px rgba(0, 0, 0, 0.22);
}
.calc-btn-2:hover {
box-shadow: 0 14px 28px rgba(0, 0, 0, 0.25), 0 10px 10px rgba(0, 0, 0, 0.22);
}
.calc-btn-2 {
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
transition: all 0.3s cubic-bezier(.25, .8, .25, 1);
}
.calc-btn {
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
transition: all 0.3s cubic-bezier(.25, .8, .25, 1);
}
.calc {
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
}
.view-image-search {
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
transition: all 0.3s cubic-bezier(.25, .8, .25, 1);
}
.view-image-search:hover {
box-shadow: 0 14px 28px rgba(0, 0, 0, 0.25), 0 10px 10px rgba(0, 0, 0, 0.22);
}

100
static/css/latte.css Normal file
View file

@ -0,0 +1,100 @@
:root {
--rosewater: #f5e0dc;
--flamingo: #f2cdcd;
--pink: #f5c2e7;
--mauve: #cba6f7;
--red: #f38ba8;
--maroon: #eba0ac;
--peach: #fab387;
--yellow: #f9e2af;
--green: #a6e3a1;
--teal: #94e2d5;
--sky: #89dceb;
--sapphire: #74c7ec;
--blue: #89b4fa;
--lavender: #b4befe;
--text: #cdd6f4;
--subtext1: #bac2de;
--subtext0: #a6adc8;
--overlay2: #9399b2;
--overlay1: #7f849c;
--overlay0: #6c7086;
--surface2: #585b70;
--surface1: #45475a;
--surface0: #313244;
--base: #1e1e2e;
--mantle: #181825;
--crust: #11111b;
--html-bg: var(--base);
--font-fg: var(--text);
--fg: var(--subtext0);
--search-bg: var(--mantle);
--search-bg-input: var(--surface1);
--search-bg-input-border: var(--overlay0);
--search-select: var(--surface0);
--border: var(--overlay0);
--link: var(--blue);
--link-visited: var(--mauve);
--snip-border: var(--surface1);
--snip-background: var(--surface0);
--snip-text: var(--text);
--settings-border: var(--overlay1);
--button: var(--surface1);
--footer-bg: var(--mantle);
--footer-font: var(--overlay1);
--highlight: var(--subtext1);
--blue: var(--blue);
--green: var(--green);
--search-button: var(--subtext0);
--image-view: var(--mantle);
--image-view-titlebar: var(--mantle);
--view-image-color: var(--crust);
--image-select: var(--surface1);
--fff: var(--text);
--publish-info: var(--overlay2);
color-scheme: dark;
}
.calc-btn:hover {
box-shadow: 0 14px 28px rgba(0, 0, 0, 0.25), 0 10px 10px rgba(0, 0, 0, 0.22);
}
.calc-btn-2:hover {
box-shadow: 0 14px 28px rgba(0, 0, 0, 0.25), 0 10px 10px rgba(0, 0, 0, 0.22);
}
.calc-btn-2 {
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
transition: all 0.3s cubic-bezier(.25, .8, .25, 1);
}
.calc-btn {
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
transition: all 0.3s cubic-bezier(.25, .8, .25, 1);
}
.calc {
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
}
.view-image-search {
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
transition: all 0.3s cubic-bezier(.25, .8, .25, 1);
}
.view-image-search:hover {
box-shadow: 0 14px 28px rgba(0, 0, 0, 0.25), 0 10px 10px rgba(0, 0, 0, 0.22);
}

100
static/css/mocha.css Normal file
View file

@ -0,0 +1,100 @@
:root {
--rosewater: #dc8a78;
--flamingo: #dd7878;
--pink: #ea76cb;
--mauve: #8839ef;
--red: #d20f39;
--maroon: #e64553;
--peach: #fe640b;
--yellow: #df8e1d;
--green: #40a02b;
--teal: #179299;
--sky: #04a5e5;
--sapphire: #209fb5;
--blue: #1e66f5;
--lavender: #7287fd;
--text: #4c4f69;
--subtext1: #5c5f77;
--subtext0: #6c6f85;
--overlay2: #7c7f93;
--overlay1: #8c8fa1;
--overlay0: #9ca0b0;
--surface2: #acb0be;
--surface1: #bcc0cc;
--surface0: #ccd0da;
--base: #eff1f5;
--mantle: #e6e9ef;
--crust: #dce0e8;
--html-bg: var(--base);
--font-fg: var(--text);
--fg: var(--subtext0);
--search-bg: var(--mantle);
--search-bg-input: var(--surface1);
--search-bg-input-border: var(--overlay0);
--search-select: var(--surface0);
--border: var(--overlay0);
--link: var(--blue);
--link-visited: var(--mauve);
--snip-border: var(--surface1);
--snip-background: var(--surface0);
--snip-text: var(--text);
--settings-border: var(--overlay1);
--button: var(--surface1);
--footer-bg: var(--mantle);
--footer-font: var(--overlay1);
--highlight: var(--subtext1);
--blue: var(--blue);
--green: var(--green);
--search-button: var(--subtext0);
--image-view: var(--mantle);
--image-view-titlebar: var(--mantle);
--view-image-color: var(--crust);
--image-select: var(--surface1);
--fff: var(--text);
--publish-info: var(--overlay2);
color-scheme: light;
}
.calc-btn:hover {
box-shadow: 0 14px 28px rgba(0, 0, 0, 0.15), 0 10px 10px rgba(0, 0, 0, 0.12);
}
.calc-btn-2:hover {
box-shadow: 0 14px 28px rgba(0, 0, 0, 0.15), 0 10px 10px rgba(0, 0, 0, 0.12);
}
.calc-btn-2 {
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.10), 0 1px 2px rgba(0, 0, 0, 0.14);
transition: all 0.3s cubic-bezier(.25, .8, .25, 1);
}
.calc-btn {
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.10), 0 1px 2px rgba(0, 0, 0, 0.14);
transition: all 0.3s cubic-bezier(.25, .8, .25, 1);
}
.calc {
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);
}
.view-image-search {
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.10), 0 1px 2px rgba(0, 0, 0, 0.14);
transition: all 0.3s cubic-bezier(.25, .8, .25, 1);
}
.view-image-search:hover {
box-shadow: 0 14px 28px rgba(0, 0, 0, 0.15), 0 10px 10px rgba(0, 0, 0, 0.12);
}

74
static/css/night.css Normal file
View file

@ -0,0 +1,74 @@
:root {
--html-bg: #171b25;
--font-fg: #ebecf7;
--fg: #ebecf7;
--search-bg: #0c0d0f;
--search-bg-input: #2e3443;
--search-bg-input-border: rgb(46, 52, 67);
--search-select: #3a445c;
--border: rgb(46, 52, 67);
--link: #a7b1fc;
--link-visited: #ad71bc;
--snip-border: rgb(46, 52, 67);
--snip-background: #1e222d;
--snip-text: #f1f3f4;
--settings-border: #5f6368;
--button: #0c0d0f;
--footer-bg: #0c0d0f;
--footer-font: #ebecf7;
--highlight: #ebecf7;
--blue: #8ab4f8;
--green: #31b06e;
--image-view: #0c0d0f;
--image-view-titlebar: #0c0d0f;
--view-image-color: #000000;
--image-select: #303030;
--fff: #fff;
--search-button: #BABCBE;
--publish-info: #7f869e;
color-scheme: dark;
}
.calc-btn:hover {
box-shadow: 0 14px 28px rgba(0, 0, 0, 0.25), 0 10px 10px rgba(0, 0, 0, 0.22);
}
.calc-btn-2:hover {
box-shadow: 0 14px 28px rgba(0, 0, 0, 0.25), 0 10px 10px rgba(0, 0, 0, 0.22);
}
.calc-btn-2 {
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
transition: all 0.3s cubic-bezier(.25, .8, .25, 1);
}
.calc-btn {
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
transition: all 0.3s cubic-bezier(.25, .8, .25, 1);
}
.calc {
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
}
.view-image-search {
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
transition: all 0.3s cubic-bezier(.25, .8, .25, 1);
}
.view-image-search:hover {
box-shadow: 0 14px 28px rgba(0, 0, 0, 0.25), 0 10px 10px rgba(0, 0, 0, 0.22);
}

View file

@ -0,0 +1,62 @@
/* settings.html */
.theme-link {
display: block;
text-decoration: none;
color: inherit;
width: 48%;
margin-bottom: 10px;
height: 150px;
position: relative; /* Make it possible to position the tooltip */
}
.theme-link img {
width: 100%;
height: 100%;
object-fit: cover;
border-radius: 4px;
border: 1px solid var(--snip-border);
transition: border-color 0.3s ease;
}
/* .theme-link:hover img {
border-color: var(--highlight);
} */
.theme-tooltip {
display: none; /* Hidden by default */
position: absolute;
bottom: 10px; /* Position at the bottom of the image */
left: 50%;
transform: translateX(-50%);
background-color: rgba(0, 0, 0, 0.7); /* Semi-transparent background */
color: #fff;
padding: 5px 10px;
border-radius: 4px;
font-size: 14px;
white-space: nowrap;
}
.theme-link:hover .theme-tooltip {
display: block; /* Show tooltip on hover */
}
.themes-settings-menu {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
background: var(--snip-background);
color: var(--fg);
border-radius: 4px;
padding: 10px;
gap: 10px;
}
@media (max-width: 600px) {
.theme-link {
width: 100%;
}
}
/* --- */

View file

@ -838,23 +838,6 @@ form.torrent-sort {
display: initial;
}
.themes-settings-menu {
background: var(--snip-background);
color: var(--fg);
border-radius: 4px;
height: 100%;
margin: 5px;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.themes-settings-menu>div {
width: calc(50% - 10px);
margin: 5px;
}
.view-image-search {
border: 1px solid var(--snip-border);
margin: 0;
@ -1873,8 +1856,6 @@ body, h1, p, a, input, button {
}
/* --- */
/* Ensuring dark theme compliance */
@media (prefers-color-scheme: dark) {
.leaflet-control-locate,

BIN
static/images/black.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.8 KiB

After

Width:  |  Height:  |  Size: 9.5 KiB

BIN
static/images/latte.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.8 KiB

After

Width:  |  Height:  |  Size: 10 KiB

BIN
static/images/mocha.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

BIN
static/images/night.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

View file

@ -59,7 +59,7 @@
<div class="search-menu settings-menu-hidden">
<h2>Settings</h2>
<div class="settings-content">
<!-- <button id="settingsButton" onclick="window.location.href='/settings'">All settings</button> Well its unessesary to use js here but this menu will not work without js anyway -->
<button id="settingsButton" onclick="window.location.href='/settings'">All settings</button> <!-- Well its unessesary to use js here but this menu will not work without js anyway -->
<div class="theme-settings">
<p><span class="highlight">Current theme: </span> <span id="theme_name">{{.Theme}}</span></p>
<div class="themes-settings-menu">

View file

@ -6,77 +6,85 @@
<title>Settings - Ocásek</title>
<link rel="stylesheet" href="/static/css/style.css">
<link rel="stylesheet" href="/static/css/{{.Theme}}.css">
<link rel="stylesheet" href="/static/css/style-settings.css">
<link rel="search" type="application/opensearchdescription+xml" title="Ocásek" href="/opensearch.xml">
</head>
<body>
<form action="/search" id="prev-next-form" class="results-search-container" method="GET" autocomplete="off">
<h1 class="logomobile"><a class="no-decoration" href="./">Ocásek</a></h1>
<div class="wrapper-results">
<input type="text" name="q" value="" id="search-input" placeholder="Type to search..." />
<button id="search-wrapper-ico" class="material-icons-round" name="t" value="text">search</button>
<input type="submit" class="hide" name="t" value="text" />
<div class="settings-nav">
<h1 class="logomobile"><a class="no-decoration" href="./">Settings</a></h1>
</div>
<div class="sub-search-button-wrapper">
<div class="search-container-results-btn">
<button id="sub-search-wrapper-ico" class="material-icons-round clickable" name="t" value="text">search</button>
<button name="t" value="text" class="clickable">Web</button>
</div>
<div class="search-container-results-btn">
<button id="sub-search-wrapper-ico" class="material-icons-round clickable" name="t" value="image">image</button>
<button name="t" value="image" class="clickable">Images</button>
</div>
<div class="search-container-results-btn">
<button id="sub-search-wrapper-ico" class="material-icons-round clickable" name="t" value="video">movie</button>
<button name="t" value="video" class="clickable">Videos</button>
</div>
<div class="search-container-results-btn">
<button id="sub-search-wrapper-ico" class="material-icons-round clickable" name="t" value="forum">forum</button>
<button name="t" value="forum" class="clickable">Forums</button>
</div>
<div id="content" class="js-enabled">
<div class="search-container-results-btn">
<button id="sub-search-wrapper-ico" class="material-icons-round clickable" name="t" value="map">map</button>
<button name="t" value="map" class="clickable">Maps</button>
</div>
</div>
<div class="search-container-results-btn">
<button id="sub-search-wrapper-ico" class="material-icons-round clickable" name="t" value="torrent">share</button>
<button name="t" value="torrent" class="clickable">Torrents</button>
</div>
</div>
</div>
</form>
<div class="results_settings">
<form>
<h1>SETTINGS ARE NOT IMPLEMENTED YET</h1>
<h2>Theme</h2>
<label for="theme-dark">Dark Theme:</label>
<input type="checkbox" class="results-settings" id="theme-dark" name="theme" value="dark"><br>
<h2>Language</h2>
<label for="ui-language">UI Language:</label>
<select id="ui-language" class="results-settings" name="ui_language">
<option value="english">English</option>
<option value="deutsch">Deutsch</option>
</select><br>
<label for="search-language">Search Language:</label>
<select id="search-language" class="results-settings" name="search_language">
<option value="english">English</option>
<option value="deutsch">Deutsch</option>
<div class="settings-container">
<form action="/save-settings" method="post">
<div class="settings">
<div class="settings-row">
<span class="highlight"><p>Theme</p></span>
</div>
<div class="theme-settings">
<div class="themes-settings-menu">
<a href="/search?theme=dark" class="theme-link">
<div class="view-image-search clickable" id="dark">
<img src="/static/images/dark.webp" alt="Dark (Default)">
<div class="theme-tooltip">Dark (Default)</div>
</div>
</a>
<a href="/search?theme=light" class="theme-link">
<div class="view-image-search clickable" id="light">
<img src="/static/images/light.webp" alt="Light">
<div class="theme-tooltip">Light</div>
</div>
</a>
<a href="/search?theme=night" class="theme-link">
<div class="view-image-search clickable" id="night">
<img src="/static/images/night.webp" alt="night">
<div class="theme-tooltip">Night</div>
</div>
</a>
<a href="/search?theme=black" class="theme-link">
<div class="view-image-search clickable" id="black">
<img src="/static/images/black.webp" alt="Black">
<div class="theme-tooltip">Black</div>
</div>
</a>
<a href="/search?theme=mocha" class="theme-link">
<div class="view-image-search clickable" id="mocha">
<img src="/static/images/mocha.webp" alt="🌿 Mocha">
<div class="theme-tooltip">Mocha</div>
</div>
</a>
<a href="/search?theme=latte" class="theme-link">
<div class="view-image-search clickable" id="latte">
<img src="/static/images/latte.webp" alt="🌻 Latte">
<div class="theme-tooltip">Latte</div>
</div>
</a>
</div>
</div>
<div class="settings-row">
<p>Safe Search</p>
<select class="results-settings" name="safe" id="safeSearchSelect">
<option value="disabled" {{if eq .Safe "disabled"}}selected{{end}}>Safe Search Off</option>
<option value="active" {{if eq .Safe "active"}}selected{{end}}>Safe Search On</option>
</select>
</div>
<h2>Privacy</h2>
<label for="theme-dark">Use JavaScript:</label>
<input type="checkbox" class="results-settings" id="theme-dark" name="theme" value="dark"><br>
<label for="theme-dark">Use search suggestions:</label>
<input type="checkbox" class="results-settings" id="theme-dark" name="theme" value="dark"><br><br>
<div class="settings-row">
<p>Preferred Language</p>
<select class="results-settings" name="lang" id="languageSelect">
{{range .LanguageOptions}}
<option value="{{.Code}}" {{if eq .Code $.CurrentLang}}selected{{end}}>{{.Name}}</option>
{{end}}
</select>
</div>
<input type="submit" class="results-settings" value="Save">
<div class="settings-row settings-row2">
<p class="font-hide">|</p>
<button class="save save-settings-page" type="submit">Save Settings</button>
</div>
</div>
</form>
<div>
<script>
// Check if JavaScript is enabled and modify the DOM accordingly
document.getElementById('content').classList.remove('js-enabled');
</script>
</div>
</body>
</html>

View file

@ -1,6 +1,9 @@
package main
import "net/http"
import (
"html/template"
"net/http"
)
type UserSettings struct {
Theme string
@ -57,4 +60,63 @@ func saveUserSettings(w http.ResponseWriter, settings UserSettings) {
Secure: true, // Ensure cookie is sent over HTTPS only
SameSite: http.SameSiteNoneMode, // Set SameSite to None
})
printDebug("settings saved: %v", settings)
}
func handleSaveSettings(w http.ResponseWriter, r *http.Request) {
if r.Method == "POST" {
// Load current settings
settings := loadUserSettings(r)
// Update only the settings that were submitted in the form
if theme := r.FormValue("theme"); theme != "" {
settings.Theme = theme
}
if lang := r.FormValue("lang"); lang != "" {
settings.Language = lang
}
if safe := r.FormValue("safe"); safe != "" {
settings.SafeSearch = safe
}
// Save the updated settings
saveUserSettings(w, settings)
// Redirect back to the previous page or settings page
http.Redirect(w, r, r.FormValue("past"), http.StatusSeeOther)
}
}
func handleSettings(w http.ResponseWriter, r *http.Request) {
// Load user settings
settings = loadUserSettings(r)
data := struct {
LanguageOptions []LanguageOption
CurrentLang string
Theme string
Safe string
}{
LanguageOptions: languageOptions,
CurrentLang: settings.Language,
Theme: settings.Theme,
Safe: settings.SafeSearch,
}
printDebug("Rendering settings with data: %+v", data)
tmpl, err := template.ParseFiles("templates/settings.html")
if err != nil {
printErr("Error parsing template: %s", err)
http.Error(w, "Internal Server Error", 500)
return
}
err = tmpl.Execute(w, data)
if err != nil {
printErr("Error executing template: %s", err)
http.Error(w, "Internal Server Error", 500)
return
}
}