Skip to content
Snippets Groups Projects
Verified Commit 581cb2e9 authored by Janne Mareike Koschinski's avatar Janne Mareike Koschinski
Browse files

More statistics

parent 97634c11
No related branches found
No related tags found
No related merge requests found
......@@ -12,6 +12,8 @@ import (
"time"
)
const DEBUG = true
type Config struct {
Database DatabaseConfig
}
......@@ -47,9 +49,10 @@ func formatTemplate(w http.ResponseWriter, templateName string, data interface{}
type ChannelData struct {
Id int
Name string
TotalCharacters int
TotalWords int
TotalLines int
Lines int
Words int
WordsPerLine float64
CharactersPerLine float64
Users []UserData
Questions []FloatEntry
Exclamations []FloatEntry
......@@ -58,8 +61,9 @@ type ChannelData struct {
EmojiSad []FloatEntry
LongestLines []FloatEntry
ShortestLines []FloatEntry
Total []IntEntry
Average float64
TotalWords []TotalEntry
AverageWords []FloatEntry
References []ReferenceData
}
type FloatEntry struct {
......@@ -72,14 +76,34 @@ type IntEntry struct {
Value int
}
type TotalEntry struct {
Name string
Value int
Previous string
}
type UserData struct {
Name string
Total int
Words int
Lines int
Words int
WordsPerLine float64
LastSeen time.Time
}
type ReferenceData struct {
Name string
LastUsed string
Count string
}
func handleError(err error) {
if DEBUG {
panic(err)
} else {
handleError(err)
}
}
func main() {
config := NewConfigFromEnv()
......@@ -95,73 +119,78 @@ func main() {
channelData := ChannelData{}
err = db.QueryRow("SELECT id, channel FROM channels WHERE channel ILIKE $1", channel).Scan(&channelData.Id, &channelData.Name)
if err != nil {
println(err.Error())
handleError(err)
return
}
err = db.QueryRow("SELECT COUNT(*), SUM(characters), SUM(words) FROM messages WHERE channel = $1", channelData.Id).Scan(&channelData.TotalLines, &channelData.TotalCharacters, &channelData.TotalWords)
err = db.QueryRow("SELECT COUNT(*), SUM(words), AVG(words), AVG(characters) FROM messages WHERE channel = $1", channelData.Id).Scan(&channelData.Lines, &channelData.Words, &channelData.WordsPerLine, &channelData.CharactersPerLine)
if err != nil {
println(err.Error())
handleError(err)
return
}
result, err := db.Query("SELECT coalesce(users.nick, '[Unknown]'), t.characters, t.words, t.lines, t.lastSeen FROM (SELECT coalesce(groups.\"group\", messages.sender) AS hash, SUM(messages.characters) as characters, SUM(messages.words) as words, COUNT(*) as lines, MAX(messages.time) AS lastSeen FROM messages LEFT JOIN groups ON messages.sender = groups.nick AND groups.channel = 1 WHERE messages.channel = 1 GROUP BY hash ORDER BY characters DESC) t LEFT JOIN users ON t.hash = users.hash LIMIT 20")
channelData.Users, err = retrieveUsers(db, channelData.Id)
if err != nil {
println(err.Error())
handleError(err)
return
}
for result.Next() {
var info UserData
err := result.Scan(&info.Name, &info.Total, &info.Words, &info.Lines, &info.LastSeen)
channelData.Questions, err = retrievePercentageStats(db, channelData.Id, "question")
if err != nil {
panic(err)
handleError(err)
return
}
channelData.Users = append(channelData.Users, info)
channelData.Exclamations, err = retrievePercentageStats(db, channelData.Id, "exclamation")
if err != nil {
handleError(err)
return
}
channelData.Questions, err = retrievePercentageStats(db, "question")
channelData.Caps, err = retrievePercentageStats(db, channelData.Id, "caps")
if err != nil {
println(err.Error())
handleError(err)
return
}
channelData.Exclamations, err = retrievePercentageStats(db, "exclamation")
channelData.EmojiHappy, err = retrievePercentageStats(db, channelData.Id, "emoji_happy")
if err != nil {
println(err.Error())
handleError(err)
return
}
channelData.Caps, err = retrievePercentageStats(db, "caps")
channelData.EmojiSad, err = retrievePercentageStats(db, channelData.Id, "emoji_sad")
if err != nil {
println(err.Error())
handleError(err)
return
}
channelData.EmojiHappy, err = retrievePercentageStats(db, "emoji_happy")
channelData.LongestLines, err = retrieveLongestLines(db, channelData.Id)
if err != nil {
println(err.Error())
handleError(err)
return
}
channelData.EmojiSad, err = retrievePercentageStats(db, "emoji_sad")
channelData.ShortestLines, err = retrieveShortestLines(db, channelData.Id)
if err != nil {
println(err.Error())
handleError(err)
return
}
channelData.LongestLines, err = retrieveLongestLines(db)
channelData.TotalWords, err = retrieveTotalWords(db, channelData.Id)
if err != nil {
println(err.Error())
handleError(err)
return
}
channelData.ShortestLines, err = retrieveShortestLines(db)
channelData.References, err = retrieveReferences(db, channelData.Id)
if err != nil {
println(err.Error())
handleError(err)
return
}
err = formatTemplate(w, "statistics", channelData)
if err != nil {
println(err.Error())
handleError(err)
return
}
} else {
......@@ -181,12 +210,12 @@ func main() {
}
}
func retrievePercentageStats(db *sql.DB, stats string) ([]FloatEntry, error) {
var data []FloatEntry
result, err := db.Query("SELECT coalesce(users.nick, '[Unknown]'), t." + stats + " FROM (SELECT coalesce(groups.\"group\", messages.sender) AS hash, round((count(nullif(messages." + stats + ", false)) * 100) :: numeric / count(*)) as " + stats + " FROM messages LEFT JOIN groups ON messages.sender = groups.nick AND groups.channel = 1 WHERE messages.channel = 1 GROUP BY hash ORDER BY " + stats + " DESC) t LEFT JOIN users ON t.hash = users.hash WHERE t." + stats + " > 0 LIMIT 2;")
func retrievePercentageStats(db *sql.DB, channel int, stats string) ([]FloatEntry, error) {
result, err := db.Query("SELECT coalesce(users.nick, '[Unknown]'), t."+stats+" FROM (SELECT coalesce(groups.\"group\", messages.sender) AS hash, round((count(nullif(messages."+stats+", false)) * 100) :: numeric / count(*)) as "+stats+" FROM messages LEFT JOIN groups ON messages.sender = groups.nick AND groups.channel = $1 WHERE messages.channel = $1 GROUP BY hash ORDER BY "+stats+" DESC) t LEFT JOIN users ON t.hash = users.hash WHERE t."+stats+" > 0 LIMIT $2;", channel, 2)
if err != nil {
return nil, err
}
var data []FloatEntry
for result.Next() {
var info FloatEntry
err := result.Scan(&info.Name, &info.Value)
......@@ -198,12 +227,12 @@ func retrievePercentageStats(db *sql.DB, stats string) ([]FloatEntry, error) {
return data, nil
}
func retrieveLongestLines(db *sql.DB) ([]FloatEntry, error) {
var data []FloatEntry
result, err := db.Query("SELECT coalesce(users.nick, '[Unknown]'), t.average FROM (SELECT coalesce(groups.\"group\", messages.sender) AS hash, avg(messages.characters) as average FROM messages LEFT JOIN groups ON messages.sender = groups.nick AND groups.channel = 1 WHERE messages.channel = 1 GROUP BY hash ORDER BY average DESC) t LEFT JOIN users ON t.hash = users.hash LIMIT 2;")
func retrieveLongestLines(db *sql.DB, channel int) ([]FloatEntry, error) {
result, err := db.Query("SELECT coalesce(users.nick, '[Unknown]'), t.average FROM (SELECT coalesce(groups.\"group\", messages.sender) AS hash, avg(messages.characters) as average FROM messages LEFT JOIN groups ON messages.sender = groups.nick AND groups.channel = $1 WHERE messages.channel = $1 GROUP BY hash ORDER BY average DESC) t LEFT JOIN users ON t.hash = users.hash LIMIT $2;", channel, 2)
if err != nil {
return nil, err
}
var data []FloatEntry
for result.Next() {
var info FloatEntry
err := result.Scan(&info.Name, &info.Value)
......@@ -215,12 +244,12 @@ func retrieveLongestLines(db *sql.DB) ([]FloatEntry, error) {
return data, nil
}
func retrieveShortestLines(db *sql.DB) ([]FloatEntry, error) {
var data []FloatEntry
result, err := db.Query("SELECT coalesce(users.nick, '[Unknown]'), t.average FROM (SELECT coalesce(groups.\"group\", messages.sender) AS hash, avg(messages.characters) as average FROM messages LEFT JOIN groups ON messages.sender = groups.nick AND groups.channel = 1 WHERE messages.channel = 1 GROUP BY hash ORDER BY average DESC) t LEFT JOIN users ON t.hash = users.hash LIMIT 2;")
func retrieveShortestLines(db *sql.DB, channel int) ([]FloatEntry, error) {
result, err := db.Query("SELECT coalesce(users.nick, '[Unknown]'), t.average FROM (SELECT coalesce(groups.\"group\", messages.sender) AS hash, avg(messages.characters) as average FROM messages LEFT JOIN groups ON messages.sender = groups.nick AND groups.channel = $1 WHERE messages.channel = $1 GROUP BY hash ORDER BY average DESC) t LEFT JOIN users ON t.hash = users.hash LIMIT $2;", channel, 2)
if err != nil {
return nil, err
}
var data []FloatEntry
for result.Next() {
var info FloatEntry
err := result.Scan(&info.Name, &info.Value)
......@@ -231,3 +260,57 @@ func retrieveShortestLines(db *sql.DB) ([]FloatEntry, error) {
}
return data, nil
}
func retrieveTotalWords(db *sql.DB, channel int) ([]TotalEntry, error) {
result, err := db.Query("SELECT coalesce(users.nick, '[Unknown]'), t.words FROM (SELECT coalesce(groups.\"group\", messages.sender) AS hash, SUM(messages.words) as words FROM messages LEFT JOIN groups ON messages.sender = groups.nick AND groups.channel = $1 WHERE messages.channel = $1 GROUP BY hash ORDER BY words DESC) t LEFT JOIN users ON t.hash = users.hash LIMIT $2", channel, 2)
if err != nil {
return nil, err
}
var data []TotalEntry
previous := ""
for result.Next() {
var info TotalEntry
err := result.Scan(&info.Name, &info.Value)
if err != nil {
panic(err)
}
info.Previous = previous
previous = info.Name
data = append(data, info)
}
return data, nil
}
func retrieveUsers(db *sql.DB, channel int) ([]UserData, error) {
result, err := db.Query("SELECT coalesce(users.nick, '[Unknown]'), t.lines, t.words, t.wordsPerLine, t.lastSeen FROM (SELECT coalesce(groups.\"group\", messages.sender) AS hash, COUNT(*) as lines, SUM(messages.words) as words, AVG(messages.words) as wordsPerLine, MAX(messages.time) AS lastSeen FROM messages LEFT JOIN groups ON messages.sender = groups.nick AND groups.channel = $1 WHERE messages.channel = $1 GROUP BY hash ORDER BY lines DESC) t LEFT JOIN users ON t.hash = users.hash LIMIT $2", channel, 20)
if err != nil {
return nil, err
}
var data []UserData
for result.Next() {
var info UserData
err := result.Scan(&info.Name, &info.Lines, &info.Words, &info.WordsPerLine, &info.LastSeen)
if err != nil {
panic(err)
}
data = append(data, info)
}
return data, nil
}
func retrieveReferences(db *sql.DB, channel int) ([]ReferenceData, error) {
result, err := db.Query("SELECT coalesce(u1.nick, '[Unknown]') as target, t.count, coalesce(u2.nick, '[Unknown]') AS lastUsed FROM (SELECT coalesce(g1.\"group\", t.target) AS target, t.count, coalesce(g2.\"group\", \"references\".source) AS lastUsed FROM (SELECT \"references\".target AS target, COUNT(*) as count, MAX(id) AS lastUsed FROM \"references\" WHERE \"references\".channel = $1 GROUP BY target) t JOIN \"references\" ON t.lastUsed = \"references\".id LEFT JOIN groups g1 ON \"references\".source = g1.nick AND g1.channel = $1 LEFT JOIN groups g2 ON t.target = g2.nick AND g2.channel = $1) t LEFT JOIN users u1 ON t.target = u1.hash LEFT JOIN users u2 ON t.lastUsed = u2.hash ORDER BY count DESC LIMIT $2", channel, 5)
if err != nil {
return nil, err
}
var data []ReferenceData
for result.Next() {
var info ReferenceData
err := result.Scan(&info.Name, &info.Count, &info.LastUsed)
if err != nil {
panic(err)
}
data = append(data, info)
}
return data, nil
}
......@@ -20,18 +20,18 @@
<meta name="apple-mobile-web-app-status-bar-style" content="#FFC107">
<link href="/assets/css/style.css" rel="stylesheet">
<p>Total: {{.TotalCharacters}} Characters, {{.TotalWords}} Words, {{.TotalLines}} Lines</p>
<p>Total: {{.Lines}} Lines, {{.Words}} Words, {{printf "%.1f" .WordsPerLine}} Words per Line</p>
<table>
<thead>
<tr>
<th colspan="3">Most active nicks</th>
<th colspan="5">Most active nicks</th>
</tr>
<tr>
<th>Nick</th>
<th>Number of Characters</th>
<th>Number of Words</th>
<th>Number of Lines</th>
<th>Number of Words</th>
<th>Words per Line</th>
<th>Last seen</th>
</tr>
</thead>
......@@ -39,9 +39,9 @@
{{range .Users}}
<tr>
<td>{{.Name}}</td>
<td>{{.Total}}</td>
<td>{{.Words}}</td>
<td>{{.Lines}}</td>
<td>{{.Words}}</td>
<td>{{printf "%.1f" .WordsPerLine}}</td>
<td>{{.LastSeen.Format "2006-01-02"}}</td>
</tr>
{{end}}
......@@ -131,6 +131,9 @@
</tr>
{{end}}
{{end}}
<tr>
<td>{{.Name}} average was {{printf "%.1f" .CharactersPerLine}} letters per line.</td>
</tr>
</tbody>
<tbody>
{{range $i, $e := .ShortestLines}}
......@@ -145,4 +148,53 @@
{{end}}
{{end}}
</tbody>
<tbody>
{{range $i, $e := .TotalWords}}
{{with $e}}
<tr>
{{if eq $i 0}}
<td><b>{{.Name}}</b> spoke a total of {{.Value}} words!</td>
{{ else }}
<td>{{.Previous}}'s faithful follower, <b>{{.Name}}</b>, didn't speak so much: {{.Value}} words.</td>
{{end}}
</tr>
{{end}}
{{end}}
</tbody>
<tbody>
{{range $i, $e := .AverageWords}}
{{with $e}}
<tr>
{{if eq $i 0}}
<td><b>{{.Name}}</b> wrote an average of {{printf "%.1f" .Value}} words per line.</td>
{{end}}
</tr>
{{end}}
{{end}}
<tr>
<td>Channel average was {{printf "%.1f" .WordsPerLine}} words per line.</td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr>
<th colspan="3">Most referenced nicks</th>
</tr>
<tr>
<th>Nick</th>
<th>Number of Uses</th>
<th>Last Used by</th>
</tr>
</thead>
<tbody>
{{range .References}}
<tr>
<td>{{.Name}}</td>
<td>{{.Count}}</td>
<td>{{.LastUsed}}</td>
</tr>
{{end}}
</tbody>
</table>
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment