[CODE] parsing CSV, no speakers yet
This commit is contained in:
parent
7e5fbbe254
commit
e5b29648c0
177
main.go
177
main.go
|
@ -7,10 +7,22 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
"strconv"
|
||||||
"text/template"
|
"text/template"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var timeCSVFormat = "2.1.06 15:04" // input format
|
||||||
|
var timeXMLDateFormat = "2006-01-02" // frab xml format for dates
|
||||||
|
var timeXMLTimeFormat = "15:04" // frab xml format for times
|
||||||
|
|
||||||
|
const csvColTitle = 0
|
||||||
|
const csvColRoom = 1
|
||||||
|
const csvColStart = 2
|
||||||
|
const csvColEnd = 3
|
||||||
|
const csvColSpeaker = 4
|
||||||
|
const csvColLang = 5
|
||||||
|
|
||||||
type frabSchedule struct {
|
type frabSchedule struct {
|
||||||
Conf conference
|
Conf conference
|
||||||
Days []day
|
Days []day
|
||||||
|
@ -55,6 +67,14 @@ type person struct {
|
||||||
Name string
|
Name string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func fmtDuration(d time.Duration) string {
|
||||||
|
d = d.Round(time.Minute)
|
||||||
|
h := d / time.Hour
|
||||||
|
d -= h * time.Hour
|
||||||
|
m := d / time.Minute
|
||||||
|
return fmt.Sprintf("%02d:%02d", h, m)
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
fmt.Println("Conference Schedule: CSV to Frab (Infobeamer) Converter")
|
fmt.Println("Conference Schedule: CSV to Frab (Infobeamer) Converter")
|
||||||
|
|
||||||
|
@ -67,7 +87,9 @@ func main() {
|
||||||
log.Fatal("Error opening CSV file:\n", err)
|
log.Fatal("Error opening CSV file:\n", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
records, err := csv.NewReader(csvFile).ReadAll()
|
csvReader := csv.NewReader(csvFile)
|
||||||
|
csvReader.Comma = ';' // MS excel default export format
|
||||||
|
records, err := csvReader.ReadAll()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("Error reading CSV file:\n", err)
|
log.Fatal("Error reading CSV file:\n", err)
|
||||||
}
|
}
|
||||||
|
@ -75,51 +97,114 @@ func main() {
|
||||||
// omit title row
|
// omit title row
|
||||||
csvRecords := records[1:]
|
csvRecords := records[1:]
|
||||||
|
|
||||||
fmt.Println(csvRecords) // TODO
|
// fmt.Println(csvRecords) // TODO
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Data Conversion
|
* Data Conversion
|
||||||
*/
|
*/
|
||||||
timeDateFormat := "2006-01-02"
|
roomsList := make(map[time.Time]map[string]int) // map of day's start time to map of room names
|
||||||
// timeTimeFormat := "15:04"
|
var conferenceStart time.Time
|
||||||
|
var conferenceEnd time.Time
|
||||||
|
loc, _ := time.LoadLocation("Europe/Berlin")
|
||||||
|
|
||||||
|
for idx, row := range csvRecords {
|
||||||
|
// parse event times
|
||||||
|
eventStart, err := time.ParseInLocation(timeCSVFormat, row[csvColStart], loc)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Error parsing start date in CSV file, line ", idx+1, ":\n", err)
|
||||||
|
}
|
||||||
|
eventEnd, err := time.ParseInLocation(timeCSVFormat, row[csvColEnd], loc)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Error parsing end date in CSV file, line ", idx+1, ":\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// create unique list of the rooms for each day
|
||||||
|
dayStart := eventStart.Truncate(24 * time.Hour)
|
||||||
|
if roomsList[dayStart] == nil {
|
||||||
|
roomsList[dayStart] = make(map[string]int)
|
||||||
|
}
|
||||||
|
roomsList[dayStart][row[csvColRoom]] = 1
|
||||||
|
|
||||||
|
// get conference start and end date
|
||||||
|
if idx == 0 {
|
||||||
|
conferenceStart = eventStart
|
||||||
|
conferenceEnd = eventEnd
|
||||||
|
}
|
||||||
|
if eventStart.Before(conferenceStart) {
|
||||||
|
conferenceStart = eventStart
|
||||||
|
}
|
||||||
|
if eventEnd.After(conferenceEnd) {
|
||||||
|
conferenceEnd = eventEnd
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
conferenceStart = conferenceStart.Truncate(24 * time.Hour)
|
||||||
|
conferenceEnd = conferenceEnd.Truncate(24 * time.Hour).Add(24 * time.Hour)
|
||||||
|
|
||||||
|
// convert csv entries into event and sort in days
|
||||||
|
events := make(map[int][]event) // map of day index to day's events
|
||||||
|
eventID := 100
|
||||||
|
confDays := make(map[int]day) // map of day index to day structure
|
||||||
|
|
||||||
|
for idx, row := range csvRecords {
|
||||||
|
// TODO: add speakers
|
||||||
|
|
||||||
|
eventStart, err := time.ParseInLocation(timeCSVFormat, row[csvColStart], loc)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Error parsing start date in CSV file, line ", idx+1, ":\n", err)
|
||||||
|
}
|
||||||
|
eventEnd, err := time.ParseInLocation(timeCSVFormat, row[csvColEnd], loc)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Error parsing end date in CSV file, line ", idx+1, ":\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
dayIdx := int(eventStart.Sub(conferenceStart).Hours()/24) + 1
|
||||||
|
eventGUID := strconv.Itoa(dayIdx) + "-" + strconv.Itoa(eventID)
|
||||||
|
eventDateStr := eventStart.Format(time.RFC3339)
|
||||||
|
eventStartStr := eventStart.Format(timeXMLTimeFormat)
|
||||||
|
eventDurationStr := fmtDuration(eventEnd.Sub(eventStart))
|
||||||
|
|
||||||
|
events[dayIdx] = append(events[dayIdx], event{eventID, eventGUID, row[csvColRoom], row[csvColTitle], eventDateStr, eventStartStr, eventDurationStr, row[csvColLang], nil})
|
||||||
|
|
||||||
|
// create days
|
||||||
|
if _, ok := confDays[dayIdx]; !ok {
|
||||||
|
dayDateStr := eventStart.Format(timeXMLDateFormat)
|
||||||
|
dayStart := eventStart.Truncate(24 * time.Hour)
|
||||||
|
dayEnd := dayStart.Add(24 * time.Hour)
|
||||||
|
dayStartStr := dayStart.Format(time.RFC3339)
|
||||||
|
dayEndStr := dayEnd.Format(time.RFC3339)
|
||||||
|
|
||||||
|
var dayRooms []room
|
||||||
|
for roomName := range roomsList[dayStart] {
|
||||||
|
dayRooms = append(dayRooms, room{roomName, nil})
|
||||||
|
}
|
||||||
|
|
||||||
|
confDays[dayIdx] = day{dayIdx, dayDateStr, dayStartStr, dayEndStr, dayRooms}
|
||||||
|
}
|
||||||
|
|
||||||
|
eventID++
|
||||||
|
}
|
||||||
|
|
||||||
|
// sort events to rooms and day structures
|
||||||
|
for dayIdx, eventDay := range events {
|
||||||
|
for _, event := range eventDay {
|
||||||
|
for roomIdx, roomName := range confDays[dayIdx].Rooms {
|
||||||
|
if roomName.Name == event.Room {
|
||||||
|
confDays[dayIdx].Rooms[roomIdx].Events = append(confDays[dayIdx].Rooms[roomIdx].Events, event)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// new conference
|
// new conference
|
||||||
cmdTitle := "Test Conference" // TODO: get from command line
|
confDurationDays := int(conferenceEnd.Sub(conferenceStart).Hours() / 24)
|
||||||
cmdStart := "2018-11-18" // TODO: get from command line
|
conf := conference{"Wälderhaus Veranstaltung", conferenceStart.Format(time.RFC3339), conferenceEnd.Format(time.RFC3339), confDurationDays}
|
||||||
cmdEnd := "2018-11-19" // TODO: get from command line
|
|
||||||
|
|
||||||
cmdStartTime, _ := time.Parse(timeDateFormat, cmdStart)
|
var days []day
|
||||||
cmdEndTime, _ := time.Parse(timeDateFormat, cmdEnd)
|
for _, d := range confDays {
|
||||||
|
days = append(days, d)
|
||||||
|
}
|
||||||
|
|
||||||
confDurationDays := int(cmdEndTime.Sub(cmdStartTime).Hours()/24) + 1
|
|
||||||
conf := conference{cmdTitle, cmdStart, cmdEnd, confDurationDays}
|
|
||||||
|
|
||||||
// gather all rooms and persons
|
|
||||||
// TODO
|
|
||||||
|
|
||||||
// TODO: make room and day structs
|
|
||||||
|
|
||||||
// sort by room and day into structure
|
|
||||||
// TODO
|
|
||||||
// valid rooms: Heuckenlock, Heuckenlock {Ebbe, Flut}, Holzhafen, Raackmoor, Wohldorfer Wald
|
|
||||||
|
|
||||||
// assign the conference and days to the schedule
|
|
||||||
speaker1 := person{1, "Frau Testperson"}
|
|
||||||
|
|
||||||
day1Room1Event1 := event{123, "1-123", "Heuckenlock", "Opening Keynote", "2018-11-18T21:00:00+01:00", "21:00", "01:00", "", []person{speaker1}}
|
|
||||||
day1Room1Event2 := event{124, "1-124", "Heuckenlock", "Quartalszahlen", "2018-11-18T22:00:00+01:00", "22:00", "00:30", "de", []person{speaker1}}
|
|
||||||
day1Room1Events := []event{day1Room1Event1, day1Room1Event2}
|
|
||||||
day1Room1 := room{"Heuckenlock", day1Room1Events}
|
|
||||||
|
|
||||||
day1Room2Event1 := event{223, "", "Holzhafen", "Room 2 Talk 1", "2018-11-18T21:00:00+01:00", "21:00", "01:00", "", []person{speaker1}}
|
|
||||||
day1Room2Event2 := event{224, "", "Holzhafen", "Room 2 Title 2", "2018-11-18T22:00:00+01:00", "22:00", "00:30", "", []person{speaker1}}
|
|
||||||
day1Room2Events := []event{day1Room2Event1, day1Room2Event2}
|
|
||||||
day1Room2 := room{"Holzhafen", day1Room2Events}
|
|
||||||
|
|
||||||
day1Rooms := []room{day1Room1, day1Room2}
|
|
||||||
day1 := day{1, "2018-11-18", "2018-11-18T00:00:00+01:00", "2018-11-19T00:00:00+01:00", day1Rooms}
|
|
||||||
|
|
||||||
days := []day{day1}
|
|
||||||
sched := frabSchedule{conf, days}
|
sched := frabSchedule{conf, days}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -145,7 +230,21 @@ func main() {
|
||||||
/*
|
/*
|
||||||
* Print Summary
|
* Print Summary
|
||||||
*/
|
*/
|
||||||
// TODO
|
fmt.Println("- Conference Start:", conferenceStart)
|
||||||
|
fmt.Println("- Conference End :", conferenceEnd)
|
||||||
|
fmt.Println("- Days :", confDurationDays)
|
||||||
|
fmt.Println("- Events :", eventID-100)
|
||||||
|
|
||||||
|
// fmt.Println("Dump days:")
|
||||||
|
// for _, day := range days {
|
||||||
|
// fmt.Println("Day", day.Index)
|
||||||
|
// for _, room := range day.Rooms {
|
||||||
|
// fmt.Println(" Room", room.Name)
|
||||||
|
// for _, event := range room.Events {
|
||||||
|
// fmt.Println(" Event", event)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
fmt.Println("done")
|
fmt.Println("done")
|
||||||
}
|
}
|
||||||
|
|
17
schedule.csv
17
schedule.csv
|
@ -1,3 +1,14 @@
|
||||||
Titel, Raum, Von, Bis, Speaker, Sprache (DE/EN)
|
Titel des Programmpunktes;Raum;Von (TT.MM.JJ HH:MM);Bis (TT.MM.JJ HH:MM);Vortragende;Sprache (DE/EN)
|
||||||
Very good talk, Holzhafen, 19.11.2018 12:00, 19.11.2018 13:00:00, frab-user, de
|
Begrüßung;Holzhafen;25.11.18 12:00;25.11.18 13:00;Ada Lovelace;EN
|
||||||
Keynote, Heuckenlock Ebbe, 19.11.2018 12:00, 19.11.2018 13:00:00, frab-user, de
|
Vortrag 1;Raackmoor;25.11.18 12:00;25.11.18 13:00;Marie Curie;
|
||||||
|
Noch ein Vortrag;Wohldorfer Wald;25.11.18 12:00;25.11.18 13:00;Donna Strickland;
|
||||||
|
Workshop;Heuckenlock;25.11.18 12:00;25.11.18 13:00;Edith Clarke;
|
||||||
|
Testvortrag Ebbe;Heuckenlock Ebbe;25.11.18 12:00;25.11.18 13:00;Bjarne Stroustrup;
|
||||||
|
Testvortrag Flut;Heuckenlock Flut;25.11.18 12:00;25.11.18 13:00;Chris Lattner;
|
||||||
|
Test 1;Holzhafen;25.11.18 13:00;25.11.18 13:30;;
|
||||||
|
Test 2;Raackmoor;25.11.18 13:00;25.11.18 13:30;;
|
||||||
|
Test 3;Wohldorfer Wald;25.11.18 13:00;25.11.18 13:30;;
|
||||||
|
Test 4;Heuckenlock;25.11.18 13:00;25.11.18 13:30;;
|
||||||
|
Test 5;Heuckenlock Ebbe;25.11.18 13:00;25.11.18 13:30;;
|
||||||
|
Test 6;Heuckenlock Flut;25.11.18 13:00;25.11.18 13:30;;
|
||||||
|
Test 7;Heuckenlock Flut;24.11.18 13:00;24.11.18 13:30;;
|
|
Loading…
Reference in a new issue