Skip to content

Instantly share code, notes, and snippets.

@robfig
Last active August 29, 2015 14:12
Show Gist options
  • Save robfig/5bffdd8d8f826422b774 to your computer and use it in GitHub Desktop.
Save robfig/5bffdd8d8f826422b774 to your computer and use it in GitHub Desktop.
OOO
package main
import (
"fmt"
"io/ioutil"
"sort"
"strings"
"time"
"github.com/laurent22/ical-go"
)
var holidays = []time.Time{
time.Date(2014, 12, 25, 0, 0, 0, 0, time.UTC),
time.Date(2014, 12, 24, 0, 0, 0, 0, time.UTC),
time.Date(2014, 11, 27, 0, 0, 0, 0, time.UTC),
time.Date(2014, 11, 28, 0, 0, 0, 0, time.UTC),
time.Date(2014, 9, 1, 0, 0, 0, 0, time.UTC),
time.Date(2014, 7, 4, 0, 0, 0, 0, time.UTC),
time.Date(2014, 5, 26, 0, 0, 0, 0, time.UTC),
}
func isHoliday(t time.Time) bool {
for _, holiday := range holidays {
if holiday.Equal(t) {
return true
}
}
return false
}
func canonicalName(name string) string {
var m = map[string]string{
"deepak": "dbapat",
"looking": "unknown",
"doctors": "unknown",
"ooo": "unknown",
"appointment": "unknown",
"cc": "unknown",
"nik's": "nik",
"andy": "atien",
"chris": "cthomas",
"dan": "dp",
"jacob": "jfancher",
"matt": "mattjs",
}
v := m[name]
if v != "" {
return v
}
return name
}
type byDate []time.Time
func (s byDate) Len() int { return len(s) }
func (s byDate) Less(i, j int) bool { return s[i].Before(s[j]) }
func (s byDate) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func weekdays(start, end time.Time) []time.Time {
if end.Sub(start) < 6*time.Hour {
return nil // ignore OOO within a single day
}
var r []time.Time
for !end.Before(start) && start.Year() == 2014 {
switch start.Weekday() {
case time.Sunday, time.Saturday:
default:
if !isHoliday(start) {
r = append(r, start)
}
}
start = start.Add(24 * time.Hour)
}
return r
}
func main() {
b, err := ioutil.ReadFile("/Users/robfig/Downloads/basic.ics")
if err != nil {
panic(err)
}
lines := strings.Split(string(b), "\n")
node, _, err, _ := ical.ParseCalendarNode(lines, 0)
if err != nil {
panic(err)
}
type ooo struct {
name string
days []time.Time
}
var ooos = make(map[string]ooo)
for _, event := range node.Children {
if event.Name != "VEVENT" {
continue
}
const layout = "20060102"
var details struct {
start, end time.Time
summary string
}
for _, prop := range event.Children {
switch prop.Name {
case "DTSTART":
details.start, err = time.Parse(layout, prop.Value[:8])
if err != nil {
fmt.Println("failed parsing ", prop.Value)
}
case "DTEND":
details.end, _ = time.Parse(layout, prop.Value[:8])
case "SUMMARY":
details.summary = prop.Value
}
}
if details.start.Year() == 2014 && !details.end.IsZero() && details.summary != "" {
var name = canonicalName(strings.ToLower(strings.Fields(details.summary)[0]))
var old = ooos[name]
ooos[name] = ooo{
name: name,
days: append(old.days, weekdays(details.start, details.end)...),
}
}
}
for _, ooo := range ooos {
sort.Sort(byDate(ooo.days))
fmt.Print(ooo.name, ",")
var str = ""
var n = 0
var last time.Time
for _, day := range ooo.days {
if !day.Equal(last) {
str += day.Format("1/2") + " "
n++
}
last = day
}
fmt.Print(n, ",", str, "\n")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment