diff --git a/.gitignore b/.gitignore index 60d49a7..6b43255 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,5 @@ Logs/ -*.exe \ No newline at end of file +*.exe +progs.db +tmpdir/ +.vscode/ \ No newline at end of file diff --git a/main.go b/main.go index 1c724e4..0603e01 100644 --- a/main.go +++ b/main.go @@ -1,5 +1,7 @@ +// 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" @@ -10,60 +12,69 @@ import ( "strings" "time" - _ "modernc.org/sqlite" + _ "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") - f, err := template.ParseFiles("./html/wsb.html") + 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.Println(err) // Log any errors encountered. } - err = f.Execute(res, g) + err = f.Execute(res, g) // Execute the template with the CSS and send it to the client. if err != nil { - log.Println(err) + 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è") + 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) - query := generateSQL("msgs", lngs, [2]string{"content", id}) - res := sqldb.QueryRow(query) + 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) + dt := res.Scan(&lng) // Scan the result into the lng variable. if dt != nil { - return "" + return "" // Return an empty string if there's an error. } - return lng + 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) - pkgs := make([]packages, 0) + 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}) - res, err := sqldb.Query(query) - defer res.Close() - err = res.Err() + 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.Panicln(err) // Log and panic on any errors. } for res.Next() { - npkg := packages{} - err := res.Scan(&npkg.Id, &npkg.Name, &npkg.Version, &npkg.ExtraCommand, &npkg.Tag, &npkg.Warning) + 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.Fatalln(err) // Log and exit on any errors. } - npkg.Element = element - pkgs = append(pkgs, npkg) + npkg.Element = element // Associate the element with the package. + pkgs = append(pkgs, npkg) // Append the package to the slice. } } - return pkgs + 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) @@ -74,6 +85,12 @@ func queryDatabase(sqldb *sql.DB, queryRow string) []string { } 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 @@ -88,6 +105,12 @@ func generateSQL(table string, columns []string, arg ...[2]string) string { } 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) @@ -108,6 +131,11 @@ func searchDownloads(sqldb *sql.DB, table string, columns ...string) []DownloadE } 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{ @@ -143,6 +171,10 @@ func stats(sqldb *sql.DB, lang string) http.Handler { 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() @@ -165,6 +197,10 @@ func getPkgIdFromDB(sqldb *sql.DB) []string { } 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 @@ -177,6 +213,11 @@ func fullSearchPackagesDB(sqldb *sql.DB) []packages { } return pkgs } + +// 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{ @@ -190,11 +231,13 @@ func index(sqldb *sql.DB, lang string) http.Handler { Explain: getMsgFromDB(sqldb, "explain", lang), } data := struct { + BodyClass string ElementsData elements PackagesData []packages Lang string }{ ElementsData: pageDataFromDatabase, + BodyClass: "", PackagesData: queryPacks(sqldb, &pageDataFromDatabase), Lang: lang, } @@ -211,9 +254,14 @@ func index(sqldb *sql.DB, lang string) http.Handler { }) } + +// 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) @@ -222,7 +270,7 @@ func main() { } log.SetOutput(file) - db, err := sql.Open("sqlite", "file:progs.db") + db, _ := sql.Open("sqlite", "file:progs.db") mux := http.NewServeMux() mux.Handle("/public/", public()) mux.Handle("/", index(db, "heb")) diff --git a/temp.progs.db b/temp.progs.db new file mode 100644 index 0000000..401b752 Binary files /dev/null and b/temp.progs.db differ