Skip to content

Commit

Permalink
commented exported functions/methods; ensured urlParams (firstSemeste…
Browse files Browse the repository at this point in the history
…r and lastSemester) validity once more
  • Loading branch information
karjo24 committed Sep 30, 2024
1 parent 15a07b5 commit ca80508
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 7 deletions.
32 changes: 25 additions & 7 deletions api/search.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ func getDefaultParameters(c *gin.Context) (*model.User, string, uint64) {
user := c.MustGet("TUMLiveContext").(tools.TUMLiveContext).User
query := c.Query("q")
limit, err := strconv.ParseUint(c.Query("limit"), 10, 16)
if err != nil || limit > math.MaxInt64 { // second condition should never happen, max bitSize for parseuint is 16
if err != nil || limit > math.MaxInt64 { // second condition should never evaluate to true (maximum bitSize for ParseUint is 16)
limit = DefaultLimit
}
return user, query, limit
Expand Down Expand Up @@ -157,7 +157,7 @@ func semesterSearchHelper(c *gin.Context, m tools.MeiliSearchInterface, query st
semesters1, err1 := parseSemesters(firstSemesterParam)
semesters2, err2 := parseSemesters(lastSemesterParam)
semesters, err3 := parseSemesters(semestersParam)
if (err1 != nil || err2 != nil || len(semesters1) > 1 || len(semesters2) > 1) && err3 != nil {
if (err1 != nil || err2 != nil || len(semesters1) != 1 || len(semesters2) != 1) && err3 != nil {
return nil, errors.New("wrong parameters")
}
rangeSearch := false
Expand Down Expand Up @@ -344,8 +344,11 @@ func checkAndFillResponse(c *gin.Context, user *model.User, limit int64, daoWrap
}
}

// meilisearch filter
// meilisearch filters

// meiliSubtitleFilter returns a filter conforming to MeiliSearch filter format that can be used for filtering subtitles
//
// Checking eligibility to search in each course in courses is the caller's responsibility
func meiliSubtitleFilter(user *model.User, courses []model.Course) string {
if len(courses) == 0 {
return ""
Expand All @@ -363,6 +366,9 @@ func meiliSubtitleFilter(user *model.User, courses []model.Course) string {
return fmt.Sprintf("streamID IN %s", uintSliceToString(streamIDs))
}

// meiliStreamFilter returns a filter conforming to MeiliSearch filter format that can be used for filtering streams
//
// Checking eligibility to search for courses and validation of model.Semester format is the caller's responsibility
func meiliStreamFilter(c *gin.Context, user *model.User, semester model.Semester, courses []model.Course) string {
if courses != nil {
return fmt.Sprintf("courseID IN %s", courseSliceToString(courses))
Expand Down Expand Up @@ -394,6 +400,9 @@ func meiliStreamFilter(c *gin.Context, user *model.User, semester model.Semester
return fmt.Sprintf("(%s AND %s)", permissionFilter, semesterFilter)
}

// meiliCourseFilter returns a filter conforming to MeiliSearch filter format that can be used for filtering courses
//
// Validation of model.Semester format is the caller's responsibility
func meiliCourseFilter(c *gin.Context, user *model.User, firstSemester model.Semester, lastSemester model.Semester, semesters []model.Semester) string {
semesterFilter := meiliSemesterFilter(firstSemester, lastSemester, semesters)
if user != nil && user.Role == model.AdminType {
Expand Down Expand Up @@ -421,6 +430,9 @@ func meiliCourseFilter(c *gin.Context, user *model.User, firstSemester model.Sem
return fmt.Sprintf("(%s AND %s)", permissionFilter, semesterFilter)
}

// meiliSemesterFilter returns a filter conforming to MeiliSearch filter format
//
// Validation of model.Semester format is the caller's responsibility
func meiliSemesterFilter(firstSemester model.Semester, lastSemester model.Semester, semesters []model.Semester) string {
if len(semesters) == 0 && firstSemester.Year < 1900 && lastSemester.Year > 2800 {
return ""
Expand Down Expand Up @@ -448,7 +460,6 @@ func meiliSemesterFilter(firstSemester model.Semester, lastSemester model.Semest
return fmt.Sprintf("(%s OR (year > %d AND year < %d) OR %s)", constraint1, firstSemester.Year, lastSemester.Year, constraint2)
}
return fmt.Sprintf("(%s OR %s)", constraint1, constraint2)

}

semesterStringsSlice := make([]string, len(semesters))
Expand Down Expand Up @@ -487,7 +498,9 @@ func parseSemesters(semestersParam string) ([]model.Semester, error) {
return semesters, nil
}

// parses the URL Parameter course (urlParamCourse) and returns a slice containing every course in the parameter or an error code
// parseCourses parses the URL Parameter course (urlParamCourse) and returns a slice containing every course in the parameter or an error code
//
// Checking if the user is allowed to see returned courses is the caller's responsibility
func parseCourses(c *gin.Context, daoWrapper dao.DaoWrapper, urlParamCourse string) ([]model.Course, uint) {
coursesStrings := strings.Split(urlParamCourse, ",")

Expand Down Expand Up @@ -536,6 +549,7 @@ func uintSliceToString(ids []uint) string {
return filter
}

// ToSearchCourseDTO converts Courses to slice of SearchCourseDTO
func ToSearchCourseDTO(cs ...model.Course) []SearchCourseDTO {
res := make([]SearchCourseDTO, len(cs))
for i, c := range cs {
Expand All @@ -549,7 +563,9 @@ func ToSearchCourseDTO(cs ...model.Course) []SearchCourseDTO {
return res
}

// ToSearchStreamDTO ignores any errors and sets affected fields to zero value
// ToSearchStreamDTO converts Streams to slice of SearchStreamDTO
//
// Ignores any errors and sets affected fields to zero value
func ToSearchStreamDTO(wrapper dao.DaoWrapper, streams ...model.Stream) []SearchStreamDTO {
res := make([]SearchStreamDTO, len(streams))
for i, s := range streams {
Expand All @@ -575,7 +591,9 @@ func ToSearchStreamDTO(wrapper dao.DaoWrapper, streams ...model.Stream) []Search
return res
}

// ToSearchSubtitleDTO ignores any errors and sets affected fields to zero value
// ToSearchSubtitleDTO converts MeiliSubtitles to slice of SearchSubtitlesDTO
//
// Ignores any errors and sets affected fields to zero value
func ToSearchSubtitleDTO(wrapper dao.DaoWrapper, subtitles ...tools.MeiliSubtitles) []SearchSubtitlesDTO {
res := make([]SearchSubtitlesDTO, len(subtitles))
for i, subtitle := range subtitles {
Expand Down
2 changes: 2 additions & 0 deletions model/semester.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ type Semester struct {
Year int
}

// InRangeOfSemesters checks if s is between firstSemester (inclusive) and lastSemester (inclusive) or is element of semesters slice
func (s *Semester) InRangeOfSemesters(firstSemester Semester, lastSemester Semester, semesters []Semester) bool {
if s == nil {
return false
Expand All @@ -23,6 +24,7 @@ func (s *Semester) InRangeOfSemesters(firstSemester Semester, lastSemester Semes
return false
}

// GreaterEqualThan checks if s comes after or is equal to s1
func (s *Semester) GreaterEqualThan(s1 Semester) bool {
if s == nil {
return false
Expand Down
4 changes: 4 additions & 0 deletions model/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,7 @@ func (u *User) IsAdminOfCourse(course Course) bool {
return u.Role == AdminType || course.UserID == u.ID
}

// IsEligibleToWatchCourse checks if the user is allowed to access the course
func (u *User) IsEligibleToWatchCourse(course Course) bool {
if u == nil {
return course.Visibility == "public" || course.Visibility == "hidden"
Expand All @@ -277,6 +278,7 @@ func (u *User) IsEligibleToWatchCourse(course Course) bool {
return u.IsAdminOfCourse(course)
}

// IsEligibleToSearchForCourse is a stricter version of IsEligibleToWatchCourse; in case of hidden course, it returns true only when the user is an admin of the course
func (u *User) IsEligibleToSearchForCourse(course Course) bool {
return u.IsEligibleToWatchCourse(course) && course.Visibility != "hidden" || u.IsAdminOfCourse(course)
}
Expand All @@ -300,6 +302,7 @@ func (u *User) CoursesForSemester(year int, term string, context context.Context
return cRes
}

// AdministeredCoursesForSemesters returns all courses, that the user is a course admin of, in the given semester range or semesters
func (u *User) AdministeredCoursesForSemesters(firstSemester Semester, lastSemester Semester, semesters []Semester) []Course {
if u == nil {
return make([]Course, 0)
Expand All @@ -315,6 +318,7 @@ func (u *User) AdministeredCoursesForSemesters(firstSemester Semester, lastSemes
return administeredCourses
}

// CoursesForSemestersWithoutAdministeredCourses returns all courses of the user in the given semester range or semesters excluding administered courses
func (u *User) CoursesForSemestersWithoutAdministeredCourses(firstSemester Semester, lastSemester Semester, semesters []Semester) []Course {
if u == nil {
return make([]Course, 0)
Expand Down
3 changes: 3 additions & 0 deletions tools/meiliExporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ func NewMeiliExporter(d dao.DaoWrapper) *MeiliExporter {
return &MeiliExporter{c, d}
}

// Export exports all relevant search data to MeiliSearch Instance
func (m *MeiliExporter) Export() {
if m == nil {
return
Expand Down Expand Up @@ -190,6 +191,7 @@ func (m *MeiliExporter) SetIndexSettings() {
}
}

// ToMeiliCourses converts slice of model.Course to slice of MeiliCourse
func ToMeiliCourses(cs []model.Course) []MeiliCourse {
res := make([]MeiliCourse, len(cs))
for i, c := range cs {
Expand All @@ -205,6 +207,7 @@ func ToMeiliCourses(cs []model.Course) []MeiliCourse {
return res
}

// ToMeiliStreams converts slice of model.Stream to slice of MeiliStream
func ToMeiliStreams(streams []model.Stream, daoWrapper dao.DaoWrapper) ([]MeiliStream, error) {
res := make([]MeiliStream, len(streams))
for i, s := range streams {
Expand Down
3 changes: 3 additions & 0 deletions tools/meiliSearch.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ func getCoursesSearchRequest(q string, limit int64, courseFilter string) meilise
return req
}

// Search passes search requests on to MeiliSearch instance and returns the results
//
// searchType specifies bit-wise which indexes should be searched (lowest bit set to 1: Index SUBTITLES | second-lowest bit set to 1: Index STREAMS | third-lowest bit set to 1: Index COURSES)
func (d *meiliSearchFunctions) Search(q string, limit int64, searchType int, courseFilter string, streamFilter string, subtitleFilter string) *meilisearch.MultiSearchResponse {
c, err := Cfg.GetMeiliClient()
if err != nil {
Expand Down

0 comments on commit ca80508

Please sign in to comment.