From fb2adbb65087252c0fd0392c8fa8f0218bffa22b Mon Sep 17 00:00:00 2001 From: Physcik Date: Fri, 26 Dec 2025 20:08:28 +0500 Subject: Articles idnexing --- articles | 2 +- db.sql | 19 +++++++++++ src/Index/Connection.go | 89 ++++++++++++++++++++++++++++++++++++++++++++++++ src/Render/Render.go | 54 ++++++++++++++++++++++------- src/Settings.json | 3 +- src/Settings/Settings.go | 2 ++ src/go.mod | 2 ++ src/go.sum | 2 ++ src/main.go | 2 ++ static/common.js | 8 ++--- templates/index.html | 16 ++++++--- 11 files changed, 175 insertions(+), 24 deletions(-) create mode 100644 db.sql create mode 100644 src/Index/Connection.go create mode 100644 src/go.sum diff --git a/articles b/articles index 7586257..28d1b19 160000 --- a/articles +++ b/articles @@ -1 +1 @@ -Subproject commit 7586257fd5767bca2c3e939c05e7e51f052f8a7e +Subproject commit 28d1b19d519b55aaa39a145c631df6f84ba099b5 diff --git a/db.sql b/db.sql new file mode 100644 index 0000000..06db73b --- /dev/null +++ b/db.sql @@ -0,0 +1,19 @@ +CREATE TABLE Articles ( + Id INTEGER PRIMARY KEY AUTOINCREMENT, + DisplayName TEXT UNIQUE, + FileName TEXT UNIQUE, + URL TEXT UNIQUE, + CreatedAt TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP +); + +CREATE TABLE Tags ( + Id INTEGER PRIMARY KEY AUTOINCREMENT, + Name TEXT +); + +CREATE TABLE ArticlesToTags ( + ArticleId INTEGER, + TagId INTEGER, + FOREIGN KEY(ArticleId) REFERENCES Articles(Id), + FOREIGN KEY(TagId) REFERENCES Tags(Id) +); diff --git a/src/Index/Connection.go b/src/Index/Connection.go new file mode 100644 index 0000000..d4523b2 --- /dev/null +++ b/src/Index/Connection.go @@ -0,0 +1,89 @@ +package index + +import ( + "database/sql" + "fmt" + "log/slog" + _ "github.com/mattn/go-sqlite3" + + settings "physick.ru/Settings" +) + +var db *sql.DB = nil + +type Article struct { + Id int + DisplayName string + FileName string + URL string + + Tags []Tag +} + +type Tag struct { + Id int + Name string +} + +func EstablistDBConnection() { + var database, err = sql.Open("sqlite3", settings.Current.IndexDB) + if err != nil { + panic(fmt.Sprintf("Failed to start a server: DB connection failed (%s)", err.Error())) + } + db = database +} + +func GetAllArticles() ([]Article, error) { + var rows, sqlErr = db.Query("SELECT Id, DisplayName, FileName, URL FROM Articles;") + if sqlErr != nil { + return []Article{}, sqlErr + } + var outp = make([]Article, 0) + for rows.Next() { + var new = Article{} + rows.Scan(&new.Id, &new.DisplayName, &new.FileName, &new.URL) + var tagsErr = new.FillTags() + if tagsErr != nil { + slog.Warn("Failed to parse article flags", slog.Any("Error", tagsErr)) + } + outp = append(outp, new) + } + return outp, nil +} + +func (base *Article) FillTags() error { + var rows, sqlErr = db.Query(`SELECT Tags.Id, Tags.Name + FROM ArticlesToTags LEFT JOIN Tags ON Tags.Id = ArticlesToTags.TagId + WHERE ArticlesToTags.ArticleId = ?;`, base.Id) + if sqlErr != nil { + return sqlErr + } + var outp = make([]Tag, 0) + for rows.Next() { + var new = Tag{} + var err = rows.Scan(&new.Id, &new.Name) + if err != nil { + slog.Warn("Failed to parse a tag descriptor from the table", slog.Any("Error", err)) + } + outp = append(outp, new) + } + base.Tags = outp + return nil +} + +func GetArticleByName(URL string) (Article, error) { + var rows, sqlErr = db.Query("SELECT Id, DisplayName, FileName, URL FROM Articles WHERE URL = ?;", URL) + if sqlErr != nil { + return Article{}, sqlErr + } + var new = Article{} + for rows.Next() { + rows.Scan(&new.Id, &new.DisplayName, &new.FileName, &new.URL) + var tagsErr = new.FillTags() + if tagsErr != nil { + slog.Error("Failed to parse article flags", slog.Any("Error", tagsErr)) + } + } + return new, nil + +} diff --git a/src/Render/Render.go b/src/Render/Render.go index bdaa51e..130789c 100644 --- a/src/Render/Render.go +++ b/src/Render/Render.go @@ -6,17 +6,14 @@ import ( "net/http" "strings" + index "physick.ru/Index" settings "physick.ru/Settings" ) type IndexTemplateContents struct { - LastArticles []recentArticle + LastArticles []index.Article Content string -} - -type recentArticle struct { - Link string - DisplayName string + Tags []index.Tag } func RegisterEndpoints() { @@ -45,17 +42,48 @@ func common(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusInternalServerError) return } + var recentArticles, dbErr = index.GetAllArticles() + if dbErr != nil { + slog.Error("Failed to get recent articles from database", slog.Any("Error", dbErr)) + w.WriteHeader(http.StatusInternalServerError) + return + } executeIndexTemplate(IndexTemplateContents{ - LastArticles: []recentArticle { - recentArticle { - Link: "/", - DisplayName: "Index page", - }, - }, + LastArticles: recentArticles, Content: indexArticle, }, w) } func test(w http.ResponseWriter, r *http.Request) { - fmt.Fprint(w, "xdx") + var requestedName = r.PathValue("name") + if len(requestedName) < 1 { + w.WriteHeader(http.StatusNotFound) + return + } + var article, dbErr = index.GetArticleByName(requestedName) + if dbErr != nil { + slog.Error("Failed to get an article from db", slog.Any("Error", dbErr)) + w.WriteHeader(http.StatusInternalServerError) + return + } + if len(article.DisplayName) < 1 { + w.WriteHeader(http.StatusNotFound) + return + } + var contents, fileErr = getTemplate(article.FileName) + if fileErr != nil { + w.WriteHeader(http.StatusNotFound) + return + } + var recentArticles, err = index.GetAllArticles() + if err != nil { + slog.Error("Failed to get recent articles from database", slog.Any("Error", err)) + w.WriteHeader(http.StatusInternalServerError) + return + } + executeIndexTemplate(IndexTemplateContents{ + LastArticles: recentArticles, + Content: contents, + Tags: article.Tags, + }, w) } diff --git a/src/Settings.json b/src/Settings.json index acd7ab3..9700828 100644 --- a/src/Settings.json +++ b/src/Settings.json @@ -2,5 +2,6 @@ "Port": ":7000", "StaticLocation": "../static", "TemplatesLocation": "../templates", - "ArticlesLocation": "../articles" + "ArticlesLocation": "../articles", + "IndexDB": "../articles/index.db" } diff --git a/src/Settings/Settings.go b/src/Settings/Settings.go index 50df787..8c64442 100644 --- a/src/Settings/Settings.go +++ b/src/Settings/Settings.go @@ -12,6 +12,7 @@ type Settings struct { StaticLocation string TemplatesLocation string ArticlesLocation string + IndexDB string } const settingsLocation = "Settings.json" @@ -21,6 +22,7 @@ var defaultSettings = Settings { StaticLocation: "../static", TemplatesLocation: "../templates", ArticlesLocation: "../articles", + IndexDB: "../articles/index.db", } diff --git a/src/go.mod b/src/go.mod index 27c0362..d6b9df7 100644 --- a/src/go.mod +++ b/src/go.mod @@ -1,3 +1,5 @@ module physick.ru go 1.25.4 + +require github.com/mattn/go-sqlite3 v1.14.32 // indirect diff --git a/src/go.sum b/src/go.sum new file mode 100644 index 0000000..66f7516 --- /dev/null +++ b/src/go.sum @@ -0,0 +1,2 @@ +github.com/mattn/go-sqlite3 v1.14.32 h1:JD12Ag3oLy1zQA+BNn74xRgaBbdhbNIDYvQUEuuErjs= +github.com/mattn/go-sqlite3 v1.14.32/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= diff --git a/src/main.go b/src/main.go index c950f14..fdcfef8 100644 --- a/src/main.go +++ b/src/main.go @@ -4,12 +4,14 @@ import ( "log/slog" "net/http" + index "physick.ru/Index" render "physick.ru/Render" settings "physick.ru/Settings" ) func main() { settings.ReadSettings() + index.EstablistDBConnection() render.RegisterEndpoints() diff --git a/static/common.js b/static/common.js index a7dc3a5..bf98cea 100644 --- a/static/common.js +++ b/static/common.js @@ -13,15 +13,15 @@ function ToggleMode() { function setLightMode() { swapClasses("dark", "light"); localStorage.setItem("theme", "light"); - document.getElementById("toggleIcon").src = "static/toggle.svg" - document.getElementById("homeIcon").src = "static/home_dark.svg" + document.getElementById("toggleIcon").src = "/static/toggle.svg" + document.getElementById("homeIcon").src = "/static/home_dark.svg" } function setDarkMode() { swapClasses("light", "dark"); localStorage.setItem("theme", "dark"); - document.getElementById("toggleIcon").src = "static/toggle_dark.svg" - document.getElementById("homeIcon").src = "static/home.svg" + document.getElementById("toggleIcon").src = "/static/toggle_dark.svg" + document.getElementById("homeIcon").src = "/static/home.svg" } function swapClasses(baseClass, newClass) { diff --git a/templates/index.html b/templates/index.html index 250f509..16377d2 100644 --- a/templates/index.html +++ b/templates/index.html @@ -4,26 +4,32 @@ - - + +
{{.Content}} -- cgit v1.3