mirror of
https://gitlab.dit.htwk-leipzig.de/htwk-software/htwkalender.git
synced 2025-08-06 11:49:14 +02:00
feat:#39 added fetcher for SeminarGroups
This commit is contained in:
229
backend/service/fetch/v3/fetchSeminarGroupService.go
Normal file
229
backend/service/fetch/v3/fetchSeminarGroupService.go
Normal file
@@ -0,0 +1,229 @@
|
||||
package v3
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/pocketbase/pocketbase"
|
||||
"github.com/pocketbase/pocketbase/models"
|
||||
"golang.org/x/net/http2"
|
||||
"htwkalender/model"
|
||||
"net/http"
|
||||
|
||||
"htwkalender/service/db"
|
||||
"log/slog"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func FetchSeminarGroups(app *pocketbase.PocketBase) ([]*models.Record, error) {
|
||||
var groups []model.SeminarGroup
|
||||
client := &http.Client{}
|
||||
client.Transport = &http2.Transport{}
|
||||
|
||||
apiUrl := "https://luna.htwk-leipzig.de/api/"
|
||||
|
||||
seminarUrl := apiUrl + "studierendengruppen"
|
||||
|
||||
parsedSeminarGroups, err := parseSeminarGroups(seminarUrl, client)
|
||||
|
||||
studyTypeUrl := apiUrl + "studiengaenge"
|
||||
|
||||
parsedStudyTypes, err := parseStudyTypes(studyTypeUrl, client)
|
||||
|
||||
if err != nil {
|
||||
slog.Error("Error while fetching study types", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
facultyUrl := apiUrl + "fakultaeten"
|
||||
parsedFaculties, err := parseFaculties(facultyUrl, client)
|
||||
|
||||
slog.Info("Fetched study types: " + strconv.Itoa(len(parsedStudyTypes)))
|
||||
slog.Info("Fetched seminar groups: " + strconv.Itoa(len(parsedSeminarGroups.Groups)) + " of " + strconv.Itoa(parsedSeminarGroups.TotalItems))
|
||||
slog.Info("Fetched faculties: " + strconv.Itoa(len(parsedFaculties.Faculties)))
|
||||
|
||||
// map seminar groups to model seminar groups
|
||||
for _, group := range parsedSeminarGroups.Groups {
|
||||
var newGroup model.SeminarGroup
|
||||
newGroup.University = "HTWK Leipzig"
|
||||
newGroup.Course = group.SeminarGroup
|
||||
newGroup.Faculty = group.Faculty
|
||||
newGroup.Semester = group.Semester
|
||||
|
||||
// find corresponding study type by studiengang in parsedStudyTypes
|
||||
for _, studyTypeItem := range parsedStudyTypes {
|
||||
if studyTypeItem.ID == group.Studiengang {
|
||||
newGroup.GroupShortcut = studyTypeItem.Description
|
||||
newGroup.GroupId = studyTypeItem.GroupID
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
for _, facultyItem := range parsedFaculties.Faculties {
|
||||
if facultyItem.ID == group.Faculty {
|
||||
newGroup.FacultyId = facultyItem.ShortCut
|
||||
newGroup.Faculty = facultyItem.Description
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
groups = append(groups, newGroup)
|
||||
}
|
||||
|
||||
collection, dbError := db.FindCollection(app, "groups")
|
||||
if dbError != nil {
|
||||
slog.Error("Error while searching collection groups", dbError)
|
||||
return nil, err
|
||||
}
|
||||
var insertedGroups []*models.Record
|
||||
|
||||
insertedGroups, dbError = db.SaveGroups(groups, collection, app)
|
||||
if dbError != nil {
|
||||
slog.Error("Error while saving groups", dbError)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return insertedGroups, nil
|
||||
}
|
||||
|
||||
func parseFaculties(url string, client *http.Client) (faculties, error) {
|
||||
|
||||
// the url is paginated, so we need to fetch all pages
|
||||
// example url: https://luna.htwk-leipzig.de/api/fakultaeten?page=1&itemsPerPage=100
|
||||
// the itemsPerPage is set to 100, so we need to fetch all pages until we get an empty response
|
||||
|
||||
var fetchedFaculties []faculty
|
||||
var page = 1
|
||||
var itemsPerPage = 100
|
||||
|
||||
for {
|
||||
requestUrl := url + "?page=" + strconv.Itoa(page) + "&itemsPerPage=" + strconv.Itoa(itemsPerPage)
|
||||
response, err := requestJSON(requestUrl, client)
|
||||
if err != nil {
|
||||
slog.Error("Error while fetching faculties", err)
|
||||
return faculties{}, err
|
||||
}
|
||||
|
||||
var facs faculties
|
||||
err = json.Unmarshal([]byte(response), &facs)
|
||||
if err != nil {
|
||||
slog.Error("Error while unmarshalling faculties", err)
|
||||
return faculties{}, err
|
||||
}
|
||||
|
||||
fetchedFaculties = append(fetchedFaculties, facs.Faculties...)
|
||||
|
||||
if len(facs.Faculties) == 0 {
|
||||
break
|
||||
}
|
||||
page++
|
||||
}
|
||||
|
||||
return faculties{
|
||||
Faculties: fetchedFaculties,
|
||||
}, nil
|
||||
|
||||
}
|
||||
|
||||
func parseStudyTypes(url string, client *http.Client) ([]studyType, error) {
|
||||
|
||||
// the url is paginated, so we need to fetch all pages
|
||||
// example url: https://luna.htwk-leipzig.de/api/studiengangstypen?page=1&itemsPerPage=100
|
||||
// the itemsPerPage is set to 100, so we need to fetch all pages until we get an empty response
|
||||
|
||||
var fetchedStudyTypes []studyType
|
||||
var page = 1
|
||||
var itemsPerPage = 100
|
||||
|
||||
for {
|
||||
requestUrl := url + "?page=" + strconv.Itoa(page) + "&itemsPerPage=" + strconv.Itoa(itemsPerPage)
|
||||
response, err := requestJSON(requestUrl, client)
|
||||
if err != nil {
|
||||
slog.Error("Error while fetching study types", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var types studyTypes
|
||||
err = json.Unmarshal([]byte(response), &types)
|
||||
if err != nil {
|
||||
slog.Error("Error while unmarshalling study types", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fetchedStudyTypes = append(fetchedStudyTypes, types.Types...)
|
||||
|
||||
if len(types.Types) == 0 {
|
||||
break
|
||||
}
|
||||
page++
|
||||
}
|
||||
|
||||
return fetchedStudyTypes, nil
|
||||
}
|
||||
|
||||
func parseSeminarGroups(url string, client *http.Client) (seminarGroups, error) {
|
||||
|
||||
// the url is paginated, so we need to fetch all pages
|
||||
// example url: https://luna.htwk-leipzig.de/api/studierendengruppen?page=1&itemsPerPage=100
|
||||
// the itemsPerPage is set to 100, so we need to fetch all pages until we get an empty response
|
||||
|
||||
var fetchedSeminarGroups []seminarGroup
|
||||
var page = 1
|
||||
var itemsPerPage = 100
|
||||
var totalItems = 0
|
||||
|
||||
for {
|
||||
requestUrl := url + "?page=" + strconv.Itoa(page) + "&itemsPerPage=" + strconv.Itoa(itemsPerPage)
|
||||
response, err := requestJSON(requestUrl, client)
|
||||
if err != nil {
|
||||
slog.Error("Error while fetching seminar groups", err)
|
||||
return seminarGroups{}, err
|
||||
}
|
||||
|
||||
var groups seminarGroups
|
||||
err = json.Unmarshal([]byte(response), &groups)
|
||||
if err != nil {
|
||||
slog.Error("Error while unmarshalling seminar groups", err)
|
||||
return seminarGroups{}, err
|
||||
}
|
||||
|
||||
// cut api iri prefix
|
||||
for i, group := range groups.Groups {
|
||||
//keep the last 32 characters of the string
|
||||
groups.Groups[i].Faculty = group.Faculty[len(group.Faculty)-32:]
|
||||
groups.Groups[i].Studiengang = group.Studiengang[len(group.Studiengang)-32:]
|
||||
groups.Groups[i].Semester = group.Semester[len(group.Semester)-2:]
|
||||
}
|
||||
|
||||
totalItems = groups.TotalItems
|
||||
fetchedSeminarGroups = append(fetchedSeminarGroups, groups.Groups...)
|
||||
|
||||
if len(groups.Groups) == 0 {
|
||||
break
|
||||
}
|
||||
page++
|
||||
}
|
||||
|
||||
return seminarGroups{
|
||||
TotalItems: totalItems,
|
||||
Groups: fetchedSeminarGroups,
|
||||
}, nil
|
||||
|
||||
}
|
||||
|
||||
func removeDuplicates(groups []model.SeminarGroup) []model.SeminarGroup {
|
||||
var uniqueGroups []model.SeminarGroup
|
||||
for _, group := range groups {
|
||||
if !contains(uniqueGroups, group) {
|
||||
uniqueGroups = append(uniqueGroups, group)
|
||||
}
|
||||
}
|
||||
return uniqueGroups
|
||||
}
|
||||
|
||||
func contains(groups []model.SeminarGroup, group model.SeminarGroup) bool {
|
||||
for _, a := range groups {
|
||||
if (a.Course == group.Course) && (a.Semester == group.Semester) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
Reference in New Issue
Block a user