// Package main defines the entry point of the Go application. package main // Importing necessary packages for database interaction, web server functionality, logging, and more. import ( "database/sql" "fmt" "html/template" "io" "log" "net/http" "os" "strings" "time" _ "modernc.org/sqlite" // Importing SQLite driver for database interaction. ) // readHtml function reads an HTML file and applies a CSS template to it before sending it to the client. func readHtml(res http.ResponseWriter, req *http.Request) { g := template.CSS("./html/public/mod.css") // Define the CSS path. f, err := template.ParseFiles("./html/wsb.html") // Parse the HTML file. if err != nil { log.Println(err) // Log any errors encountered. } err = f.Execute(res, g) // Execute the template with the CSS and send it to the client. if err != nil { log.Println(err) // Log any errors encountered. } } // simpRequestResp sends a simple response to the client. func simpRequestResp(res http.ResponseWriter, req *http.Request) { fmt.Fprint(res, "Hello, M'Lord", 153*4, " I'm here to serveè") // Print a formatted string to the client. } // getMsgFromDB retrieves a message from the database based on the provided ID and language. func getMsgFromDB(sqldb *sql.DB, id string, lang string) string { var lngs []string lngs = append(lngs, lang) // Append the language to the slice. query := generateSQL("msgs", lngs, [2]string{"content", id}) // Generate the SQL query. res := sqldb.QueryRow(query) // Execute the query. lng := "" dt := res.Scan(&lng) // Scan the result into the lng variable. if dt != nil { return "" // Return an empty string if there's an error. } return lng // Return the retrieved message. } // queryPacks retrieves a list of packages from the database. func queryPacks(sqldb *sql.DB, element *elements) []packages { pkg_list := getPkgIdFromDB(sqldb) // Get the list of package IDs from the database. pkgs := make([]packages, 0) // Initialize a slice to hold the packages. for _, p := range pkg_list { query := generateSQL("packs_all", []string{"*"}, [2]string{"id", p}) // Generate the SQL query for each package. res, err := sqldb.Query(query) // Execute the query. defer res.Close() // Ensure the result set is closed after the function returns. err = res.Err() // Check for any errors during query execution. if err != nil { log.Panicln(err) // Log and panic on any errors. } for res.Next() { npkg := packages{} // Create a new package instance. err := res.Scan(&npkg.Id, &npkg.Name, &npkg.Version, &npkg.ExtraCommand, &npkg.Tag, &npkg.Warning) // Scan the result into the package instance. if err != nil { log.Fatalln(err) // Log and exit on any errors. } npkg.Element = element // Associate the element with the package. pkgs = append(pkgs, npkg) // Append the package to the slice. } } return pkgs // Return the slice of packages. } // queryDatabase executes a SQL query expecting a single row and returns the result as a slice of strings. // sqldb: The database connection object. // queryRow: The SQL query string to be executed. // Returns: A slice of strings representing the query result. func queryDatabase(sqldb *sql.DB, queryRow string) []string { res := sqldb.QueryRow(queryRow) var values []string err := res.Scan(&values) if err != nil { log.Println(err) } return values } // generateSQL constructs a SQL SELECT statement with optional WHERE clauses. // table: The name of the database table. // columns: A slice of strings representing the column names to be selected. // arg: A variadic slice of string pairs representing WHERE clause conditions. // Returns: A string representing the complete SQL SELECT statement. func generateSQL(table string, columns []string, arg ...[2]string) string { cols := strings.Join(columns, ",") table = "SELECT " + cols + " FROM " + table if len(arg) > 0 { table += " WHERE " for i, a := range arg { table += a[0] + " like '" + a[1] + "'" if i+1 < len(arg) { table += " and " } } } return table } // searchDownloads performs a database query to retrieve download statistics. // sqldb: The database connection object. // table: The name of the database table. // columns: A variadic number of strings representing the column names to be selected. // Returns: A slice of DownloadElements structs containing the query results. func searchDownloads(sqldb *sql.DB, table string, columns ...string) []DownloadElements { query := generateSQL(table, columns) runquery, err := sqldb.Query(query) defer runquery.Close() err = runquery.Err() if err != nil { log.Fatalln(err) } var elems []DownloadElements var e DownloadElements for runquery.Next() { if len(columns) > 2 { err = runquery.Scan(&e.ID, &e.Version, &e.Counter) } else { err = runquery.Scan(&e.ID, &e.Counter) } elems = append(elems, e) } return elems } // stats creates an HTTP handler that serves a statistics page with data from the database. // sqldb: The database connection object. // lang: The language code to localize the content. // Returns: An http.Handler that serves the statistics page. func stats(sqldb *sql.DB, lang string) http.Handler { return http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) { Counter := struct{ ElementsData elements VersionStats []DownloadElements TotalStats []DownloadElements BodyClass string Lang string }{ ElementsData: elements{ Title: getMsgFromDB(sqldb, "title", lang), Header: getMsgFromDB(sqldb, "header", lang), Help: getMsgFromDB(sqldb, "help", lang), Packagename: getMsgFromDB(sqldb, "packagename", lang), Packageversion: getMsgFromDB(sqldb, "packageversion", lang), Allow: getMsgFromDB(sqldb, "allow", lang), Warning: getMsgFromDB(sqldb, "warning", lang), Explain: getMsgFromDB(sqldb, "explain", lang), }, BodyClass: "m", VersionStats: searchDownloads(sqldb, "counterd", "program", "version","download_count"), TotalStats: searchDownloads(sqldb, "count_all", "program","download_count"), Lang: lang, } templates, err := template.ParseFiles("html/master.html", "html/statsitics.html") if err != nil { log.Println(err) } err = templates.ExecuteTemplate(res, "master", Counter) if err != nil { log.Println(err) } res.WriteHeader(http.StatusOK) }) } // getPkgIdFromDB retrieves a list of package IDs from the database. // sqldb: The database connection object. // Returns: A slice of strings containing package IDs. func getPkgIdFromDB(sqldb *sql.DB) []string { query, err := sqldb.Query("SELECT id FROM packs_all") defer query.Close() err = query.Err() if err != nil { log.Println(err) } var pkgs []string var tmpstr string for query.Next() { err = query.Scan(&tmpstr) if err != nil { log.Println(err) } pkgs = append(pkgs, tmpstr) } // query.Scan(&pkgs) if err != nil { log.Println(err) } return pkgs } // fullSearchPackagesDB performs a full search of packages in the database. // sqldb: The database connection object. // Returns: A slice of packages structs containing the full package details. func fullSearchPackagesDB(sqldb *sql.DB) []packages { pkg_list := getPkgIdFromDB(sqldb) var pkgs []packages for _, p := range pkg_list { query := generateSQL("packs_all", []string{"*"}, [2]string{"id", p}) res := queryDatabase(sqldb, query) var pkg packages pkg, _ = ConvertStringsToPackage(res) pkgs = append(pkgs, pkg) } return pkgs } func uploadFileForServer(sqldb *sql.DB, lang string) http.Handler{ return http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) { pageDataFromDatabase := elements{ Title: getMsgFromDB(sqldb, "title", lang), Header: getMsgFromDB(sqldb, "header", lang), Help: getMsgFromDB(sqldb, "help", lang), Packagename: getMsgFromDB(sqldb, "packagename", lang), Packageversion: getMsgFromDB(sqldb, "packageversion", lang), Allow: getMsgFromDB(sqldb, "allow", lang), Warning: getMsgFromDB(sqldb, "warning", lang), Explain: getMsgFromDB(sqldb, "explain", lang), } data := struct { BodyClass string ElementsData elements Lang string }{ ElementsData: pageDataFromDatabase, BodyClass: "", Lang: lang, } templates, err := template.ParseFiles("html/master.html", "html/uploadfile.html") if err != nil { log.Println(err) } err = templates.ExecuteTemplate(res, "master", data) if err != nil { log.Println(err) } // upload(res, req) res.WriteHeader(http.StatusOK) }) } func upload() http.Handler { return http.HandlerFunc(func(res http.ResponseWriter, req *http.Request){ file, header, _ := req.FormFile("myFile") req.ParseMultipartForm(10000000<<20) defer file.Close() filename := header.Filename tempFile, _ :=os.CreateTemp("Data",header.Filename) defer tempFile.Close() fileBytes,_:=io.ReadAll(file) tempFile.Write(fileBytes) fn,_:=os.OpenFile("Data/"+filename, os.O_CREATE, 0666) fn.Write(fileBytes) fn.Close() getParamsFromExif("Data/"+filename) })} // index creates an HTTP handler that serves the main page with data from the database. // sqldb: The database connection object. // lang: The language code to localize the content. // Returns: An http.Handler that serves the main page. func index(sqldb *sql.DB, lang string) http.Handler { return http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) { pageDataFromDatabase := elements{ Title: getMsgFromDB(sqldb, "title", lang), Header: getMsgFromDB(sqldb, "header", lang), Help: getMsgFromDB(sqldb, "help", lang), Packagename: getMsgFromDB(sqldb, "packagename", lang), Packageversion: getMsgFromDB(sqldb, "packageversion", lang), Allow: getMsgFromDB(sqldb, "allow", lang), Warning: getMsgFromDB(sqldb, "warning", lang), Explain: getMsgFromDB(sqldb, "explain", lang), } data := struct { BodyClass string ElementsData elements PackagesData []packages Lang string }{ ElementsData: pageDataFromDatabase, BodyClass: "", PackagesData: queryPacks(sqldb, &pageDataFromDatabase), Lang: lang, } templates, err := template.ParseFiles("html/master.html", "html/main.html") if err != nil { log.Println(err) } err = templates.ExecuteTemplate(res, "master", data) if err != nil { log.Println(err) } res.WriteHeader(http.StatusOK) }) } // public serves static files from the "public" directory. // Returns: An http.Handler that serves static files. func public() http.Handler { return http.StripPrefix("/public/", http.FileServer(http.Dir("./public"))) } // main initializes the application, sets up logging, database connection, HTTP routing, and starts the server. func main() { logfilename := "Logs/" + time.Now().Format("2006-01-02--15-04-05") + ".log" file, err := os.OpenFile(logfilename, os.O_APPEND|os.O_CREATE, 0777) if err != nil { os.Exit(12) } log.SetOutput(file) db, _ := sql.Open("sqlite", "file:progs.db") mux := http.NewServeMux() mux.Handle("/public/", public()) mux.Handle("/", index(db, "heb")) mux.Handle("/en", index(db, "eng")) mux.Handle("/stats", stats(db,"eng")) mux.Handle("/up", uploadFileForServer(db,"eng")) mux.Handle("/upload",upload()) addr := fmt.Sprintf(":%s", "12312") server := http.Server{ Addr: addr, Handler: mux, ReadTimeout: 15 * time.Second, WriteTimeout: 15 * time.Second, IdleTimeout: 15 * time.Second, } if err := server.ListenAndServe(); err != nil { log.Fatalf("main: couldn't start simple server: %v\n", err) } lang := "heb" log.Println(getMsgFromDB(db, "title", lang)) }