Skip to content

Commit

Permalink
Admin stats (#101)
Browse files Browse the repository at this point in the history
* refactoring

* fixing issues

* fixing layout

* admin stats scheduling

* scheduler for admin stats

---------

Co-authored-by: Maksym Bilan <>
  • Loading branch information
maximbilan authored Dec 26, 2024
1 parent 00bfb2d commit f01e14b
Show file tree
Hide file tree
Showing 7 changed files with 158 additions and 113 deletions.
43 changes: 4 additions & 39 deletions internal/app/admin.go
Original file line number Diff line number Diff line change
@@ -1,58 +1,23 @@
package app

import (
"fmt"
"log"

"github.com/capymind/internal/translator"
)

func getTotalUserCount(session *Session) *string {
count, err := adminStorage.GetTotalUserCount(session.Context)
if err != nil {
log.Printf("[Admin] Error during fetching total user count: %v", err)
return nil
}
message := fmt.Sprintf(translator.Translate(session.Locale(), "total_user_count"), count)
return &message
}
import "github.com/capymind/internal/helpers"

func handleTotalUserCount(session *Session) {
message := getTotalUserCount(session)
message := helpers.GetTotalUserCount(session.Context, session.Locale())
if message != nil {
setOutputText(*message, session)
}
}

func getTotalActiveUserCount(session *Session) *string {
count, err := adminStorage.GetActiveUserCount(session.Context)
if err != nil {
log.Printf("[Admin] Error during fetching active user count: %v", err)
return nil
}
message := fmt.Sprintf(translator.Translate(session.Locale(), "total_active_user_count"), count)
return &message
}

func handleTotalActiveUserCount(session *Session) {
message := getTotalActiveUserCount(session)
message := helpers.GetTotalActiveUserCount(session.Context, session.Locale())
if message != nil {
setOutputText(*message, session)
}
}

func getTotalNoteCount(session *Session) *string {
count, err := adminStorage.GetTotalNoteCount(session.Context)
if err != nil {
log.Printf("[Admin] Error during fetching total note count: %v", err)
return nil
}
message := fmt.Sprintf(translator.Translate(session.Locale(), "total_note_count"), count)
return &message
}

func handleTotalNoteCount(session *Session) {
message := getTotalNoteCount(session)
message := helpers.GetTotalNoteCount(session.Context, session.Locale())
if message != nil {
setOutputText(*message, session)
}
Expand Down
28 changes: 2 additions & 26 deletions internal/app/feedback.go
Original file line number Diff line number Diff line change
@@ -1,33 +1,9 @@
package app

import (
"log"
)

func prepareFeedback(session *Session) []string {
var array []string
array = append(array, "feedback_last_week")
array = append(array, "\n\n")

feedback, err := feedbackStorage.GetFeedbackForLastWeek(session.Context)
if err != nil {
log.Printf("[Bot] Error getting feedbacks from firestore, %s", err.Error())
}

if len(feedback) == 0 {
array = append(array, "no_feedback")
return array
}

for _, f := range feedback {
array = append(array, *f.User.FirstName+" "+*f.User.LastName+":"+"\n"+f.Feedback.Text+"\n\n")
}

return array
}
import "github.com/capymind/internal/helpers"

func handleFeedbackLastWeek(session *Session) {
array := prepareFeedback(session)
array := helpers.PrepareFeedback(session.Context, session.Locale())
for _, item := range array {
setOutputText(item, session)
}
Expand Down
56 changes: 8 additions & 48 deletions internal/app/stats.go
Original file line number Diff line number Diff line change
@@ -1,55 +1,15 @@
package app

import "sync"

type statFunc func(session *Session) *string
type feedbackFunc func(session *Session) []string

var wg sync.WaitGroup
import (
"github.com/capymind/internal/helpers"
)

func handleStats(session *Session) {
totalUserCount := waitForStatFunction(getTotalUserCount, session)
totalActiveUserCount := waitForStatFunction(getTotalActiveUserCount, session)
totalNoteCount := waitForStatFunction(getTotalNoteCount, session)
feedback := waitForFeedback(prepareFeedback, session)

wg.Wait()
stats := helpers.GetStats(session.Context, session.Locale())

if totalUserCount != nil {
setOutputText(*totalUserCount, session)
var finalString string
for _, stat := range stats {
finalString += stat + "\n"
}
if totalActiveUserCount != nil {
setOutputText(*totalActiveUserCount, session)
}
if totalNoteCount != nil {
setOutputText(*totalNoteCount, session)
}

for _, item := range feedback {
setOutputText(item, session)
}
}

func waitForStatFunction(statFunc statFunc, session *Session) *string {
wg.Add(1)
ch := make(chan *string)
go func() {
defer wg.Done()
result := statFunc(session)
ch <- result
}()
result := <-ch
return result
}

func waitForFeedback(feedbackFunc feedbackFunc, session *Session) []string {
wg.Add(1)
ch := make(chan []string)
go func() {
defer wg.Done()
result := feedbackFunc(session)
ch <- result
}()
result := <-ch
return result
setOutputText(finalString, session)
}
121 changes: 121 additions & 0 deletions internal/helpers/stats.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
package helpers

import (
"context"
"fmt"
"log"
"sync"

"github.com/capymind/internal/translator"
"github.com/capymind/third_party/firestore"
)

type statFunc func(ctx *context.Context, locale translator.Locale) *string
type feedbackFunc func(ctx *context.Context, locale translator.Locale) []string

var wg sync.WaitGroup

var adminStorage firestore.AdminStorage
var feedbackStorage firestore.FeedbackStorage

func GetTotalUserCount(ctx *context.Context, locale translator.Locale) *string {
count, err := adminStorage.GetTotalUserCount(ctx)
if err != nil {
log.Printf("[Admin] Error during fetching total user count: %v", err)
return nil
}
message := fmt.Sprintf(translator.Translate(locale, "total_user_count"), count)
return &message
}

func GetTotalActiveUserCount(ctx *context.Context, locale translator.Locale) *string {
count, err := adminStorage.GetActiveUserCount(ctx)
if err != nil {
log.Printf("[Admin] Error during fetching active user count: %v", err)
return nil
}
message := fmt.Sprintf(translator.Translate(locale, "total_active_user_count"), count)
return &message
}

func GetTotalNoteCount(ctx *context.Context, locale translator.Locale) *string {
count, err := adminStorage.GetTotalNoteCount(ctx)
if err != nil {
log.Printf("[Admin] Error during fetching total note count: %v", err)
return nil
}
message := fmt.Sprintf(translator.Translate(locale, "total_note_count"), count)
return &message
}

func GetStats(ctx *context.Context, locale translator.Locale) []string {
totalUserCount := waitForStatFunction(GetTotalUserCount, ctx, locale)
totalActiveUserCount := waitForStatFunction(GetTotalActiveUserCount, ctx, locale)
totalNoteCount := waitForStatFunction(GetTotalNoteCount, ctx, locale)
feedback := waitForFeedback(PrepareFeedback, ctx, locale)

wg.Wait()

var array []string

if totalUserCount != nil {
array = append(array, *totalUserCount)
}
if totalActiveUserCount != nil {
array = append(array, *totalActiveUserCount)
}
if totalNoteCount != nil {
array = append(array, *totalNoteCount)
}

array = append(array, feedback...)

return array
}

func PrepareFeedback(ctx *context.Context, locale translator.Locale) []string {
var array []string
array = append(array, "")
array = append(array, translator.Translate(locale, "feedback_last_week"))
array = append(array, "")

feedback, err := feedbackStorage.GetFeedbackForLastWeek(ctx)
if err != nil {
log.Printf("[Bot] Error getting feedbacks from firestore, %s", err.Error())
}

if len(feedback) == 0 {
array = append(array, translator.Translate(locale, "no_feedback"))
return array
}

for _, f := range feedback {
array = append(array, *f.User.FirstName+" "+*f.User.LastName+":"+"\n"+f.Feedback.Text+"\n")
}

return array
}

func waitForStatFunction(statFunc statFunc, ctx *context.Context, locale translator.Locale) *string {
wg.Add(1)
ch := make(chan *string)
go func() {
defer wg.Done()
result := statFunc(ctx, locale)
ch <- result
}()
result := <-ch
return result
}

func waitForFeedback(feedbackFunc feedbackFunc, ctx *context.Context, locale translator.Locale) []string {
wg.Add(1)
ch := make(chan []string)
go func() {
defer wg.Done()
result := feedbackFunc(ctx, locale)
ch <- result
}()
result := <-ch
return result
}
13 changes: 13 additions & 0 deletions internal/scheduler/scheduler.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/capymind/internal/analysis"
"github.com/capymind/internal/botservice"
"github.com/capymind/internal/database"
"github.com/capymind/internal/helpers"
"github.com/capymind/internal/taskservice"
"github.com/capymind/internal/translator"
"github.com/capymind/third_party/googletasks"
Expand Down Expand Up @@ -126,6 +127,18 @@ func prepareMessage(user *database.User, ctx *context.Context, offset int, messa
} else {
return
}
} else if messageType == taskservice.AdminStats {
// Send only to admins
if !database.IsAdmin(user.Role) {
return
}
stats := helpers.GetStats(ctx, userLocale)

var finalString string
for _, stat := range stats {
finalString += stat + "\n"
}
localizedMessage = finalString
} else {
localizedMessage = translator.Translate(userLocale, message)
}
Expand Down
1 change: 1 addition & 0 deletions internal/taskservice/message_type.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const (
Evening MessageType = "evening"
WeeklyAnalysis MessageType = "weekly_analysis"
UserStats MessageType = "user_stats"
AdminStats MessageType = "admin_stats"
)

func GetMessage(messageType MessageType, weekday time.Weekday) string {
Expand Down
9 changes: 9 additions & 0 deletions scripts/schedule_jobs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ JOB1="schedule-morning-messages"
JOB2="schedule-evening-messages"
JOB3="schedule-weekly-analysis"
JOB4="schedule-motivational-messages"
JOB5="schedule-admin-stats"

JOBS=($JOB1 $JOB2 $JOB3 $JOB4)

Expand Down Expand Up @@ -48,4 +49,12 @@ gcloud scheduler jobs create http $JOB4 \
--http-method=GET \
--location=$REGION

# Every Friday
gcloud scheduler jobs create http $JOB5 \
--project $PROJECT_ID \
--uri="https://$REGION-$PROJECT_ID.cloudfunctions.net/$FUNCTION_NAME?type=admin_stats&offset=10" \
--schedule="0 0 * * 5" \
--http-method=GET \
--location=$REGION

echo "Setup complete!"

0 comments on commit f01e14b

Please sign in to comment.