Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
Signed-off-by: Andrea Barberio <insomniac@slackware.it>
  • Loading branch information
insomniacslk committed Sep 12, 2024
0 parents commit a6f3d75
Show file tree
Hide file tree
Showing 4 changed files with 209 additions and 0 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# moca24-ics

Smal tool that fetches the [MOCA 2024 calendar](https://moca.camp/calendar/index.html) via HackerTracker API and prints it in ICS format.
7 changes: 7 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module git.cicciogatto.lol/insomniac/moca-ics

go 1.22.6

require github.com/sirupsen/logrus v1.9.3

require golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect
15 changes: 15 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
184 changes: 184 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
package main

import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"strings"
"time"

"github.com/sirupsen/logrus"
)

var (
hturl = url.URL{
Scheme: "https",
Host: "firestore.googleapis.com",
Path: "/v1/projects/junctor-hackertracker/databases/(default)/documents/conferences/MOCA2024:runQuery",
}
)

type StringField struct {
StringValue string `json:"stringValue,omitempty"`
}

type IntField struct {
IntValue string `json:"intValue,omitempty"`
}

type Value struct {
MapValue struct {
Fields struct {
ConferenceID interface{} `json:"conference_id,omitempty"`
EventIDs ArrayField `json:"event_i_ds,omitempty"`
Name StringField `json:"name,omitempty"`
Links ArrayField `json:"links,omitempty"`
Affiliations ArrayField `json:"affiliations,omitempty"`
Media ArrayField `json:"media,omitempty"`
ID IntField `json:"id,omitempty"`
ShortName StringField `json:"short_name,omitempty"`
} `json:"fields,omitempty"`
} `json:"mapValue,omitempty"`
}

type ArrayField struct {
ArrayValue struct {
Values []Value `json:"values,omitempty"`
} `json:"arrayValue,omitempty"`
}

type Item struct {
Document struct {
Name string `json:"name"`
Fields struct {
Conference StringField `json:"conference,omitempty"`
Timezone StringField `json:"timezone,omitempty"`
Link StringField `json:"link,omitempty"`
Title StringField `json:"title,omitempty"`
Description StringField `json:"description,omitempty"`
Media ArrayField `json:"media,omitempty"`
Type interface{} `json:"type,omitempty"`
BeginTsz StringField `json:"begin_tsz,omitempty"`
EndTsz StringField `json:"end_tsz,omitempty"`
BeginTimestamp StringField `json:"begin_timestamp,omitempty"`
EndTimestamp StringField `json:"end_timestamp,omitempty"`
UpdatedTsz StringField `json:"updated_tsz,omitempty"`
UpdatedTimestamp StringField `json:"updated_timestamp,omitempty"`
Location Value `json:"location,omitempty"`
Speakers ArrayField `json:"speakers,omitempty"`
Links ArrayField `json:"links,omitempty"`
} `json:"fields,omitempty"`
} `json:"document"`
}

func main() {
reqData := []byte(`{
"structuredQuery": {
"from": [
{
"collectionId": "events"
}
],
"orderBy": [
{
"field": {
"fieldPath": "begin_timestamp"
},
"direction": "DESCENDING"
},
{
"field": {
"fieldPath": "__name__"
},
"direction": "DESCENDING"
}
]
}
}`)
req, err := http.NewRequest(http.MethodPost, hturl.String(), bytes.NewBuffer(reqData))
if err != nil {
logrus.Fatalf("Failed to create new request: %v", err)
}
client := http.Client{}
resp, err := client.Do(req)
if err != nil {
logrus.Fatalf("HTTP POST failed: %v", err)
}
defer func() {
_ = resp.Body.Close()
}()
if resp.StatusCode != 200 {
logrus.Fatalf("Status code is not 200 OK but %s", resp.Status)
}
body, err := io.ReadAll(resp.Body)
if err != nil {
logrus.Fatalf("Failed to read HTTP body: %v", err)
}
var items []Item
if err := json.Unmarshal(body, &items); err != nil {
logrus.Fatalf("Failed to unmarshal response: %v", err)
}
ics := fmt.Sprintf(`BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//moca/camp/schedule v1.0//EN
VTIMEZONE: Europe/Rome
`)

for _, item := range items {
eventUID := item.Document.Name
location := item.Document.Fields.Location.MapValue.Fields.Name.StringValue
speakerNames := make([]string, 0, len(item.Document.Fields.Speakers.ArrayValue.Values))
for _, v := range item.Document.Fields.Speakers.ArrayValue.Values {
name := v.MapValue.Fields.Name.StringValue
if name != "" {
name = strings.Replace(name, "\n", "\\n", -1)
name = strings.Replace(name, "\"", "'", -1)
speakerNames = append(speakerNames, name)
}
}
speakers := "unknown"
if len(speakerNames) > 0 {
speakers = strings.Join(speakerNames, ", ")
}
speakerEmail := "unknown"
start, err := time.Parse("2006-01-02T15:04:05Z", item.Document.Fields.BeginTsz.StringValue)
if err != nil {
logrus.Fatalf("Failed to parse start time %q: %v", item.Document.Fields.BeginTsz.StringValue, err)
}
end, err := time.Parse("2006-01-02T15:04:05Z", item.Document.Fields.EndTsz.StringValue)
if err != nil {
logrus.Fatalf("Failed to parse end time %q: %v", item.Document.Fields.EndTsz.StringValue, err)
}
summary := item.Document.Fields.Title.StringValue
description := item.Document.Fields.Description.StringValue
description = strings.Replace(description, "\n", "\\n", -1)
description = strings.Replace(description, "\r", "", -1)
ics += fmt.Sprintf(`BEGIN:VEVENT
UID:%s
ORGANIZER;CN=%s:MAILTO:%s
DTSTAMP:20240912T140000Z
DTSTART:%s
DTEND:%s
SUMMARY:%s
DESCRIPTION: %s
GEO:42.5816338;14.0901461
LOCATION: %s
END:VEVENT
`,
eventUID,
speakers,
speakerEmail,
start.Format("20060102T150405Z"),
end.Format("20060102T150405Z"),
summary,
description,
location,
)
}
ics += fmt.Sprintln("END:VCALENDAR")
ics = strings.Replace(ics, "\n", "\r\n", -1)
fmt.Println(ics)
}

0 comments on commit a6f3d75

Please sign in to comment.