quantum-inspiration / commit
Adding a GitLab Pages page that shows all the articles and the chosen one.
.gitignore | 1 + .gitlab-ci.yml | 11 ++++++-- http-cache.go | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ main.go | 45 +++++++++++++++++++++++++++--- public/index.html | 32 ++++++++++++++++++++++ wiki.go | 41 ++++++---------------------- 6 files changed, 172 insertions(+), 40 deletions(-) diff --git a/.gitignore b/.gitignore index 185145a..cbe2dfe 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ cache/ __debug_bin +public/results.js \ No newline at end of file diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c99721d..50eefd6 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -2,7 +2,7 @@ image: golang:latest stages: - build-and-test - - run + - run-and-deploy before_script: - go version @@ -14,7 +14,12 @@ build-job: - make build - make test -run-job: - stage: run +pages: + stage: run-and-deploy script: - make run + artifacts: + paths: + - public + only: + - main \ No newline at end of file diff --git a/http-cache.go b/http-cache.go new file mode 100644 index 0000000..ccac112 --- /dev/null +++ b/http-cache.go @@ -0,0 +1,82 @@ +package main + +import ( + "fmt" + "io" + "net/http" + "os" + "path/filepath" + "time" +) + +func getCachedUrl( + url string, + id string, + cacheFileTimeFormat string, +) ([]byte, error) { + return getCachedUrlFunc(url, id, cacheFileTimeFormat, func(bytes []byte) ([]byte, error) { + return bytes, nil + }) +} +func getCachedUrlFunc( + url string, + id string, + cacheFileTimeFormat string, + byteProcessor func([]byte) ([]byte, error), +) ([]byte, error) { + now := time.Now() + nowFormatted := now.Format(cacheFileTimeFormat) + cacheFile := fmt.Sprintf("cache/%s-%s.txt", id, nowFormatted) + dir := filepath.Dir(cacheFile) + _, err := os.Stat(dir) + dirExists := err == nil || !os.IsNotExist(err) + if !dirExists { + err = os.Mkdir(dir, 0755) + if err != nil { + return nil, err + } + } + + _, err = os.Stat(cacheFile) + fileExists := err == nil || !os.IsNotExist(err) + if fileExists { + f, err := os.Open(cacheFile) + if err != nil { + return nil, err + } + defer f.Close() + bytes, err := io.ReadAll(f) + if err != nil { + return nil, err + } + return bytes, nil + } else { + resp, err := http.Get(url) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err + } + + body, err = byteProcessor(body) + if err != nil { + return nil, err + } + + f, err := os.Create(cacheFile) + if err != nil { + return nil, err + } + defer f.Close() + _, err = f.Write(body) + if err != nil { + return nil, err + } + + return body, nil + } +} diff --git a/main.go b/main.go index a7a1994..eabb283 100644 --- a/main.go +++ b/main.go @@ -1,14 +1,51 @@ package main -import "fmt" +import ( + "encoding/json" + "fmt" + "os" + "time" +) + +type Results struct { + CreationDate string + RandomNumber uint8 + Pages []WikiPage +} func main() { - title, url, err := GetRandomWikiPage() + random256Pages, err := getRandomWikipediaPages(256) if err != nil { - panic(err) + panic(fmt.Errorf("error getting random Wikipedia pages: %v", err)) + } + + randomNumbers, err := GetRandomNumbers(1) + if err != nil { + panic(fmt.Errorf("error getting random numbers: %v", err)) + } + + random := randomNumbers[0] + + result := Results{ + Pages: random256Pages, + RandomNumber: random, + CreationDate: time.Now().Format("2006-01-02"), + } + resultJson, err := json.MarshalIndent(result, "", " ") + if err != nil { + panic(fmt.Errorf("error marshalling results: %v", err)) + } + completeJson := fmt.Sprintf("var results = %s;", resultJson) + outPath := "./public/results.js" + err = os.WriteFile(outPath, []byte(completeJson), 0644) + if err != nil { + panic(fmt.Errorf("error writing to %s: %v", outPath, err)) } - message := fmt.Sprintf("Quantum inspiration for the day: <a href='%s'>%s</a>", url, title) + page := random256Pages[random] + title := page.Title + url := page.Url + message := fmt.Sprintf("Quantum inspiration for the day: <a href='%s'>%s</a>\n\n<a href='https://pavelsafronov.gitlab.io/quantum-inspiration/'>More...</a>", url, title) err = SendPushoverMessage(message) if err != nil { panic(err) diff --git a/public/index.html b/public/index.html new file mode 100644 index 0000000..776453b --- /dev/null +++ b/public/index.html @@ -0,0 +1,32 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="utf-8"> + <title>Quantum Inspiration - Results</title> + </head> + <body> + <h1 id="header">Quantum Inspiration</h1> + <h2 id="subheader"></h2> + <div id="root"></div> + <script src="results.js"></script> + <script> + header.innerHTML = `Quantum Inspiration - ${results.CreationDate}`; + + const chosenPage = results.Pages[results.RandomNumber]; + subheader.innerHTML = `Today's randomly chosen page: <a href="#chosen">#${results.RandomNumber + 1}</a> - <a href="${chosenPage.Url}">${chosenPage.Title}</a>`; + + results.Pages.forEach(function (page, index) { + var div = document.createElement('div'); + div.innerHTML = `${index + 1} - <a href="${page.Url}">${page.Title}</a>`; + + const isChosen = results.RandomNumber === index; + if (isChosen) { + div.style.fontWeight = 'bold'; + div.id = 'chosen'; + } + + root.appendChild(div); + }); + </script> + </body> +</html> \ No newline at end of file diff --git a/wiki.go b/wiki.go index 3ae04da..636c985 100644 --- a/wiki.go +++ b/wiki.go @@ -3,29 +3,11 @@ package main import ( "encoding/json" "fmt" - "io" - "net/http" ) -func GetRandomWikiPage() (title string, url string, err error) { - random256Pages, err := getRandomWikipediaPages(256) - if err != nil { - return "", "", fmt.Errorf("error getting random Wikipedia pages: %v", err) - } - - randomNumbers, err := GetRandomNumbers(1) - if err != nil { - return "", "", fmt.Errorf("error getting random numbers: %v", err) - } - - titles := []string{} - for title := range random256Pages { - titles = append(titles, title) - } - random := randomNumbers[0] - randomTitle := titles[random] - randomPage := random256Pages[randomTitle] - return randomTitle, randomPage, nil +type WikiPage struct { + Title string + Url string } type WikipediaResponse struct { @@ -39,18 +21,12 @@ type WikipediaResponse struct { } `json:"query"` } -func getRandomWikipediaPages(count int) (nameToUrlMap map[string]string, err error) { +func getRandomWikipediaPages(count int) (pages []WikiPage, err error) { url := fmt.Sprintf("https://en.wikipedia.org/w/api.php?format=json&action=query&generator=random&grnnamespace=0&grnlimit=%d", count) - resp, err := http.Get(url) + body, err := getCachedUrl(url, "wikipedia-randoms", "2006-01-02-15") if err != nil { return nil, fmt.Errorf("error fetching Wikipedia pages: %v", err) } - defer resp.Body.Close() - - body, err := io.ReadAll(resp.Body) - if err != nil { - return nil, fmt.Errorf("error reading Wikipedia response: %v", err) - } var wikiResponse WikipediaResponse err = json.Unmarshal(body, &wikiResponse) @@ -58,13 +34,12 @@ func getRandomWikipediaPages(count int) (nameToUrlMap map[string]string, err err return nil, fmt.Errorf("error unmarshalling Wikipedia JSON: %v", err) } - nameToUrlMap = map[string]string{} + pages = []WikiPage{} for pageID := range wikiResponse.Query.Pages { title := wikiResponse.Query.Pages[pageID].Title url := fmt.Sprintf("http://en.m.wikipedia.org/?curid=%s", pageID) - nameToUrlMap[title] = url - fmt.Printf("title: %s, url: %s\n", title, url) + pages = append(pages, WikiPage{Title: title, Url: url}) } - return nameToUrlMap, nil + return pages, nil }