-
Notifications
You must be signed in to change notification settings - Fork 50
Expand file tree
/
Copy pathastraParser.go
More file actions
109 lines (92 loc) · 3.06 KB
/
astraParser.go
File metadata and controls
109 lines (92 loc) · 3.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
package parser
import (
"encoding/json"
"fmt"
"log"
"os"
"strings"
"github.com/UTDNebula/api-tools/utils"
"github.com/UTDNebula/nebula-api/api/schema"
)
// InputData describes the raw Astra export payload containing fields metadata and row values.
type InputData struct {
Fields string `json:"fields"`
Data [][]interface{} `json:"data"`
}
// ParseAstra reads Astra scrape output and produces structured multi-building event JSON files.
func ParseAstra(inDir string, outDir string) {
astraFile, err := os.ReadFile(inDir + "/astraScraped.json")
if err != nil {
panic(err)
}
var rawData map[string]InputData
err = json.Unmarshal(astraFile, &rawData)
if err != nil {
panic(err)
}
var result []schema.MultiBuildingEvents[schema.AstraEvent]
for date, data := range rawData {
fieldMap := mapFields(data.Fields)
buildingsMap := make(map[string]map[string][]schema.AstraEvent)
for _, record := range data.Data {
building := getString(record, fieldMap["BuildingCode"])
room := getString(record, fieldMap["RoomNumber"])
event := schema.AstraEvent{
ActivityName: getString(record, fieldMap["ActivityName"]),
MeetingType: getString(record, fieldMap["MeetingType"]),
StartDate: getString(record, fieldMap["StartDate"]),
EndDate: getString(record, fieldMap["EndDate"]),
CurrentState: getString(record, fieldMap["CurrentState"]),
NotAllowedUsageMask: getInt(record, fieldMap["NotAllowedUsageMask"]),
UsageColor: getString(record, fieldMap["UsageColor"]),
Capacity: getInt(record, fieldMap["Capacity"]),
}
if building == nil || room == nil || *(building) == "" || *(room) == "" {
continue
}
if _, exists := buildingsMap[*building]; !exists {
buildingsMap[*building] = make(map[string][]schema.AstraEvent)
}
buildingsMap[*building][*room] = append(buildingsMap[*building][*room], event)
}
var buildings []schema.SingleBuildingEvents[schema.AstraEvent]
for buildingCode, rooms := range buildingsMap {
var roomList []schema.RoomEvents[schema.AstraEvent]
for roomNumber, events := range rooms {
roomList = append(roomList, schema.RoomEvents[schema.AstraEvent]{Room: roomNumber, Events: events})
}
buildings = append(buildings, schema.SingleBuildingEvents[schema.AstraEvent]{Building: buildingCode, Rooms: roomList})
}
data := schema.MultiBuildingEvents[schema.AstraEvent]{
Date: date,
Buildings: buildings,
}
result = append(result, data)
}
log.Print("Parsed Astra!")
utils.WriteJSON(fmt.Sprintf("%s/astra.json", outDir), result)
}
func mapFields(fields string) map[string]int {
fieldNames := map[string]int{}
fieldList := strings.Split(fields, ",")
for i, name := range fieldList {
fieldNames[name] = i
}
return fieldNames
}
func getString(record []interface{}, place int) *string {
val := record[place]
if val == nil {
return nil
}
s := val.(string)
return &s
}
func getInt(record []interface{}, place int) *float64 {
val := record[place]
if val == nil {
return nil
}
i := val.(float64)
return &i
}