mirror of
https://gitlab.dit.htwk-leipzig.de/htwk-software/htwkalender-pwa.git
synced 2025-08-07 04:09:17 +02:00
Initial Commit
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -19,3 +19,5 @@
|
|||||||
|
|
||||||
# Go workspace file
|
# Go workspace file
|
||||||
go.work
|
go.work
|
||||||
|
|
||||||
|
/pb_data/
|
||||||
|
8
.idea/.gitignore
generated
vendored
Normal file
8
.idea/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Editor-based HTTP Client requests
|
||||||
|
/httpRequests/
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
9
.idea/htwk-planner.iml
generated
Normal file
9
.idea/htwk-planner.iml
generated
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="WEB_MODULE" version="4">
|
||||||
|
<component name="Go" enabled="true" />
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$" />
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/htwk-planner.iml" filepath="$PROJECT_DIR$/.idea/htwk-planner.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
31
addRoute.go
Normal file
31
addRoute.go
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/labstack/echo/v5"
|
||||||
|
"github.com/pocketbase/pocketbase"
|
||||||
|
"github.com/pocketbase/pocketbase/apis"
|
||||||
|
"github.com/pocketbase/pocketbase/core"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
func addRoutes(app *pocketbase.PocketBase) {
|
||||||
|
|
||||||
|
app.OnBeforeServe().Add(func(e *core.ServeEvent) error {
|
||||||
|
_, err := e.Router.AddRoute(echo.Route{
|
||||||
|
Method: http.MethodGet,
|
||||||
|
Path: "/api/fetchPlans",
|
||||||
|
Handler: func(c echo.Context) error {
|
||||||
|
return fetchHTWK(c, app)
|
||||||
|
},
|
||||||
|
Middlewares: []echo.MiddlewareFunc{
|
||||||
|
apis.ActivityLogger(app),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
344
fetchService.go
Normal file
344
fetchService.go
Normal file
@@ -0,0 +1,344 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/labstack/echo/v5"
|
||||||
|
"github.com/pocketbase/pocketbase"
|
||||||
|
"github.com/pocketbase/pocketbase/apis"
|
||||||
|
"github.com/pocketbase/pocketbase/models"
|
||||||
|
"golang.org/x/net/html"
|
||||||
|
"htwk-planner/model"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func fetchHTWK(c echo.Context, app *pocketbase.PocketBase) error {
|
||||||
|
|
||||||
|
var seminarGroups []model.SeminarGroup
|
||||||
|
|
||||||
|
seminarGroupsLabel := []string{
|
||||||
|
"22INB-3",
|
||||||
|
"22INB-2",
|
||||||
|
"22INB-1",
|
||||||
|
"21INB-2",
|
||||||
|
"21INB-1",
|
||||||
|
"22INM",
|
||||||
|
//"21INM (Masterarbeit)",
|
||||||
|
"22MIB-BIN",
|
||||||
|
"22MIB-2",
|
||||||
|
"22MIB-1",
|
||||||
|
"21MIB-BIN",
|
||||||
|
"21MIB-1",
|
||||||
|
"21MIB-2",
|
||||||
|
//"20MIB (Praxis/Bachelorarbeit)",
|
||||||
|
"22MIM",
|
||||||
|
//"21MIM (Masterarbeit)"
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, seminarGroupLabel := range seminarGroupsLabel {
|
||||||
|
|
||||||
|
result, err := getPlanHTML("ss", seminarGroupLabel)
|
||||||
|
|
||||||
|
seminarGroup := parseSeminarGroup(result)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return apis.NewNotFoundError("The Data could not be fetched", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
collection, err := app.Dao().FindCollectionByNameOrId("events")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, event := range seminarGroup.Events {
|
||||||
|
record := models.NewRecord(collection)
|
||||||
|
record.Set("Day", event.Day)
|
||||||
|
record.Set("Week", event.Week)
|
||||||
|
record.Set("Start", event.Start)
|
||||||
|
record.Set("End", event.End)
|
||||||
|
record.Set("Name", event.Name)
|
||||||
|
record.Set("EventType", event.EventType)
|
||||||
|
record.Set("Prof", event.Prof)
|
||||||
|
record.Set("Rooms", event.Rooms)
|
||||||
|
record.Set("Notes", event.Notes)
|
||||||
|
record.Set("BookedAt", event.BookedAt)
|
||||||
|
if err := app.Dao().SaveRecord(record); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
seminarGroups = append(seminarGroups, seminarGroup)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(http.StatusOK, seminarGroups)
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseSeminarGroup(result string) model.SeminarGroup {
|
||||||
|
doc, _ := html.Parse(strings.NewReader(result))
|
||||||
|
table := findFirstTable(doc)
|
||||||
|
events := toEvents(getEventTables(doc), getAllDayLabels(doc))
|
||||||
|
|
||||||
|
var seminarGroup = model.SeminarGroup{
|
||||||
|
University: findFirstSpanWithClass(table, "header-1-0-0").FirstChild.Data,
|
||||||
|
GroupShortcut: findFirstSpanWithClass(table, "header-2-0-1").FirstChild.Data,
|
||||||
|
Events: events,
|
||||||
|
}
|
||||||
|
|
||||||
|
return seminarGroup
|
||||||
|
}
|
||||||
|
|
||||||
|
func toEvents(tables [][]*html.Node, days []string) []model.Events {
|
||||||
|
var events []model.Events
|
||||||
|
|
||||||
|
for table := range tables {
|
||||||
|
for row := range tables[table] {
|
||||||
|
|
||||||
|
tableData := findTableData(tables[table][row])
|
||||||
|
if len(tableData) > 0 {
|
||||||
|
events = append(events, model.Events{
|
||||||
|
Day: days[table],
|
||||||
|
Week: getTextContent(tableData[0]),
|
||||||
|
Start: getTextContent(tableData[1]),
|
||||||
|
End: getTextContent(tableData[2]),
|
||||||
|
Name: getTextContent(tableData[3]),
|
||||||
|
EventType: getTextContent(tableData[4]),
|
||||||
|
Prof: getTextContent(tableData[5]),
|
||||||
|
Rooms: getTextContent(tableData[6]),
|
||||||
|
Notes: getTextContent(tableData[7]),
|
||||||
|
BookedAt: getTextContent(tableData[8]),
|
||||||
|
})
|
||||||
|
// Print the content of each <td> element
|
||||||
|
//for _, td := range tableData {
|
||||||
|
// content := getTextContent(td)
|
||||||
|
// println(content)
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return events
|
||||||
|
}
|
||||||
|
|
||||||
|
func toUtf8(iso8859_1_buf []byte) string {
|
||||||
|
buf := make([]rune, len(iso8859_1_buf))
|
||||||
|
for i, b := range iso8859_1_buf {
|
||||||
|
buf[i] = rune(b)
|
||||||
|
}
|
||||||
|
return string(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getPlanHTML(semester string, matrikel string) (string, error) {
|
||||||
|
url := "https://stundenplan.htwk-leipzig.de/" + string(semester) + "/Berichte/Text-Listen;Studenten-Sets;name;" + matrikel + "?template=sws_semgrp&weeks=1-65"
|
||||||
|
|
||||||
|
// Send GET request
|
||||||
|
response, err := http.Get(url)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Error occurred while making the request: %s\n", err.Error())
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
defer func(Body io.ReadCloser) {
|
||||||
|
err := Body.Close()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}(response.Body)
|
||||||
|
|
||||||
|
// Read the response body
|
||||||
|
body, err := io.ReadAll(response.Body)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Error occurred while reading the response: %s\n", err.Error())
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return toUtf8(body), err
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the first <table> element in the HTML document
|
||||||
|
func findFirstTable(node *html.Node) *html.Node {
|
||||||
|
if node.Type == html.ElementNode && node.Data == "table" {
|
||||||
|
return node
|
||||||
|
}
|
||||||
|
// Traverse child nodes recursively
|
||||||
|
for child := node.FirstChild; child != nil; child = child.NextSibling {
|
||||||
|
found := findFirstTable(child)
|
||||||
|
if found != nil {
|
||||||
|
return found
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the first <span> element with the specified class attribute value
|
||||||
|
func findFirstSpanWithClass(node *html.Node, classValue string) *html.Node {
|
||||||
|
if node.Type == html.ElementNode && node.Data == "span" {
|
||||||
|
if hasClassAttribute(node, classValue) {
|
||||||
|
return node
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Traverse child nodes recursively
|
||||||
|
for child := node.FirstChild; child != nil; child = child.NextSibling {
|
||||||
|
found := findFirstSpanWithClass(child, classValue)
|
||||||
|
if found != nil {
|
||||||
|
return found
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the specified element has the specified class attribute value
|
||||||
|
func hasClassAttribute(node *html.Node, classValue string) bool {
|
||||||
|
for _, attr := range node.Attr {
|
||||||
|
if attr.Key == "class" && strings.Contains(attr.Val, classValue) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get Tables with days
|
||||||
|
func getEventTables(node *html.Node) [][]*html.Node {
|
||||||
|
var eventTables [][]*html.Node
|
||||||
|
|
||||||
|
tables := findTables(node)
|
||||||
|
|
||||||
|
for events := range tables {
|
||||||
|
rows := findTableRows(tables[events])
|
||||||
|
rows = rows[1:]
|
||||||
|
eventTables = append(eventTables, rows)
|
||||||
|
}
|
||||||
|
|
||||||
|
return eventTables
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get Tables with days
|
||||||
|
func getAllDayLabels(node *html.Node) []string {
|
||||||
|
paragraphs := findParagraphs(node)
|
||||||
|
var dayArray []string
|
||||||
|
|
||||||
|
for _, p := range paragraphs {
|
||||||
|
label := getDayLabel(p)
|
||||||
|
if label != "" {
|
||||||
|
dayArray = append(dayArray, label)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dayArray
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find all <p> elements in the HTML document
|
||||||
|
func findParagraphs(node *html.Node) []*html.Node {
|
||||||
|
var paragraphs []*html.Node
|
||||||
|
|
||||||
|
if node.Type == html.ElementNode && node.Data == "p" {
|
||||||
|
paragraphs = append(paragraphs, node)
|
||||||
|
}
|
||||||
|
|
||||||
|
for child := node.FirstChild; child != nil; child = child.NextSibling {
|
||||||
|
paragraphs = append(paragraphs, findParagraphs(child)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
return paragraphs
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find all <tr> elements in <tbody>, excluding the first one
|
||||||
|
func findTableRows(node *html.Node) []*html.Node {
|
||||||
|
var tableRows []*html.Node
|
||||||
|
|
||||||
|
if node.Type == html.ElementNode && node.Data == "tbody" {
|
||||||
|
child := node.FirstChild
|
||||||
|
for child != nil {
|
||||||
|
if child.Type == html.ElementNode && child.Data == "tr" {
|
||||||
|
tableRows = append(tableRows, child)
|
||||||
|
}
|
||||||
|
child = child.NextSibling
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for child := node.FirstChild; child != nil; child = child.NextSibling {
|
||||||
|
tableRows = append(tableRows, findTableRows(child)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
return tableRows
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find all <p> elements in the HTML document
|
||||||
|
func findTables(node *html.Node) []*html.Node {
|
||||||
|
var tables []*html.Node
|
||||||
|
|
||||||
|
if node.Type == html.ElementNode && node.Data == "table" {
|
||||||
|
tables = append(tables, node)
|
||||||
|
}
|
||||||
|
|
||||||
|
for child := node.FirstChild; child != nil; child = child.NextSibling {
|
||||||
|
tables = append(tables, findDayTables(child)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
return tables
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find all <p> elements in the HTML document
|
||||||
|
func findDayTables(node *html.Node) []*html.Node {
|
||||||
|
var tables []*html.Node
|
||||||
|
|
||||||
|
for child := node.FirstChild; child != nil; child = child.NextSibling {
|
||||||
|
tables = append(tables, findDayTables(child)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
if node.Type == html.ElementNode && node.Data == "table" && hasClassAttribute(node, "spreadsheet") {
|
||||||
|
tables = append(tables, node)
|
||||||
|
}
|
||||||
|
|
||||||
|
return tables
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the text content of the specified node and its descendants
|
||||||
|
func getDayLabel(node *html.Node) string {
|
||||||
|
|
||||||
|
child := node.FirstChild
|
||||||
|
if child != nil {
|
||||||
|
if child.Type == html.ElementNode && child.Data == "span" {
|
||||||
|
if child.FirstChild != nil {
|
||||||
|
return child.FirstChild.Data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find all <td> elements in the current <tr>
|
||||||
|
func findTableData(node *html.Node) []*html.Node {
|
||||||
|
var tableData []*html.Node
|
||||||
|
|
||||||
|
if node.Type == html.ElementNode && node.Data == "tr" {
|
||||||
|
child := node.FirstChild
|
||||||
|
for child != nil {
|
||||||
|
if child.Type == html.ElementNode && child.Data == "td" {
|
||||||
|
tableData = append(tableData, child)
|
||||||
|
}
|
||||||
|
child = child.NextSibling
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tableData
|
||||||
|
}
|
||||||
|
|
||||||
|
func getTextContent(node *html.Node) string {
|
||||||
|
var textContent string
|
||||||
|
|
||||||
|
if node.Type == html.TextNode {
|
||||||
|
textContent = node.Data
|
||||||
|
}
|
||||||
|
|
||||||
|
for child := node.FirstChild; child != nil; child = child.NextSibling {
|
||||||
|
textContent += getTextContent(child)
|
||||||
|
}
|
||||||
|
|
||||||
|
return textContent
|
||||||
|
}
|
86
go.mod
Normal file
86
go.mod
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
module htwk-planner
|
||||||
|
|
||||||
|
go 1.20
|
||||||
|
|
||||||
|
require github.com/pocketbase/pocketbase v0.16.5
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/AlecAivazis/survey/v2 v2.3.6 // indirect
|
||||||
|
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
|
||||||
|
github.com/aws/aws-sdk-go v1.44.274 // indirect
|
||||||
|
github.com/aws/aws-sdk-go-v2 v1.18.0 // indirect
|
||||||
|
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.10 // indirect
|
||||||
|
github.com/aws/aws-sdk-go-v2/config v1.18.25 // indirect
|
||||||
|
github.com/aws/aws-sdk-go-v2/credentials v1.13.24 // indirect
|
||||||
|
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.3 // indirect
|
||||||
|
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.67 // indirect
|
||||||
|
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.33 // indirect
|
||||||
|
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.27 // indirect
|
||||||
|
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.34 // indirect
|
||||||
|
github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.25 // indirect
|
||||||
|
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.11 // indirect
|
||||||
|
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.28 // indirect
|
||||||
|
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.27 // indirect
|
||||||
|
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.14.2 // indirect
|
||||||
|
github.com/aws/aws-sdk-go-v2/service/s3 v1.33.1 // indirect
|
||||||
|
github.com/aws/aws-sdk-go-v2/service/sso v1.12.10 // indirect
|
||||||
|
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.10 // indirect
|
||||||
|
github.com/aws/aws-sdk-go-v2/service/sts v1.19.0 // indirect
|
||||||
|
github.com/aws/smithy-go v1.13.5 // indirect
|
||||||
|
github.com/disintegration/imaging v1.6.2 // indirect
|
||||||
|
github.com/domodwyer/mailyak/v3 v3.6.0 // indirect
|
||||||
|
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||||
|
github.com/fatih/color v1.15.0 // indirect
|
||||||
|
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
|
||||||
|
github.com/ganigeorgiev/fexpr v0.3.0 // indirect
|
||||||
|
github.com/go-ozzo/ozzo-validation/v4 v4.3.0 // indirect
|
||||||
|
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
|
||||||
|
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||||
|
github.com/golang/protobuf v1.5.3 // indirect
|
||||||
|
github.com/google/uuid v1.3.0 // indirect
|
||||||
|
github.com/google/wire v0.5.0 // indirect
|
||||||
|
github.com/googleapis/gax-go/v2 v2.10.0 // indirect
|
||||||
|
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||||
|
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||||
|
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
|
||||||
|
github.com/labstack/echo/v5 v5.0.0-20220201181537-ed2888cfa198 // indirect
|
||||||
|
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||||
|
github.com/mattn/go-isatty v0.0.19 // indirect
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.17 // indirect
|
||||||
|
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect
|
||||||
|
github.com/pocketbase/dbx v1.10.0 // indirect
|
||||||
|
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
||||||
|
github.com/spf13/cast v1.5.1 // indirect
|
||||||
|
github.com/spf13/cobra v1.7.0 // indirect
|
||||||
|
github.com/spf13/pflag v1.0.5 // indirect
|
||||||
|
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||||
|
github.com/valyala/fasttemplate v1.2.2 // indirect
|
||||||
|
go.opencensus.io v0.24.0 // indirect
|
||||||
|
gocloud.dev v0.29.0 // indirect
|
||||||
|
golang.org/x/crypto v0.9.0 // indirect
|
||||||
|
golang.org/x/image v0.7.0 // indirect
|
||||||
|
golang.org/x/mod v0.10.0 // indirect
|
||||||
|
golang.org/x/net v0.10.0 // indirect
|
||||||
|
golang.org/x/oauth2 v0.8.0 // indirect
|
||||||
|
golang.org/x/sys v0.8.0 // indirect
|
||||||
|
golang.org/x/term v0.8.0 // indirect
|
||||||
|
golang.org/x/text v0.9.0 // indirect
|
||||||
|
golang.org/x/time v0.3.0 // indirect
|
||||||
|
golang.org/x/tools v0.9.3 // indirect
|
||||||
|
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
|
||||||
|
google.golang.org/api v0.125.0 // indirect
|
||||||
|
google.golang.org/appengine v1.6.7 // indirect
|
||||||
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc // indirect
|
||||||
|
google.golang.org/grpc v1.55.0 // indirect
|
||||||
|
google.golang.org/protobuf v1.30.0 // indirect
|
||||||
|
lukechampine.com/uint128 v1.3.0 // indirect
|
||||||
|
modernc.org/cc/v3 v3.40.0 // indirect
|
||||||
|
modernc.org/ccgo/v3 v3.16.13 // indirect
|
||||||
|
modernc.org/libc v1.22.6 // indirect
|
||||||
|
modernc.org/mathutil v1.5.0 // indirect
|
||||||
|
modernc.org/memory v1.5.0 // indirect
|
||||||
|
modernc.org/opt v0.1.3 // indirect
|
||||||
|
modernc.org/sqlite v1.22.1 // indirect
|
||||||
|
modernc.org/strutil v1.1.3 // indirect
|
||||||
|
modernc.org/token v1.1.0 // indirect
|
||||||
|
)
|
25
main.go
Normal file
25
main.go
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/labstack/echo/v5"
|
||||||
|
"github.com/pocketbase/pocketbase"
|
||||||
|
"github.com/pocketbase/pocketbase/core"
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
app := pocketbase.New()
|
||||||
|
|
||||||
|
app.OnBeforeServe().Add(func(e *core.ServeEvent) error {
|
||||||
|
e.Router.GET("/api/hello", func(c echo.Context) error {
|
||||||
|
return c.String(200, "Hello world!")
|
||||||
|
})
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
addRoutes(app)
|
||||||
|
|
||||||
|
if err := app.Start(); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
20
model/seminarGroup.go
Normal file
20
model/seminarGroup.go
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
type SeminarGroup struct {
|
||||||
|
University string
|
||||||
|
GroupShortcut string
|
||||||
|
Events []Events
|
||||||
|
}
|
||||||
|
|
||||||
|
type Events struct {
|
||||||
|
Day string
|
||||||
|
Week string
|
||||||
|
Start string
|
||||||
|
End string
|
||||||
|
Name string
|
||||||
|
EventType string
|
||||||
|
Prof string
|
||||||
|
Rooms string
|
||||||
|
Notes string
|
||||||
|
BookedAt string
|
||||||
|
}
|
Reference in New Issue
Block a user