mirror of https://github.com/jlelse/GoBlog
Blogstats with months (on click)
This commit is contained in:
parent
9d63d0632e
commit
47ddcc4028
54
blogstats.go
54
blogstats.go
|
@ -2,15 +2,17 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
func serveBlogStats(w http.ResponseWriter, r *http.Request) {
|
func serveBlogStats(w http.ResponseWriter, r *http.Request) {
|
||||||
blog := r.Context().Value(blogContextKey).(string)
|
blog := r.Context().Value(blogContextKey).(string)
|
||||||
// Build query
|
// Build query
|
||||||
query, params := buildPostsQuery(&postsRequestConfig{
|
prq := &postsRequestConfig{
|
||||||
blog: blog,
|
blog: blog,
|
||||||
status: statusPublished,
|
status: statusPublished,
|
||||||
})
|
}
|
||||||
|
query, params := buildPostsQuery(prq)
|
||||||
// Count total posts
|
// Count total posts
|
||||||
row, err := appDbQueryRow("select count(distinct path) from ("+query+")", params...)
|
row, err := appDbQueryRow("select count(distinct path) from ("+query+")", params...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -28,21 +30,55 @@ func serveBlogStats(w http.ResponseWriter, r *http.Request) {
|
||||||
serveError(w, r, err.Error(), http.StatusInternalServerError)
|
serveError(w, r, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var years, counts []int
|
var years []stringPair
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var year, count int
|
var year, count string
|
||||||
if err = rows.Scan(&year, &count); err == nil {
|
if err = rows.Scan(&year, &count); err == nil {
|
||||||
years = append(years, year)
|
years = append(years, stringPair{year, count})
|
||||||
counts = append(counts, count)
|
} else {
|
||||||
|
serveError(w, r, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Count posts without date
|
||||||
|
row, err = appDbQueryRow("select count(distinct path) from ("+query+") where published = ''", params...)
|
||||||
|
if err != nil {
|
||||||
|
serveError(w, r, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var noDateCount int
|
||||||
|
if err = row.Scan(&noDateCount); err != nil {
|
||||||
|
serveError(w, r, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Count posts per month per year
|
||||||
|
months := map[string][]stringPair{}
|
||||||
|
for _, year := range years {
|
||||||
|
prq.publishedYear, _ = strconv.Atoi(year.First)
|
||||||
|
query, params = buildPostsQuery(prq)
|
||||||
|
rows, err = appDbQuery("select substr(published, 6, 2) as month, count(distinct path) as count from ("+query+") where published != '' group by month order by month desc", params...)
|
||||||
|
if err != nil {
|
||||||
|
serveError(w, r, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for rows.Next() {
|
||||||
|
var month, count string
|
||||||
|
if err = rows.Scan(&month, &count); err == nil {
|
||||||
|
months[year.First] = append(months[year.First], stringPair{month, count})
|
||||||
|
} else {
|
||||||
|
serveError(w, r, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
render(w, r, templateBlogStats, &renderData{
|
render(w, r, templateBlogStats, &renderData{
|
||||||
BlogString: blog,
|
BlogString: blog,
|
||||||
Canonical: blogPath(blog) + appConfig.Blogs[blog].BlogStats.Path,
|
Canonical: blogPath(blog) + appConfig.Blogs[blog].BlogStats.Path,
|
||||||
Data: map[string]interface{}{
|
Data: map[string]interface{}{
|
||||||
"total": totalCount,
|
"total": totalCount,
|
||||||
"years": years,
|
"years": years,
|
||||||
"counts": counts,
|
"withoutdate": noDateCount,
|
||||||
|
"months": months,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
12
check.go
12
check.go
|
@ -36,10 +36,10 @@ func checkAllExternalLinks() {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
for postLinkPair := range linkChan {
|
for postLinkPair := range linkChan {
|
||||||
rm.RLock()
|
rm.RLock()
|
||||||
_, ok := responses[postLinkPair.second]
|
_, ok := responses[postLinkPair.Second]
|
||||||
rm.RUnlock()
|
rm.RUnlock()
|
||||||
if !ok {
|
if !ok {
|
||||||
req, err := http.NewRequest(http.MethodGet, postLinkPair.second, nil)
|
req, err := http.NewRequest(http.MethodGet, postLinkPair.Second, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err.Error())
|
fmt.Println(err.Error())
|
||||||
continue
|
continue
|
||||||
|
@ -50,19 +50,19 @@ func checkAllExternalLinks() {
|
||||||
req.Header.Set("Accept-Language", "en-US,en;q=0.5")
|
req.Header.Set("Accept-Language", "en-US,en;q=0.5")
|
||||||
resp, err := client.Do(req)
|
resp, err := client.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(postLinkPair.second+" ("+postLinkPair.first+"):", err.Error())
|
fmt.Println(postLinkPair.Second+" ("+postLinkPair.First+"):", err.Error())
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
status := resp.StatusCode
|
status := resp.StatusCode
|
||||||
_, _ = io.Copy(io.Discard, resp.Body)
|
_, _ = io.Copy(io.Discard, resp.Body)
|
||||||
resp.Body.Close()
|
resp.Body.Close()
|
||||||
rm.Lock()
|
rm.Lock()
|
||||||
responses[postLinkPair.second] = status
|
responses[postLinkPair.Second] = status
|
||||||
rm.Unlock()
|
rm.Unlock()
|
||||||
}
|
}
|
||||||
rm.RLock()
|
rm.RLock()
|
||||||
if response, ok := responses[postLinkPair.second]; ok && !checkSuccessStatus(response) {
|
if response, ok := responses[postLinkPair.Second]; ok && !checkSuccessStatus(response) {
|
||||||
fmt.Println(postLinkPair.second+" ("+postLinkPair.first+"):", response)
|
fmt.Println(postLinkPair.Second+" ("+postLinkPair.First+"):", response)
|
||||||
}
|
}
|
||||||
rm.RUnlock()
|
rm.RUnlock()
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
(function () {
|
||||||
|
Array.from(document.getElementsByClassName('statsyear')).forEach(element => {
|
||||||
|
element.addEventListener('click', function () {
|
||||||
|
Array.from(document.getElementsByClassName('statsmonth')).forEach(c => {
|
||||||
|
if (element.dataset.year == c.dataset.year) {
|
||||||
|
c.classList.contains('hide') ? c.classList.remove('hide') : c.classList.add('hide')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})()
|
|
@ -14,19 +14,30 @@
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{{ $counts := .Data.counts }}
|
{{ $months := .Data.months }}
|
||||||
{{ range $i, $year := .Data.years }}
|
{{ range $year := .Data.years }}
|
||||||
<tr>
|
<tr class="statsyear" data-year="{{ $year.First }}">
|
||||||
<td class="tal">{{ $year }}</td>
|
<td class="tal"><b>{{ $year.First }}</b></td>
|
||||||
<td class="tar">{{ index $counts $i }}</td>
|
<td class="tar">{{ $year.Second }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
{{ range $month := (index $months $year.First) }}
|
||||||
|
<tr class="statsmonth hide" data-year="{{ $year.First }}">
|
||||||
|
<td class="tal">{{ $month.First }}</td>
|
||||||
|
<td class="tar">{{ $month.Second }}</td>
|
||||||
|
</tr>
|
||||||
|
{{ end }}
|
||||||
{{ end }}
|
{{ end }}
|
||||||
<tr>
|
<tr>
|
||||||
<td class="tal"><b>{{ string .Blog.Lang "total" }}</b></td>
|
<td class="tal"><b>{{ string .Blog.Lang "withoutdate" }}</b></td>
|
||||||
|
<td class="tar">{{ .Data.withoutdate }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="tal"><u><b>{{ string .Blog.Lang "total" }}</b></u></td>
|
||||||
<td class="tar">{{ .Data.total }}</td>
|
<td class="tar">{{ .Data.total }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
<script defer src="{{ asset "js/blogstats.js" }}"></script>
|
||||||
</main>
|
</main>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
|
|
|
@ -29,4 +29,5 @@ update: "Aktualisieren"
|
||||||
updatedon: "Aktualisiert am"
|
updatedon: "Aktualisiert am"
|
||||||
upload: "Hochladen"
|
upload: "Hochladen"
|
||||||
view: "Anschauen"
|
view: "Anschauen"
|
||||||
|
withoutdate: "Ohne Datum"
|
||||||
year: "Jahr"
|
year: "Jahr"
|
|
@ -47,4 +47,5 @@ verified: "Verified"
|
||||||
view: "View"
|
view: "View"
|
||||||
webmentions: "Webmentions"
|
webmentions: "Webmentions"
|
||||||
websiteopt: "Website (optional)"
|
websiteopt: "Website (optional)"
|
||||||
|
withoutdate: "Without date"
|
||||||
year: "Year"
|
year: "Year"
|
Loading…
Reference in New Issue