diff --git a/assets/bees/mixcloudbee.png b/assets/bees/mixcloudbee.png new file mode 100644 index 00000000..10eeaf03 Binary files /dev/null and b/assets/bees/mixcloudbee.png differ diff --git a/bees/mixcloudbee/mixcloudbee.go b/bees/mixcloudbee/mixcloudbee.go new file mode 100644 index 00000000..5f86fb2d --- /dev/null +++ b/bees/mixcloudbee/mixcloudbee.go @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2018 Stefan Derkits + * 2018 Christian Muehlhaeuser + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + * Authors: + * Stefan Derkits + * Christian Muehlhaeuser + */ + +package mixcloudbee + +import ( + "time" + + "github.com/horrendus/go-mixcloud" + + "github.com/muesli/beehive/bees" +) + +// MixcloudBee is a Bee that can interface with Mixcloud. +type MixcloudBee struct { + bees.Bee + + baseUrl string + feed string + + client *mixcloud.Client + lastUpdate time.Time + + eventChan chan bees.Event +} + +// Poll a Mixcloud Cloudcasts feed +func (mod *MixcloudBee) pollFeed(feed string) { + mod.LogDebugf("Parsing feed %s", mod.feed) + var allCloudcastsData []mixcloud.CloudcastData + var opt mixcloud.ListOptions + opt.Since = mod.lastUpdate + opt.Until = time.Now() + mod.lastUpdate = opt.Until + mod.Logln("Since", opt.Since, "Until", opt.Until) + cloudcasts, err := mod.client.GetCloudcasts(mod.feed, &opt) + if err != nil { + mod.LogErrorf("Error getting Cloudcasts: %s", err) + return + } + allCloudcastsData = append(allCloudcastsData, cloudcasts.Data...) + nextUrl := cloudcasts.Paging.NextURL + for { + if nextUrl == "" { + break + } + // the following line is necessary to always create a new object, else just some values would be overwritten + // and missing values would stay the same as before + cloudcasts = mixcloud.Cloudcasts{} + err := mod.client.GetPage(nextUrl, &cloudcasts) + allCloudcastsData = append(allCloudcastsData, cloudcasts.Data...) + if err != nil { + mod.LogErrorf("Error getting next Cloudcast page: %s", err) + break + } + nextUrl = cloudcasts.Paging.NextURL + } + + for _, cloudcast := range allCloudcastsData { + newCloudcastEvent := bees.Event{ + Bee: mod.Name(), + Name: "new_cloudcast", + Options: []bees.Placeholder{ + { + Name: "name", + Type: "string", + Value: cloudcast.Name, + }, + { + Name: "url", + Type: "string", + Value: cloudcast.URL, + }, + { + Name: "slug", + Type: "string", + Value: cloudcast.Slug, + }, + }, + } + mod.eventChan <- newCloudcastEvent + } +} + +// Action triggers the action passed to it. +func (mod *MixcloudBee) Action(action bees.Action) []bees.Placeholder { + outs := []bees.Placeholder{} + + switch action.Name { + case "poll_feed": + mod.pollFeed(mod.feed) + default: + panic("Unknown action triggered in " + mod.Name() + ": " + action.Name) + } + + return outs +} + +// Run executes the Bee's event loop. +func (mod *MixcloudBee) Run(cin chan bees.Event) { + mod.eventChan = cin +} + +// ReloadOptions parses the config options and initializes the Bee. +func (mod *MixcloudBee) ReloadOptions(options bees.BeeOptions) { + mod.SetOptions(options) + + options.Bind("baseUrl", &mod.baseUrl) + options.Bind("feed", &mod.feed) + + mod.client = mixcloud.NewClient(nil) +} diff --git a/bees/mixcloudbee/mixcloudbeefactory.go b/bees/mixcloudbee/mixcloudbeefactory.go new file mode 100644 index 00000000..264879cd --- /dev/null +++ b/bees/mixcloudbee/mixcloudbeefactory.go @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2018 Stefan Derkits + * 2018 Christian Muehlhaeuser + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + * Authors: + * Stefan Derkits + * Christian Muehlhaeuser + */ + +package mixcloudbee + +import "github.com/muesli/beehive/bees" + +// mixcloudBeeFactory is a factory for mixcloudBees. +type MixcloudBeeFactory struct { + bees.BeeFactory +} + +// New returns a new Bee instance configured with the supplied options. +func (factory *MixcloudBeeFactory) New(name, description string, options bees.BeeOptions) bees.BeeInterface { + bee := MixcloudBee{ + Bee: bees.NewBee(name, factory.ID(), description, options), + } + bee.ReloadOptions(options) + + return &bee +} + +// ID returns the ID of this Bee. +func (factory *MixcloudBeeFactory) ID() string { + return "mixcloudbee" +} + +// Name returns the name of this Bee. +func (factory *MixcloudBeeFactory) Name() string { + return "Mixcloud" +} + +// Description returns the description of this Bee. +func (factory *MixcloudBeeFactory) Description() string { + return "Interact with Mixcloud" +} + +// Image returns the filename of an image for this Bee. +func (factory *MixcloudBeeFactory) Image() string { + return factory.ID() + ".png" +} + +// LogoColor returns the preferred logo background color (used by the admin interface). +func (factory *MixcloudBeeFactory) LogoColor() string { + return "#52aad8" +} + +// Options returns the options available to configure this Bee. +func (factory *MixcloudBeeFactory) Options() []bees.BeeOptionDescriptor { + opts := []bees.BeeOptionDescriptor{ + { + Name: "feed", + Description: "Feed to follow", + Type: "string", + Mandatory: true, + }, + } + return opts +} + +// Events describes the available events provided by this Bee. +func (factory *MixcloudBeeFactory) Events() []bees.EventDescriptor { + events := []bees.EventDescriptor{ + { + Namespace: factory.Name(), + Name: "new_cloudcast", + Description: "A new cloudcast is available", + Options: []bees.PlaceholderDescriptor{ + { + Name: "name", + Description: "Name of the Cloudcast", + Type: "string", + }, + { + Name: "url", + Description: "Cloudcast URL", + Type: "string", + }, + { + Name: "slug", + Description: "Cloudcast Slug", + Type: "string", + }, + }, + }, + } + return events +} + +// Actions describes the available actions provided by this Bee. +func (factory *MixcloudBeeFactory) Actions() []bees.ActionDescriptor { + actions := []bees.ActionDescriptor{ + { + Namespace: factory.Name(), + Name: "poll_feed", + Description: "Polls the Mixcloud Feed specified in the options", + Options: []bees.PlaceholderDescriptor{ + + }, + }, + } + return actions +} + +func init() { + f := MixcloudBeeFactory{} + bees.RegisterFactory(&f) +} diff --git a/go.mod b/go.mod index 692a0da4..138516a6 100644 --- a/go.mod +++ b/go.mod @@ -36,6 +36,7 @@ require ( github.com/google/go-querystring v1.0.0 // indirect github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c // indirect github.com/guelfey/go.dbus v0.0.0-20131113121618-f6a3a2366cc3 + github.com/horrendus/go-mixcloud v0.0.0-20190427074402-c2164c9e194c github.com/huandu/facebook v2.3.1+incompatible github.com/jacobsa/go-serial v0.0.0-20180131005756-15cf729a72d4 github.com/jayeshsolanki93/devgorant v0.0.0-20160810172004-69fb03e5c3b1 diff --git a/go.sum b/go.sum index 292a50b0..d01fc289 100644 --- a/go.sum +++ b/go.sum @@ -82,6 +82,8 @@ github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/guelfey/go.dbus v0.0.0-20131113121618-f6a3a2366cc3 h1:fngCxKbvZdctIsWj2hYijhAt4iK0JXSSA78B36xP0yI= github.com/guelfey/go.dbus v0.0.0-20131113121618-f6a3a2366cc3/go.mod h1:0CNX5Cvi77WEH8llpfZ/ieuqyceb1cnO5//b5zzsnF8= +github.com/horrendus/go-mixcloud v0.0.0-20190427074402-c2164c9e194c h1:nnb4dSY7AcPeDk91FQt+wpBGV2M2vYdz/3sjN21b/pU= +github.com/horrendus/go-mixcloud v0.0.0-20190427074402-c2164c9e194c/go.mod h1:CyhbQCOE1KktIhrolqimsL9EAgBF9BsWYjnc3hRG5r0= github.com/huandu/facebook v2.3.1+incompatible h1:+F6kUqKx5TifzMg2fXYZFdA/3VVNphdNK8G4PF2ui74= github.com/huandu/facebook v2.3.1+incompatible/go.mod h1:wJogp9rhXUUjDuhx6ZaR5Eylx3dsJmy0zyFRaPYUq5g= github.com/jacobsa/go-serial v0.0.0-20180131005756-15cf729a72d4 h1:G2ztCwXov8mRvP0ZfjE6nAlaCX2XbykaeHdbT6KwDz0= diff --git a/hives.go b/hives.go index 8123ed24..4734a6f7 100644 --- a/hives.go +++ b/hives.go @@ -44,6 +44,7 @@ import ( _ "github.com/muesli/beehive/bees/jabberbee" _ "github.com/muesli/beehive/bees/jenkinsbee" _ "github.com/muesli/beehive/bees/mastodonbee" + _ "github.com/muesli/beehive/bees/mixcloudbee" _ "github.com/muesli/beehive/bees/mumblebee" _ "github.com/muesli/beehive/bees/nagiosbee" _ "github.com/muesli/beehive/bees/openweathermapbee"