From ccba37021ad38f359eb0accb16678a44bd9155e6 Mon Sep 17 00:00:00 2001 From: partisan Date: Wed, 13 Nov 2024 16:59:42 +0100 Subject: [PATCH 01/10] hopefully fixed dynamic image loading --- images.go | 169 +++++++------------ main.go | 2 +- node-handle-search.go | 3 +- templates/images.html | 323 +++++++++++++++++++------------------ templates/images_only.html | 22 +++ 5 files changed, 250 insertions(+), 269 deletions(-) create mode 100644 templates/images_only.html diff --git a/images.go b/images.go index a5e31b0..5ffcb46 100755 --- a/images.go +++ b/images.go @@ -19,11 +19,24 @@ func init() { } } -func handleImageSearch(w http.ResponseWriter, settings UserSettings, query string, page int) { +func handleImageSearch(w http.ResponseWriter, r *http.Request, settings UserSettings, query string, page int) { startTime := time.Now() - cacheKey := CacheKey{Query: query, Page: page, Safe: settings.SafeSearch == "active", Lang: settings.SearchLanguage, Type: "image"} - combinedResults := getImageResultsFromCacheOrFetch(cacheKey, query, settings.SafeSearch, settings.SearchLanguage, page) + cacheKey := CacheKey{ + Query: query, + Page: page, + Safe: settings.SafeSearch == "active", + Lang: settings.SearchLanguage, + Type: "image", + } + + // Check if JavaScript is disabled + jsDisabled := r.URL.Query().Get("js_disabled") == "true" + + // Determine if we should cache images synchronously + synchronous := jsDisabled + + combinedResults := getImageResultsFromCacheOrFetch(cacheKey, query, settings.SafeSearch, settings.SearchLanguage, page, synchronous) elapsedTime := time.Since(startTime) @@ -31,7 +44,7 @@ func handleImageSearch(w http.ResponseWriter, settings UserSettings, query strin data := map[string]interface{}{ "Results": combinedResults, "Query": query, - "Fetched": fmt.Sprintf("%.2f %s", elapsedTime.Seconds(), Translate("seconds")), // Time for fetching + "Fetched": fmt.Sprintf("%.2f %s", elapsedTime.Seconds(), Translate("seconds")), "Page": page, "HasPrevPage": page > 1, "HasNextPage": len(combinedResults) >= 50, @@ -41,14 +54,15 @@ func handleImageSearch(w http.ResponseWriter, settings UserSettings, query strin "Theme": settings.Theme, "Safe": settings.SafeSearch, "IsThemeDark": settings.IsThemeDark, - "HardCacheEnabled": config.HardCacheDuration == 0, + "HardCacheEnabled": config.HardCacheEnabled, + "JsDisabled": jsDisabled, } - // Render the template without measuring the time + // Render the full page renderTemplate(w, "images.html", data) } -func getImageResultsFromCacheOrFetch(cacheKey CacheKey, query, safe, lang string, page int) []ImageSearchResult { +func getImageResultsFromCacheOrFetch(cacheKey CacheKey, query, safe, lang string, page int, synchronous bool) []ImageSearchResult { cacheChan := make(chan []SearchResult) var combinedResults []ImageSearchResult @@ -66,7 +80,7 @@ func getImageResultsFromCacheOrFetch(cacheKey CacheKey, query, safe, lang string select { case results := <-cacheChan: if results == nil { - combinedResults = fetchImageResults(query, safe, lang, page) + combinedResults = fetchImageResults(query, safe, lang, page, synchronous) if len(combinedResults) > 0 { combinedResults = filterValidImages(combinedResults) resultsCache.Set(cacheKey, convertToSearchResults(combinedResults)) @@ -77,7 +91,7 @@ func getImageResultsFromCacheOrFetch(cacheKey CacheKey, query, safe, lang string } case <-time.After(2 * time.Second): printInfo("Cache check timeout") - combinedResults = fetchImageResults(query, safe, lang, page) + combinedResults = fetchImageResults(query, safe, lang, page, synchronous) if len(combinedResults) > 0 { combinedResults = filterValidImages(combinedResults) resultsCache.Set(cacheKey, convertToSearchResults(combinedResults)) @@ -87,7 +101,7 @@ func getImageResultsFromCacheOrFetch(cacheKey CacheKey, query, safe, lang string return combinedResults } -func fetchImageResults(query, safe, lang string, page int) []ImageSearchResult { +func fetchImageResults(query, safe, lang string, page int, synchronous bool) []ImageSearchResult { var results []ImageSearchResult engineCount := len(imageSearchEngines) safeBool := safe == "active" @@ -99,9 +113,6 @@ func fetchImageResults(query, safe, lang string, page int) []ImageSearchResult { // Calculate the specific page number for the selected engine enginePage := (page-1)/engineCount + 1 - // Debug print to verify the selected engine and page - printInfo("Fetching image results for overall page %d using engine: %s (engine page %d)", page, engine.Name, enginePage) - // Fetch results from the selected engine searchResults, _, err := engine.Func(query, safe, lang, enginePage) if err != nil { @@ -118,19 +129,26 @@ func fetchImageResults(query, safe, lang string, page int) []ImageSearchResult { imageResult.ID = hash imageResult.ProxyFull = "/image_cache/" + filename - // Start caching and validation in the background - go func(imgResult ImageSearchResult, originalURL, filename string) { - _, success, err := cacheImage(originalURL, filename, imgResult.ID) - if err != nil { - printWarn("Failed to cache image %s: %v", originalURL, err) + if synchronous { + // Synchronously cache the image + _, success, err := cacheImage(imageResult.Full, filename, imageResult.ID) + if err != nil || !success { + printWarn("Failed to cache image %s: %v", imageResult.Full, err) + // Fallback to proxy URL + imageResult.ProxyFull = "/imgproxy?url=" + imageResult.Full } - if !success { - removeImageResultFromCache(query, page, safeBool, lang, imgResult.ID) - } - }(imageResult, imageResult.Full, filename) + } else { + // Start caching and validation in the background + go func(imgResult ImageSearchResult, originalURL, filename string) { + _, success, err := cacheImage(originalURL, filename, imgResult.ID) + if err != nil || !success { + printWarn("Failed to cache image %s: %v", originalURL, err) + removeImageResultFromCache(query, page, safeBool, lang, imgResult.ID) + } + }(imageResult, imageResult.Full, filename) + } } else { // Use proxied URLs when hard cache is disabled - imageResult.ProxyThumb = "/imgproxy?url=" + imageResult.Thumb imageResult.ProxyFull = "/imgproxy?url=" + imageResult.Full } results = append(results, imageResult) @@ -161,16 +179,30 @@ func fetchImageResults(query, safe, lang string, page int) []ImageSearchResult { imageResult.ID = hash imageResult.ProxyFull = "/image_cache/" + filename - // Start caching and validation in the background - go func(imgResult ImageSearchResult, originalURL, filename string) { - _, success, err := cacheImage(originalURL, filename, imgResult.ID) + if synchronous { + // Synchronously cache the image + _, success, err := cacheImage(imageResult.Full, filename, imageResult.ID) if err != nil { - printWarn("Failed to cache image %s: %v", originalURL, err) + printWarn("Failed to cache image %s: %v", imageResult.Full, err) + // Skip this image + continue } if !success { - removeImageResultFromCache(query, page, safeBool, lang, imgResult.ID) + // Skip this image + continue } - }(imageResult, imageResult.Full, filename) + } else { + // Start caching and validation in the background + go func(imgResult ImageSearchResult, originalURL, filename string) { + _, success, err := cacheImage(originalURL, filename, imgResult.ID) + if err != nil { + printWarn("Failed to cache image %s: %v", originalURL, err) + } + if !success { + removeImageResultFromCache(query, page, safeBool, lang, imgResult.ID) + } + }(imageResult, imageResult.Full, filename) + } } else { // Use proxied URLs when hard cache is disabled imageResult.ProxyThumb = "/imgproxy?url=" + imageResult.Thumb @@ -204,82 +236,3 @@ func wrapImageSearchFunc(f func(string, string, string, int) ([]ImageSearchResul return searchResults, duration, nil } } - -// func isValidImageURL(imageURL string) bool { -// client := &http.Client{ -// Timeout: 10 * time.Second, -// Transport: &http.Transport{ -// TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, -// }, -// } - -// req, err := http.NewRequest("GET", imageURL, nil) -// if err != nil { -// return false -// } - -// // Set headers to mimic a real browser -// req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "+ -// "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36") -// req.Header.Set("Accept", "image/webp,image/*,*/*;q=0.8") -// req.Header.Set("Accept-Language", "en-US,en;q=0.9") -// req.Header.Set("Referer", imageURL) // Some servers require a referer - -// resp, err := client.Do(req) -// if err != nil { -// return false -// } -// defer resp.Body.Close() - -// if resp.StatusCode < 200 || resp.StatusCode >= 400 { -// return false -// } - -// // Limit the amount of data read to 10KB -// limitedReader := io.LimitReader(resp.Body, 10240) // 10KB - -// // Attempt to decode image configuration -// _, _, err = image.DecodeConfig(limitedReader) -// if err != nil { -// return false -// } - -// return true -// } - -// // This function can be used alternatively to isValidImageURL(), Its slower but reliable -// func isImageAccessible(imageURL string) bool { -// client := &http.Client{ -// Timeout: 5 * time.Second, -// CheckRedirect: func(req *http.Request, via []*http.Request) error { -// if len(via) >= 10 { -// return http.ErrUseLastResponse -// } -// return nil -// }, -// } - -// resp, err := client.Get(imageURL) -// if err != nil { -// return false -// } -// defer resp.Body.Close() - -// if resp.StatusCode < 200 || resp.StatusCode >= 400 { -// return false -// } - -// // Read the entire image data -// data, err := io.ReadAll(resp.Body) -// if err != nil { -// return false -// } - -// // Try to decode the image -// _, _, err = image.Decode(bytes.NewReader(data)) -// if err != nil { -// return false -// } - -// return true -// } diff --git a/main.go b/main.go index 611d583..85fa213 100755 --- a/main.go +++ b/main.go @@ -161,7 +161,7 @@ func handleSearch(w http.ResponseWriter, r *http.Request) { // Handle different search types switch searchType { case "image": - handleImageSearch(w, settings, query, page) + handleImageSearch(w, r, settings, query, page) case "video": handleVideoSearch(w, settings, query, page) case "map": diff --git a/node-handle-search.go b/node-handle-search.go index 8591b65..7323710 100755 --- a/node-handle-search.go +++ b/node-handle-search.go @@ -63,8 +63,7 @@ func handleSearchImageMessage(msg Message) { } log.Printf("Received search-image request. ResponseAddr: %s", searchParams.ResponseAddr) - - results := fetchImageResults(searchParams.Query, searchParams.Safe, searchParams.Lang, searchParams.Page) + results := fetchImageResults(searchParams.Query, searchParams.Safe, searchParams.Lang, searchParams.Page, true) resultsJSON, err := json.Marshal(results) if err != nil { log.Printf("Error marshalling search results: %v", err) diff --git a/templates/images.html b/templates/images.html index 6a0e885..bb39283 100755 --- a/templates/images.html +++ b/templates/images.html @@ -152,6 +152,9 @@ + {{ if not .JsDisabled }} + + {{ end }}
@@ -168,48 +171,60 @@
- - {{ if .Results }} -
- - {{ range $index, $result := .Results }} -
- {{ .Title }} -
{{ .Width }} × {{ .Height }}
-
- {{ .Title }} - {{ translate "source" }} -
+ + {{ if .Results }} +
+ + {{ range $index, $result := .Results }} +
+ {{ if $.HardCacheEnabled }} + {{ if $.JsDisabled }} + + {{ $result.Title }} + {{ else }} + + {{ $result.Title }} + {{ end }} + {{ else }} + + {{ $result.Title }} + {{ end }} +
{{ $result.Width }} × {{ $result.Height }}
+
+ {{ $result.Title }} + {{ translate "source" }}
+
+ {{ end }} +
+ + + {{ else if .NoResults }} +
{{ translate "no_results" .Query }}
+ {{ else }} +
{{ translate "no_more_results" }}
+ {{ end }}
{{ translate "searching_for_new_results" }} @@ -218,141 +233,133 @@
- - + - // Start polling every pollingInterval milliseconds - const pollingIntervalId = setInterval(checkImageStatus, pollingInterval); - - // Optionally, call checkImageStatus immediately - checkImageStatus(); - }); + + - - - - \ No newline at end of file diff --git a/templates/images_only.html b/templates/images_only.html index 09774d5..765045b 100644 --- a/templates/images_only.html +++ b/templates/images_only.html @@ -1,4 +1,3 @@ - {{ range $index, $result := .Results }}
{{ end }} {{ translate "site_description" }} + + + @@ -17,9 +31,14 @@ - - + +
+ +
+
+ menu +
@@ -140,38 +159,48 @@
- - -
- -

{{ translate "web" }}

+
+ +
+ +
+ +
+ +
+ +
+ +
+
-
- -

{{ translate "images" }}

+
+ +
+ +
+
- -
- -

{{ translate "videos" }}

-
- -
- -

{{ translate "forums" }}

-
- -
- -

{{ translate "maps" }}

-
- -
- -

{{ translate "torrents" }}

-
-
+
@@ -180,9 +209,9 @@ \ No newline at end of file From 998896ad86c653e3b1fa6845f9d2ce8139779004 Mon Sep 17 00:00:00 2001 From: partisan Date: Tue, 19 Nov 2024 12:14:11 +0100 Subject: [PATCH 08/10] I LOVE HTML --- templates/images.html | 29 +++++++++++++++++------------ templates/images_only.html | 25 ++++++++++++++++--------- 2 files changed, 33 insertions(+), 21 deletions(-) diff --git a/templates/images.html b/templates/images.html index e27f839..04eadf3 100755 --- a/templates/images.html +++ b/templates/images.html @@ -8,6 +8,13 @@ {{ end }} {{ .Query }} - {{ translate "site_name" }} + @@ -185,16 +192,14 @@ -
- {{ $result.Title }} -
+ {{ $result.Title }} {{ else }} {{ $result.Title }} @@ -216,10 +221,10 @@ diff --git a/templates/images_only.html b/templates/images_only.html index 765045b..e51dbe6 100644 --- a/templates/images_only.html +++ b/templates/images_only.html @@ -1,21 +1,28 @@ {{ range $index, $result := .Results }}
- + + {{ $result.Title }} + + + + {{ $result.Title }} + alt="{{ $result.Title }}" + class="clickable placeholder-img" + /> + {{ else }} + + {{ $result.Title }} + {{ end }}
{{ $result.Width }} × {{ $result.Height }}
{{ $result.Title }} {{ translate "source" }}
-{{ end }} \ No newline at end of file +{{ end }} From 3ca7d576809361a9be9b0a650ceeb44b86b04c7f Mon Sep 17 00:00:00 2001 From: partisan Date: Tue, 19 Nov 2024 14:19:15 +0100 Subject: [PATCH 09/10] fixed broken search buttons --- templates/files.html | 1 - templates/forums.html | 1 - templates/images.html | 1 - templates/map.html | 1 - templates/text.html | 1 - templates/videos.html | 1 - update.go | 2 +- 7 files changed, 1 insertion(+), 7 deletions(-) diff --git a/templates/files.html b/templates/files.html index b344339..c25751d 100755 --- a/templates/files.html +++ b/templates/files.html @@ -17,7 +17,6 @@
-

diff --git a/templates/forums.html b/templates/forums.html index 90f981a..0027f98 100755 --- a/templates/forums.html +++ b/templates/forums.html @@ -17,7 +17,6 @@ -

diff --git a/templates/images.html b/templates/images.html index 04eadf3..447a6a4 100755 --- a/templates/images.html +++ b/templates/images.html @@ -25,7 +25,6 @@ -

diff --git a/templates/map.html b/templates/map.html index a41f68d..5bfe57d 100644 --- a/templates/map.html +++ b/templates/map.html @@ -32,7 +32,6 @@ -

diff --git a/templates/text.html b/templates/text.html index e0f330f..eeb1b5a 100755 --- a/templates/text.html +++ b/templates/text.html @@ -17,7 +17,6 @@ -

diff --git a/templates/videos.html b/templates/videos.html index 047f610..3350c95 100644 --- a/templates/videos.html +++ b/templates/videos.html @@ -17,7 +17,6 @@ -

diff --git a/update.go b/update.go index 3e31ba0..9a92b18 100644 --- a/update.go +++ b/update.go @@ -9,7 +9,7 @@ import ( // Function to check for updates and restart the server if an update is found func checkForUpdates() { - repoURL := "https://weforgecode.xyz/Spitfire/Search.git" + repoURL := "https://weforge.xyz/Spitfire/Search.git" localDir := "." // Assume the repository is cloned in the current directory for { From 28f71271d7cfd703511aaf18bd661e6b0c06ed68 Mon Sep 17 00:00:00 2001 From: partisan Date: Thu, 21 Nov 2024 12:30:16 +0100 Subject: [PATCH 10/10] added Dockerfile & added --port --domain --skip-config-check flags --- Dockerfile | 32 +++++++++++++++++ README.md | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++++ init.go | 49 ++++++++++++++++++------- run.bat | 42 ++++++++++++++++++++-- run.sh | 41 +++++++++++++++++++-- 5 files changed, 249 insertions(+), 18 deletions(-) create mode 100644 Dockerfile create mode 100644 README.md diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..9655535 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,32 @@ +# Use Alpine Linux as the base image +FROM alpine:3.20 + +# Update and install Golang and Git +RUN apk update && apk add --no-cache go git + +# Create a new user and switch to it +RUN adduser -D myuser +USER myuser + +# Set the working directory +WORKDIR /home/myuser + +# Clone the Git repository +RUN git clone https://weforge.xyz/Spitfire/Search.git + +# Change directory to the cloned repository +WORKDIR /home/myuser/Search + +# Ensure the run.sh script is executable +RUN chmod +x run.sh + +# Expose the application's port +EXPOSE 5000 + +# Define environment variables for port and domain with default values +ENV PORT= +ENV DOMAIN= +ENV SKIP_CONFIG="--skip-config-check" + +# Run the run.sh script on container start +CMD ["sh", "-c", "./run.sh $SKIP_CONFIG --port ${PORT:-} --domain ${DOMAIN:-}"] diff --git a/README.md b/README.md new file mode 100644 index 0000000..65b8600 --- /dev/null +++ b/README.md @@ -0,0 +1,103 @@ +

+ Logo +

+ +

+ QGato Search Engine +

+ +

+A self-hosted private metasearch engine that aims to be more resource-efficient than its competition. +

+ +# Bare in mind that this project is still WIP + +## Comparison to other search engines + + +| Feature | Whoogle [1] | Araa-Search | LibreY | 4get | SearchXNG | *QGato* | +| :------------------------- | ------------------ | ------------------------- | ------------------------ | ------------------------ | ------------------------- | ---------------------------------------------------- | +| Works without JavaScript | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| Music search | ❓ | ❌ | ❌ | ✅ | ✅ | ✅ | +| Torrent search | ❌ | ✅ | ✅ | ❌ | ✅ | ✅ | +| API | ❌ | ❓ [2] | ✅ | ✅ | ✅ | ✅ | +| Scalable | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | +| Not Resource Hungry | ❓ Moderate | ❌ Very resource hungry | ❌ Moderate 200-400mb~ | ❌ Moderate 200-400mb~ | ❌ Moderate 200-300MiB~ | ✅ about 15-20MiB at idle, 17-22MiB when searching | +| Result caching | ❌ | ❌ | ❓ | ❓ | ❓ | ✅ | +| Dynamic Page Loading | ❓ Not specified | ❌ | ❌ | ❌ | ✅ | ✅ | +| User themable | ❌ | ✅ | ❌ | ❌ | ✅[3] | ✅ | +| Unusual logo choice | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | + +[1]: I was not able to check this since their site does not work, same for the community instances. + +[2]: In the project repo they specify that it has API, but It looks like they are no loger supporting it. Or just removed "API" button and documentation, since I was not able to find it anymore. + +[3]: It is called 'User Themable' because you want to give the user freedom of choice for their theme, not by hard-setting one theme in the backend and calling it themable. + +## Features + +### For Casual Users + +- **Works out of the box** - No configuration required, just works by default. +- **No tracking or ads** - Fully private, ad-free experience. +- **Custom themes** - Personalize the look and feel. +- **Search suggestions** - Get faster results with helpful suggestions. +- **Privacy-first** - Open-source and transparent (unlike DuckDuckGo). +- **Annoyance-free** - No pop-ups, crypto, or clutter (I'm looking at you, Brave). + +### For Self-Hosting + +- **Self-hosted option** - Run on your own server for even more privacy. +- **Lightweight** - Low memory footprint (15-22MiB) even during searches. +- **Decentralized** - No single point of failure. +- **Results caching in RAM** - Faster response times through caching. +- **Configurable** - Tweak features via `config.ini`. +- **Flexible media support** - Images optionally stored on HDD/SSD for caching and improved response time. + +### Results Sources + +- **Search suggestions** - Sources include Yahoo, Startpage, Qwant, Ecosia, Brave, Edge, and DuckDuckGo. +- **Text search** - Google, Brave, DuckDuckGo, LibreX/Y. +- **Image search** - Sources include Qwant, Bing, and Imgur. +- **Video search** - Utilizes the Piped API. +- **Maps** - Integrated OpenStreetMap. +- **File downloads** - Access via torrent sources. + +## Getting Started + +### Prerequisites + +- Go (version 1.18 or higher recommended) +- Git (unexpected) +- Access to the internet for fetching results (even more unexpected) + +### Running the QGato + +Linux: + +```bash +git clone https://weforgecode.xyz/Spitfire/Search.git +cd Search +chmod +x ./run.sh +./run.sh +``` + +Windows: + +```powershell +git clone https://weforgecode.xyz/Spitfire/Search.git +cd Search +.\run.bat +``` + +*Its that easy!* + +### Configuring + +Configuration is done via the ``config.ini`` file. +On first start, you will be guided through the basic setup. +More advanced setup and all options will be listed here later, as this is still being updated. + +## License + +[![](https://www.gnu.org/graphics/agplv3-with-text-162x68.png)](https://www.gnu.org/licenses/agpl-3.0.html) diff --git a/init.go b/init.go index 52789b7..de32e07 100644 --- a/init.go +++ b/init.go @@ -1,6 +1,8 @@ package main import ( + "flag" + "os" "time" ) @@ -35,14 +37,43 @@ const configFilePath = "config.ini" var config Config func main() { - err := initConfig() - if err != nil { - printErr("Error during initialization:") - return + // Command-line flags + portFlag := flag.Int("port", 0, "Port number to run the application (overrides config)") + domainFlag := flag.String("domain", "", "Domain address for the application (overrides config)") + skipConfigFlag := flag.Bool("skip-config-check", false, "Skip interactive prompts and load config.ini") + + // Parse command-line flags + flag.Parse() + + if *skipConfigFlag { + // Skip interactive configuration + if _, err := os.Stat(configFilePath); err == nil { + // Load from config file if it exists + config = loadConfig() + } else { + // Use defaults if config file does not exist + config = defaultConfig + saveConfig(config) // Save the defaults to config.ini + printInfo("Configuration saved to %s", configFilePath) + } + } else { + // Initialize configuration interactively or from config file + err := initConfig() + if err != nil { + printErr("Error during initialization:") + return + } + } + + // Override with command-line arguments if provided + if *portFlag != 0 { + config.Port = *portFlag + } + if *domainFlag != "" { + config.Domain = *domainFlag } loadNodeConfig() - // go checkMasterHeartbeat() // Not currently used if config.AuthCode == "" { config.AuthCode = generateStrongRandomString(64) @@ -57,14 +88,6 @@ func main() { } config.PeerID = hostID - // if len(config.Peers) > 0 { - // time.Sleep(2 * time.Second) // Give some time for connections to establish - // startElection() - // } - - // Start automatic update checker, not used now - //go checkForUpdates() - InitializeLanguage("en") // Initialize language before generating OpenSearch generateOpenSearchXML(config) diff --git a/run.bat b/run.bat index 0f68a88..3fedce2 100755 --- a/run.bat +++ b/run.bat @@ -1,6 +1,36 @@ @echo off setlocal enabledelayedexpansion +rem Initialize variables +set SKIP_CONFIG="" +set PORT="" +set DOMAIN="" + +rem Parse arguments +:parse_args +if "%~1"=="" goto end_parse +if "%~1"=="--port" ( + set PORT=%~2 + shift + shift + goto parse_args +) +if "%~1"=="--domain" ( + set DOMAIN=%~2 + shift + shift + goto parse_args +) +if "%~1"=="--skip-config-check" ( + set SKIP_CONFIG=--skip-config-check + shift + goto parse_args +) +echo Unknown argument: %~1 +exit /b 1 + +:end_parse + rem Use the current directory where the script is executed pushd %~dp0 @@ -10,8 +40,16 @@ for %%f in (*.go) do ( set GO_FILES=!GO_FILES! %%f ) -rem Run the Go program with all the .go files -go run !GO_FILES! +rem Construct the command +set CMD=go run !GO_FILES! !SKIP_CONFIG! +if not "%PORT%"=="" set CMD=!CMD! --port %PORT% +if not "%DOMAIN%"=="" set CMD=!CMD! --domain %DOMAIN% + +rem Informative output +echo Starting application with command: !CMD! + +rem Run the Go program with the constructed command +call !CMD! rem Return to the original directory popd diff --git a/run.sh b/run.sh index 1c13eb4..b703495 100755 --- a/run.sh +++ b/run.sh @@ -1,7 +1,42 @@ #!/bin/sh -# List all go files in this directory +# Initialize variables +SKIP_CONFIG="" +PORT="" +DOMAIN="" + +# Parse arguments +while [ $# -gt 0 ]; do + case $1 in + --port) + PORT=$2 + shift 2 + ;; + --domain) + DOMAIN=$2 + shift 2 + ;; + --skip-config-check) + SKIP_CONFIG="--skip-config-check" + shift + ;; + *) + echo "Unknown argument: $1" + exit 1 + ;; + esac +done + +# List all Go files in this directory GO_FILES=$(find . -name '*.go' -print) -# Run the Go program with the specified files first, followed by the remaining files -go run $FILES $GO_FILES +# Construct the command +CMD="go run $GO_FILES $SKIP_CONFIG" +[ -n "$PORT" ] && CMD="$CMD --port $PORT" +[ -n "$DOMAIN" ] && CMD="$CMD --domain $DOMAIN" + +# Informative output +echo "Starting application with command: $CMD" + +# Run the Go program with the constructed command +eval $CMD