Skip to content

Commit

Permalink
Watched state determined automatically (#1350)
Browse files Browse the repository at this point in the history
* Watched state determined automatically

* Fixed gofumpt

* Added watched state if only silence after it

* Fixed errors

* Fixed gofumpt

* Fixed bug

* Fixed bug

* Fixed bug

* Fixed some things and cleaned up code

* Fixed gofumpt

* Fixed test

* Fixed golangci-lint

* Removed test

* Removed debug messages

* Added comment

* gofumpted

* Fixed a bug
  • Loading branch information
SebiWrn authored May 2, 2024
1 parent 759d9de commit 9aa428e
Show file tree
Hide file tree
Showing 8 changed files with 92 additions and 12 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ bin
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf
.idea/copilot/

# Generated files
.idea/**/contentModel.xml
Expand Down
13 changes: 8 additions & 5 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ linters:
run:
go: '1.21'
timeout: 10m
skip-dirs:
- node_modules
- template
# skip-dirs:
# - node_modules
# - template

linters-settings:
stylecheck:
Expand Down Expand Up @@ -67,14 +67,17 @@ linters-settings:
- name: modifies-value-receiver
gofumpt:
extra-rules: false
lang-version: "1.21"
#lang-version: "1.21"

issues:
max-issues-per-linter: 0
max-same-issues: 0
new: true
new-from-rev: dev
fix: false
fix: false
exclude-dirs:
- node_modules
- template
exclude-rules:
# Exclude some linters from running on tests files.
- path: _test\.go
Expand Down
2 changes: 2 additions & 0 deletions .idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion api/info-pages.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ func (r infoPageRoutes) updateText(c *gin.Context) {
RawContent: reqBody.RawContent,
Type: reqBody.Type,
})

if err != nil {
_ = c.Error(tools.RequestError{
Status: http.StatusInternalServerError,
Expand Down
32 changes: 32 additions & 0 deletions api/progress.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ package api

import (
"errors"
"math"
"net/http"
"slices"
"strconv"
"sync"
"time"
Expand Down Expand Up @@ -114,10 +116,40 @@ func (r progressRoutes) saveProgress(c *gin.Context) {
})
return
}

stream, err := r.DaoWrapper.StreamsDao.GetStreamByID(c, strconv.FormatUint(uint64(request.StreamID), 10))
if err != nil {
return
}

watchedToLastSilence := false

// logger.Debug("Save progress")
duration := stream.Duration.Int32
if duration == 0 {
dur := stream.End.Sub(stream.Start)
duration += int32(dur.Seconds()) + int32(dur.Minutes())*60 + int32(dur.Minutes())*60*60
}
// logger.Debug("Duration", "duration", duration)
if duration != 0 && len(stream.Silences) > 0 {
lastSilence := slices.MaxFunc(stream.Silences, func(silence model.Silence, other model.Silence) int {
return int(silence.End) - int(other.End)
})

// Add a little wiggle time to the end if ffmpeg didn't detect the silence till the end
if math.Abs(float64(lastSilence.End-uint(duration))) < 10 {
lastSilencePercent := float64(lastSilence.Start) / float64(duration)
if request.Progress >= lastSilencePercent {
watchedToLastSilence = true
}
}
}

progressBuff.add(model.StreamProgress{
Progress: request.Progress,
StreamID: request.StreamID,
UserID: tumLiveContext.User.ID,
Watched: request.Progress > .9 || watchedToLastSilence,
})
}

Expand Down
17 changes: 15 additions & 2 deletions api/progress_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package api

import (
"database/sql"
"errors"
"fmt"
"net/http"
Expand Down Expand Up @@ -29,7 +30,7 @@ func TestProgressReport(t *testing.T) {

req := progressRequest{
StreamID: uint(1),
Progress: 0,
Progress: float64(.5),
}

gomino.TestCases{
Expand All @@ -51,7 +52,19 @@ func TestProgressReport(t *testing.T) {
ExpectedCode: http.StatusForbidden,
},
"success": {
Router: ProgressRouterWrapper,
Router: func(r *gin.Engine) {
wrapper := dao.DaoWrapper{
StreamsDao: func() dao.StreamsDao {
streamsMock := mock_dao.NewMockStreamsDao(gomock.NewController(t))
streamsMock.
EXPECT().
GetStreamByID(gomock.Any(), "1").
Return(model.Stream{Duration: sql.NullInt32{Int32: int32(20)}}, nil)
return streamsMock
}(),
}
configProgressRouter(r, wrapper)
},
Body: req,
Middlewares: testutils.GetMiddlewares(tools.ErrorHandler, testutils.TUMLiveContext(testutils.TUMLiveContextStudent)),
ExpectedCode: http.StatusOK,
Expand Down
37 changes: 33 additions & 4 deletions dao/progress.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,41 @@ func (d progressDao) GetProgressesForUser(userID uint) (r []model.StreamProgress
return r, DB.Where("user_id = ?", userID).Find(&r).Error
}

func filterProgress(progresses []model.StreamProgress, watched bool) []model.StreamProgress {
var result []model.StreamProgress
for _, progress := range progresses {
if progress.Watched == watched {
result = append(result, progress)
}
}
return result
}

// SaveProgresses saves a slice of stream progresses. If a progress already exists, it will be updated.
// We need two different methods for that because else the watched state will be overwritten.
func (d progressDao) SaveProgresses(progresses []model.StreamProgress) error {
return DB.Clauses(clause.OnConflict{
Columns: []clause.Column{{Name: "stream_id"}, {Name: "user_id"}}, // key column
DoUpdates: clause.AssignmentColumns([]string{"progress"}), // column needed to be updated
}).Create(progresses).Error
noWatched := filterProgress(progresses, false)
watched := filterProgress(progresses, true)
var err error
if len(noWatched) > 0 {
err = DB.Clauses(clause.OnConflict{
Columns: []clause.Column{{Name: "stream_id"}, {Name: "user_id"}}, // key column
DoUpdates: clause.AssignmentColumns([]string{"progress"}), // column needed to be updated
}).Create(noWatched).Error
}
var err2 error

if len(watched) > 0 {
err2 = DB.Clauses(clause.OnConflict{
Columns: []clause.Column{{Name: "stream_id"}, {Name: "user_id"}}, // key column
DoUpdates: clause.AssignmentColumns([]string{"progress", "watched"}), // column needed to be updated
}).Create(watched).Error
}

if err != nil {
return err
}
return err2
}

// SaveWatchedState creates/updates a stream progress with its corresponding watched state.
Expand Down
1 change: 1 addition & 0 deletions tools/realtime/connector/melody.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package connector

import (
"net/http"

"github.com/TUM-Dev/gocast/tools/realtime"
"github.com/gabstv/melody"
)
Expand Down

0 comments on commit 9aa428e

Please sign in to comment.