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"