[CODE] parsing CSV, no speakers yet

This commit is contained in:
Jannik Beyerstedt 2018-11-25 14:21:21 +01:00
parent 7e5fbbe254
commit e5b29648c0
2 changed files with 152 additions and 42 deletions

177
main.go
View file

@ -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")
} }

View file

@ -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;;
1 Titel Titel des Programmpunktes Raum Von Von (TT.MM.JJ HH:MM) Bis Bis (TT.MM.JJ HH:MM) Speaker Vortragende Sprache (DE/EN)
2 Very good talk Begrüßung Holzhafen 19.11.2018 12:00 25.11.18 12:00 19.11.2018 13:00:00 25.11.18 13:00 frab-user Ada Lovelace de EN
3 Keynote Vortrag 1 Heuckenlock Ebbe Raackmoor 19.11.2018 12:00 25.11.18 12:00 19.11.2018 13:00:00 25.11.18 13:00 frab-user Marie Curie de
4 Noch ein Vortrag Wohldorfer Wald 25.11.18 12:00 25.11.18 13:00 Donna Strickland
5 Workshop Heuckenlock 25.11.18 12:00 25.11.18 13:00 Edith Clarke
6 Testvortrag Ebbe Heuckenlock Ebbe 25.11.18 12:00 25.11.18 13:00 Bjarne Stroustrup
7 Testvortrag Flut Heuckenlock Flut 25.11.18 12:00 25.11.18 13:00 Chris Lattner
8 Test 1 Holzhafen 25.11.18 13:00 25.11.18 13:30
9 Test 2 Raackmoor 25.11.18 13:00 25.11.18 13:30
10 Test 3 Wohldorfer Wald 25.11.18 13:00 25.11.18 13:30
11 Test 4 Heuckenlock 25.11.18 13:00 25.11.18 13:30
12 Test 5 Heuckenlock Ebbe 25.11.18 13:00 25.11.18 13:30
13 Test 6 Heuckenlock Flut 25.11.18 13:00 25.11.18 13:30
14 Test 7 Heuckenlock Flut 24.11.18 13:00 24.11.18 13:30