Skip to content

Commit

Permalink
Merge branch 'getLivestreamStatics'
Browse files Browse the repository at this point in the history
  • Loading branch information
wtks committed Nov 25, 2023
2 parents 57e0f38 + 58192c4 commit 158c68d
Showing 1 changed file with 89 additions and 33 deletions.
122 changes: 89 additions & 33 deletions app/go/stats_handler.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package main

import (
"context"
"database/sql"
"errors"
"net/http"
"sort"
"strconv"

"github.com/jmoiron/sqlx"
"github.com/labstack/echo/v4"
)

Expand Down Expand Up @@ -227,30 +229,66 @@ func getLivestreamStatisticsHandler(c echo.Context) error {
}
}

var livestreams []*LivestreamModel
if err := tx.SelectContext(ctx, &livestreams, "SELECT * FROM livestreams"); err != nil && !errors.Is(err, sql.ErrNoRows) {
var livestreams []struct {
ID int64 `db:"id"`
}
if err := tx.SelectContext(ctx, &livestreams, "SELECT id FROM livestreams"); err != nil && !errors.Is(err, sql.ErrNoRows) {
return echo.NewHTTPError(http.StatusInternalServerError, "failed to get livestreams: "+err.Error())
}

// ランク算出
var ranking LivestreamRanking
for _, livestream := range livestreams {
var reactions int64
if err := tx.GetContext(ctx, &reactions, "SELECT COUNT(*) FROM livestreams l INNER JOIN reactions r ON l.id = r.livestream_id WHERE l.id = ?", livestream.ID); err != nil && !errors.Is(err, sql.ErrNoRows) {
return echo.NewHTTPError(http.StatusInternalServerError, "failed to count reactions: "+err.Error())
}
data := map[int64]LivestreamRankingEntry{}
for _, s := range livestreams {
data[s.ID] = LivestreamRankingEntry{LivestreamID: s.ID}
}

var totalTips int64
if err := tx.GetContext(ctx, &totalTips, "SELECT IFNULL(SUM(l2.tip), 0) FROM livestreams l INNER JOIN livecomments l2 ON l.id = l2.livestream_id WHERE l.id = ?", livestream.ID); err != nil && !errors.Is(err, sql.ErrNoRows) {
return echo.NewHTTPError(http.StatusInternalServerError, "failed to count tips: "+err.Error())
}
type LiveReaction struct {
ID int64 `db:"id"`
Reactions int64 `db:"reactions"`
}
var reactions []*LiveReaction
if err := tx.SelectContext(ctx, &reactions, `
SELECT
r.livestream_id AS id,
COUNT(*) AS reactions
FROM reactions r
GROUP BY r.livestream_id
`); err != nil && !errors.Is(err, sql.ErrNoRows) {
return echo.NewHTTPError(http.StatusInternalServerError, "failed to get livestreams: "+err.Error())
}

score := reactions + totalTips
ranking = append(ranking, LivestreamRankingEntry{
LivestreamID: livestream.ID,
Score: score,
})
type LiveTotalTip struct {
ID int64 `db:"id"`
TotalTips int64 `db:"total_tips"`
}
var tips []*LiveTotalTip
if err := tx.SelectContext(ctx, &tips, `
SELECT
l2.livestream_id AS id,
IFNULL(SUM(l2.tip), 0) AS total_tips
FROM livecomments l2
GROUP BY l2.livestream_id
`); err != nil && !errors.Is(err, sql.ErrNoRows) {
return echo.NewHTTPError(http.StatusInternalServerError, "failed to get livestreams: "+err.Error())
}

// ランク算出
for _, reaction := range reactions {
d := data[reaction.ID]
d.Score += reaction.Reactions
data[reaction.ID] = d
}
totalReactions := data[livestream.ID].Score
for _, tip := range tips {
d := data[tip.ID]
d.Score += tip.TotalTips
data[tip.ID] = d
}

var ranking = make(LivestreamRanking, 0, len(data))
for _, entry := range data {
ranking = append(ranking, entry)
}

sort.Sort(ranking)

var rank int64 = 1
Expand All @@ -262,27 +300,18 @@ func getLivestreamStatisticsHandler(c echo.Context) error {
rank++
}

// 視聴者数算出
var viewersCount int64
if err := tx.GetContext(ctx, &viewersCount, `SELECT COUNT(*) FROM livestreams l INNER JOIN livestream_viewers_history h ON h.livestream_id = l.id WHERE l.id = ?`, livestreamID); err != nil && !errors.Is(err, sql.ErrNoRows) {
viewersCount, err := calcViewerCount(tx, ctx, livestreamID)
if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, "failed to count livestream viewers: "+err.Error())
}

// 最大チップ額
var maxTip int64
if err := tx.GetContext(ctx, &maxTip, `SELECT IFNULL(MAX(tip), 0) FROM livestreams l INNER JOIN livecomments l2 ON l2.livestream_id = l.id WHERE l.id = ?`, livestreamID); err != nil && !errors.Is(err, sql.ErrNoRows) {
maxTip, err := calcMaxTip(tx, ctx, livestreamID)
if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, "failed to find maximum tip livecomment: "+err.Error())
}

// リアクション数
var totalReactions int64
if err := tx.GetContext(ctx, &totalReactions, "SELECT COUNT(*) FROM livestreams l INNER JOIN reactions r ON r.livestream_id = l.id WHERE l.id = ?", livestreamID); err != nil && !errors.Is(err, sql.ErrNoRows) {
return echo.NewHTTPError(http.StatusInternalServerError, "failed to count total reactions: "+err.Error())
}

// スパム報告数
var totalReports int64
if err := tx.GetContext(ctx, &totalReports, `SELECT COUNT(*) FROM livestreams l INNER JOIN livecomment_reports r ON r.livestream_id = l.id WHERE l.id = ?`, livestreamID); err != nil && !errors.Is(err, sql.ErrNoRows) {
totalReports, err := calcTotalReports(tx, ctx, livestreamID)
if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, "failed to count total spam reports: "+err.Error())
}

Expand All @@ -298,3 +327,30 @@ func getLivestreamStatisticsHandler(c echo.Context) error {
TotalReports: totalReports,
})
}

// スパム報告数
func calcTotalReports(tx *sqlx.Tx, ctx context.Context, livestreamID int64) (int64, error) {
var totalReports int64
if err := tx.GetContext(ctx, &totalReports, `SELECT COUNT(*) FROM livecomment_reports r WHERE r.livestream_id = ? GROUP BY r.livestream_id`, livestreamID); err != nil && !errors.Is(err, sql.ErrNoRows) {
return 0, err
}
return totalReports, nil
}

// 最大チップ額
func calcMaxTip(tx *sqlx.Tx, ctx context.Context, livestreamID int64) (int64, error) {
var maxTip int64
if err := tx.GetContext(ctx, &maxTip, `SELECT IFNULL(MAX(tip), 0) FROM livecomments l2 WHERE l2.livestream_id = ? GROUP BY l2.livestream_id`, livestreamID); err != nil && !errors.Is(err, sql.ErrNoRows) {
return 0, err
}
return maxTip, nil
}

// 視聴者数算出
func calcViewerCount(tx *sqlx.Tx, ctx context.Context, livestreamID int64) (int64, error) {
var viewersCount int64
if err := tx.GetContext(ctx, &viewersCount, `SELECT COUNT(*) FROM livestream_viewers_history h WHERE h.livestream_id = ? GROUP BY h.livestream_id`, livestreamID); err != nil && !errors.Is(err, sql.ErrNoRows) {
return 0, err
}
return viewersCount, nil
}

0 comments on commit 158c68d

Please sign in to comment.