forked from TUM-Dev/gocast
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Admin] Course search for course creation (TUM-Dev#700)
* preload courses from tum online * fix some styling * accessibility improvements
- Loading branch information
1 parent
659d39a
commit 39c4e37
Showing
13 changed files
with
328 additions
and
47 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
package dao | ||
|
||
import ( | ||
"context" | ||
"github.com/joschahenningsen/TUM-Live/model" | ||
"gorm.io/gorm" | ||
"gorm.io/gorm/clause" | ||
) | ||
|
||
//go:generate mockgen -source=prefetchedCourse.go -destination ../mock_dao/prefetchedCourse.go | ||
|
||
type PrefetchedCourseDao interface { | ||
// Get PrefetchedCourse by ID | ||
Get(context.Context, uint) (model.PrefetchedCourse, error) | ||
|
||
// Create a new PrefetchedCourse for the database | ||
Create(context.Context, ...*model.PrefetchedCourse) error | ||
|
||
// Delete a PrefetchedCourse by id. | ||
Delete(context.Context, uint) error | ||
|
||
// Search for a PrefetchedCourse by name using fulltext index | ||
Search(context.Context, string) ([]model.PrefetchedCourse, error) | ||
} | ||
|
||
type prefetchedCourseDao struct { | ||
db *gorm.DB | ||
} | ||
|
||
func NewPrefetchedCourseDao() PrefetchedCourseDao { | ||
return prefetchedCourseDao{db: DB} | ||
} | ||
|
||
// Get a PrefetchedCourse by id. | ||
func (d prefetchedCourseDao) Get(c context.Context, id uint) (res model.PrefetchedCourse, err error) { | ||
return res, DB.WithContext(c).First(&res, id).Error | ||
} | ||
|
||
// Create a PrefetchedCourse. | ||
func (d prefetchedCourseDao) Create(c context.Context, it ...*model.PrefetchedCourse) error { | ||
return DB.WithContext(c).Clauses(clause.OnConflict{DoNothing: true}).Create(it).Error | ||
} | ||
|
||
// Delete a PrefetchedCourse by id. | ||
func (d prefetchedCourseDao) Delete(c context.Context, id uint) error { | ||
return DB.WithContext(c).Delete(&model.PrefetchedCourse{}, id).Error | ||
} | ||
|
||
// Search for a PrefetchedCourse by name using fulltext index | ||
func (d prefetchedCourseDao) Search(ctx context.Context, s string) ([]model.PrefetchedCourse, error) { | ||
var res = make([]model.PrefetchedCourse, 0) | ||
err := DB.WithContext(ctx). | ||
Raw("WITH tmp as (SELECT *, MATCH (name) AGAINST(? IN NATURAL LANGUAGE MODE) AS m "+ | ||
"FROM "+(&model.PrefetchedCourse{}).TableName()+ | ||
") SELECT * FROM tmp WHERE m>0 ORDER BY m DESC LIMIT 10", s). | ||
Scan(&res). | ||
Error | ||
return res, err | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package model | ||
|
||
// PrefetchedCourse represents a course we found in tumonline. This course can be found and created through the "create course" user interface | ||
type PrefetchedCourse struct { | ||
CourseID string `gorm:"column:course_id;type:varchar(255);primaryKey"` | ||
Name string `gorm:"column:name;type:varchar(512);index:,class:FULLTEXT;not null;"` | ||
Year int `gorm:"column:year;not null;"` | ||
Term string `gorm:"column:term;type:varchar(1);not null;"` // Either W or S | ||
} | ||
|
||
// TableName returns the name of the table for the PrefetchedCourse model in the database. | ||
func (*PrefetchedCourse) TableName() string { | ||
return "prefetched_courses" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
package tum | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"github.com/TUM-Dev/CampusProxy/client" | ||
"github.com/joschahenningsen/TUM-Live/dao" | ||
"github.com/joschahenningsen/TUM-Live/model" | ||
"github.com/joschahenningsen/TUM-Live/tools" | ||
log "github.com/sirupsen/logrus" | ||
"strconv" | ||
"strings" | ||
) | ||
|
||
// PrefetchCourses loads all courses from tumonline, so we can use them in the course creation from search | ||
func PrefetchCourses(dao dao.DaoWrapper) func() { | ||
return func() { | ||
if tools.Cfg.Campus.CampusProxy == nil || tools.Cfg.Campus.RelevantOrgs == nil { | ||
return | ||
} | ||
var res []*model.PrefetchedCourse | ||
for _, org := range *tools.Cfg.Campus.RelevantOrgs { | ||
r, err := getCoursesForOrg(org) | ||
if err != nil { | ||
log.Error(err) | ||
} else { | ||
res = append(res, r...) | ||
} | ||
} | ||
err := dao.PrefetchedCourseDao.Create(context.Background(), res...) | ||
if err != nil { | ||
log.Error(err) | ||
} | ||
} | ||
} | ||
|
||
func getCoursesForOrg(org string) ([]*model.PrefetchedCourse, error) { | ||
conf := client.NewConfiguration() | ||
conf.Host = "campus-proxy.mm.rbg.tum.de" | ||
conf.Scheme = "https" | ||
c := client.NewAPIClient(conf) | ||
courses, _, err := c.OrganizationApi. | ||
OrganizationCoursesGet(context.WithValue(context.Background(), client.ContextAPIKeys, map[string]client.APIKey{"ApiKeyAuth": {Key: tools.Cfg.Campus.Tokens[0]}})). | ||
IncludeChildren(true). | ||
OrgUnitID(org). | ||
Execute() | ||
if err.Error() != "" { | ||
return nil, fmt.Errorf("load Course: %v", err.Error()) | ||
} | ||
var res []*model.PrefetchedCourse | ||
for _, c := range courses { | ||
t := "W" | ||
if strings.Contains(c.GetTeachingTerm(), "Sommer") { | ||
t = "S" | ||
} | ||
if !strings.Contains(c.GetTeachingTerm(), " ") { | ||
continue | ||
} | ||
y, err := strconv.Atoi(strings.Split(strings.Split(c.GetTeachingTerm(), " ")[1], "/")[0]) | ||
if err != nil { | ||
continue | ||
} | ||
res = append(res, &model.PrefetchedCourse{ | ||
Name: c.CourseName.GetText(), | ||
CourseID: c.GetCourseId(), | ||
Term: t, | ||
Year: y, | ||
}) | ||
} | ||
return res, nil | ||
} |
Oops, something went wrong.