From 6af08b80f68c59c7ffd9fc724d2f8a913e9759d5 Mon Sep 17 00:00:00 2001 From: Zhbert Date: Sun, 10 Nov 2024 21:08:18 +0300 Subject: [PATCH] feat(template): Add graphics with main info to the Habr section --- Taskfile.yml | 6 ++++ cmd/collect/collect.go | 4 ++- cmd/collect/functions.go | 4 ++- internal/common/structs/structs.go | 6 ++++ internal/csv_service/csv_service.go | 33 +++++++++++++++++++ internal/db_service/habr_sqlite.go | 50 ++++++++++++++++++++++------- internal/latex_service/latex.go | 9 ++++-- templates/tex/preamble | 3 ++ templates/tex/stats.tmpl | 26 +++++++++++++++ 9 files changed, 125 insertions(+), 16 deletions(-) create mode 100644 internal/csv_service/csv_service.go diff --git a/Taskfile.yml b/Taskfile.yml index a03d1b8..0231c83 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -78,3 +78,9 @@ tasks: cmds: - | rm -rf ./result + run-for-test-with-file: + desc: 'Run utility with generation of output file' + cmds: + - task: build + - | + ./colligendis collect --habr --file -v diff --git a/cmd/collect/collect.go b/cmd/collect/collect.go index 8f01eee..52e7ec2 100644 --- a/cmd/collect/collect.go +++ b/cmd/collect/collect.go @@ -29,6 +29,7 @@ import ( "github.com/spf13/cobra" "log" "strconv" + "time" ) const ( @@ -48,7 +49,8 @@ func GetCollectCommand(flags *common.ColligendisFlags, tmpls []structs.TemplateS case true: latex_service.GenerateLaTeXFiles(tmpls, flags) case false: - log.Printf("Total habr views: %s", strconv.Itoa(db_service.GetHabrViewsCount())) + var zeroTime time.Time + log.Printf("Total habr views: %s", strconv.Itoa(db_service.GetHabrViewsCount(zeroTime))) if flags.Full { getFullHabrViewsCount(flags.Limit, flags.SortType) } diff --git a/cmd/collect/functions.go b/cmd/collect/functions.go index f15d620..57cadb4 100644 --- a/cmd/collect/functions.go +++ b/cmd/collect/functions.go @@ -31,6 +31,7 @@ import ( "os" "sort" "strconv" + "time" ) func getFullHabrViewsCount(limit int, sortType string) []structs.StatsArticle { @@ -44,7 +45,8 @@ func getFullHabrViewsCount(limit int, sortType string) []structs.StatsArticle { var rowStructs []structs.StatsArticle for i, a := range articles { - stats, state := db_service.GetLatestStatsFromArticle(a.ID) + var zeroTime time.Time + stats, state := db_service.GetLatestStatsFromArticle(a.ID, zeroTime) var stat structs.StatsArticle if state { stat.Id = i diff --git a/internal/common/structs/structs.go b/internal/common/structs/structs.go index 86f98bf..e5e3917 100644 --- a/internal/common/structs/structs.go +++ b/internal/common/structs/structs.go @@ -77,6 +77,7 @@ type TemplateData struct { AuthorsTopGlobal []AuthorsTop Authors []AuthorsTop AllDates []string + StatsForDiagram []StatsForDiagram } type AuthorsTop struct { @@ -84,3 +85,8 @@ type AuthorsTop struct { ID int ArticlesCount int64 } + +type StatsForDiagram struct { + Date string + Count int +} diff --git a/internal/csv_service/csv_service.go b/internal/csv_service/csv_service.go new file mode 100644 index 0000000..25c7290 --- /dev/null +++ b/internal/csv_service/csv_service.go @@ -0,0 +1,33 @@ +package csv_service + +import ( + "colligendis/internal/common/structs" + "encoding/csv" + "log" + "os" + "path" + "strconv" +) + +func PrepareCSV(pathToFile string, fileNAme string, data []structs.StatsForDiagram) { + file, err := os.Create(path.Join(pathToFile, fileNAme)) + if err != nil { + log.Fatal(err) + } + defer file.Close() + + writer := csv.NewWriter(file) + defer writer.Flush() + writer.Comma = ',' + + writer.Write([]string{"date", "count"}) + + count := 1 + for _, d := range data { + if count != len(data) { + writer.Write([]string{d.Date, strconv.Itoa(d.Count)}) + count++ + } + } + +} diff --git a/internal/db_service/habr_sqlite.go b/internal/db_service/habr_sqlite.go index 15d8560..8c429cc 100644 --- a/internal/db_service/habr_sqlite.go +++ b/internal/db_service/habr_sqlite.go @@ -283,7 +283,7 @@ func GetLatestArticles() []domain.HabrStats { return stats } -func GetLatestStatsFromArticle(articleID uint) ([]domain.HabrStats, bool) { +func GetLatestStatsFromArticle(articleID uint, sinceDate time.Time) ([]domain.HabrStats, bool) { var stats []domain.HabrStats state := false @@ -293,11 +293,20 @@ func GetLatestStatsFromArticle(articleID uint) ([]domain.HabrStats, bool) { log.Fatal("Error opening db!") } else { state = true - db. - Where("habr_article_id = ?", articleID). - Order("date_of_stats DESC"). - Find(&stats). - Limit(2) + if !sinceDate.IsZero() { + db. + Where("habr_article_id = ?", articleID). + Where("date_of_stats <= ?", sinceDate). + Order("date_of_stats DESC"). + Find(&stats). + Limit(2) + } else { + db. + Where("habr_article_id = ?", articleID). + Order("date_of_stats DESC"). + Find(&stats). + Limit(2) + } } if len(stats) > 1 { @@ -310,12 +319,12 @@ func GetLatestStatsFromArticle(articleID uint) ([]domain.HabrStats, bool) { return stats, state } -func GetHabrViewsCount() int { +func GetHabrViewsCount(sinceDate time.Time) int { articles := GetAllHabrArticles("") count := 0 for _, a := range articles { - stats, state := GetLatestStatsFromArticle(a.ID) + stats, state := GetLatestStatsFromArticle(a.ID, sinceDate) if state { if len(stats) > 1 { diff := stats[1].Views - stats[0].Views @@ -357,7 +366,8 @@ func GetArticlesFormLastPeriod(dt time.Time, getAll bool, global bool) (int, []s var latestArts []structs.StatsArticle articles := GetAllHabrArticles("") for i, a := range articles { - stats, state := GetLatestStatsFromArticle(a.ID) + var zeroTime time.Time + stats, state := GetLatestStatsFromArticle(a.ID, zeroTime) var stat structs.StatsArticle if state { stat.Id = i @@ -450,10 +460,11 @@ func GetCountOfStats() int64 { return count } -func GetAllDatesOfStats() []string { +func GetAllDatesOfStats() ([]string, []time.Time) { var dates []string var stats []domain.HabrStats + var timeDates []time.Time db, err := gorm.Open(sqlite.Open("colligendis.db"), &gorm.Config{Logger: logger.Default.LogMode(getLogger())}) @@ -464,11 +475,26 @@ func GetAllDatesOfStats() []string { Group("date_of_stats"). Order("date_of_stats DESC"). Find(&stats) - for _, stat := range stats { + timeDates = append(timeDates, stat.DateOfStats) dates = append(dates, stat.DateOfStats.Format("January 2, 2006")) } } - return dates + return dates, timeDates +} + +func GetAllStatsAndDatesForDiagram() []structs.StatsForDiagram { + var statsForDiagram []structs.StatsForDiagram + + _, dates := GetAllDatesOfStats() + + for i := 0; i < len(dates); i++ { + var st structs.StatsForDiagram + st.Date = dates[i].Format("2006-01-02") + st.Count = GetHabrViewsCount(dates[i]) + statsForDiagram = append(statsForDiagram, st) + } + + return statsForDiagram } diff --git a/internal/latex_service/latex.go b/internal/latex_service/latex.go index 3ec200b..5327f39 100644 --- a/internal/latex_service/latex.go +++ b/internal/latex_service/latex.go @@ -4,6 +4,7 @@ import ( "colligendis/cmd/common" "colligendis/cmd/version" "colligendis/internal/common/structs" + "colligendis/internal/csv_service" "colligendis/internal/db_service" "fmt" "html/template" @@ -50,7 +51,8 @@ func getHabrData() structs.TemplateData { data.Version = version.GetVersion() data.StatsInBaseCount = db_service.GetCountOfStats() - data.AllViewsCount = db_service.GetHabrViewsCount() + var zeroTime time.Time + data.AllViewsCount = db_service.GetHabrViewsCount(zeroTime) data.PreviousDate, data.LatestDate = getDates() data.ArticlesCount = db_service.GetHabrArticlesCount() pd, _ := time.Parse("2006-01-02", data.PreviousDate) @@ -64,7 +66,10 @@ func getHabrData() structs.TemplateData { data.AuthorsTopGlobal = db_service.GetTopOfAuthors(false) data.AuthorsTopGlobal = data.AuthorsTopGlobal[0:5] data.Authors = db_service.GetTopOfAuthors(true) - data.AllDates = db_service.GetAllDatesOfStats() + data.AllDates, _ = db_service.GetAllDatesOfStats() + data.StatsForDiagram = db_service.GetAllStatsAndDatesForDiagram() + + csv_service.PrepareCSV("tmp", "articlesCount.csv", data.StatsForDiagram) return data } diff --git a/templates/tex/preamble b/templates/tex/preamble index 69c67c8..3153b98 100644 --- a/templates/tex/preamble +++ b/templates/tex/preamble @@ -22,6 +22,9 @@ \usepackage{listings} \usepackage{float} \usepackage{longtable} +\usepackage{pgfplots} +\pgfplotsset{compat=1.9} +\usepgfplotslibrary{dateplot} \usepackage{tocloft} \usepackage{misccorr} \usepackage{graphicx} diff --git a/templates/tex/stats.tmpl b/templates/tex/stats.tmpl index e15db0c..8135ed1 100644 --- a/templates/tex/stats.tmpl +++ b/templates/tex/stats.tmpl @@ -102,6 +102,32 @@ {{ end }} \caption{Все авторы блога} \end{longtable} + \subsection{Графики изменений} + \subsubsection{График просмотров за последние N недель} + \begin{tikzpicture} + \begin{axis}[ + xlabel={Дата статистики}, + ylabel={Кол-во просмотров}, + scaled ticks=false, + legend pos = north west, + table/col sep = semicolon, + width = 0.85\paperwidth, + grid = major, + date coordinates in=x, + date ZERO=2024-05-01, % <-- needs to be set for v1.12 and below + xtick=data, + xticklabel style={ + rotate=90, + anchor=near xticklabel, + }, + yticklabel style={/pgf/number format/fixed}, + % set the label style of the `xtick's + xticklabel=\day.\month.\year, + ] + \legend{Просмоты за период (неделя)}; + \addplot table [col sep=comma,x=date,y=count] {articlesCount.csv}; + \end{axis} + \end{tikzpicture} \section{Системная информация} \subsection{Хабр} Всего записей статистики в базе данных: {{ .StatsInBaseCount }}: