From ad492c14f9658667547a04ed3ebca502c88d81b2 Mon Sep 17 00:00:00 2001 From: oddluck <39967334+oddluck@users.noreply.github.com> Date: Sat, 13 Jun 2020 10:13:21 +0000 Subject: [PATCH] add AzuraIRC plugin --- AzuraCast/LICENSE.txt | 21 +++++ AzuraCast/README.md | 2 + AzuraCast/__init__.py | 49 +++++++++++ AzuraCast/config.py | 36 ++++++++ AzuraCast/plugin.py | 164 +++++++++++++++++++++++++++++++++++++ AzuraCast/requirements.txt | 1 + AzuraCast/test.py | 15 ++++ AzuraIRC | 1 - 8 files changed, 288 insertions(+), 1 deletion(-) create mode 100644 AzuraCast/LICENSE.txt create mode 100644 AzuraCast/README.md create mode 100644 AzuraCast/__init__.py create mode 100644 AzuraCast/config.py create mode 100644 AzuraCast/plugin.py create mode 100644 AzuraCast/requirements.txt create mode 100644 AzuraCast/test.py delete mode 160000 AzuraIRC diff --git a/AzuraCast/LICENSE.txt b/AzuraCast/LICENSE.txt new file mode 100644 index 0000000..33b7464 --- /dev/null +++ b/AzuraCast/LICENSE.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 cottongin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/AzuraCast/README.md b/AzuraCast/README.md new file mode 100644 index 0000000..bc6d5ae --- /dev/null +++ b/AzuraCast/README.md @@ -0,0 +1,2 @@ +Plugin for the AzuraCast API +forked from https://gitlab.com/cottongin/AzuraCast diff --git a/AzuraCast/__init__.py b/AzuraCast/__init__.py new file mode 100644 index 0000000..d667356 --- /dev/null +++ b/AzuraCast/__init__.py @@ -0,0 +1,49 @@ +### +# Copyright (c) 2018, cottongin +# All rights reserved. +# +# +### + +""" +AzuraCast: Plugin for the AzuraCast API +""" + +import sys +import supybot +from supybot import world + +# Use this for the version of this plugin. You may wish to put a CVS keyword +# in here if you're keeping the plugin in CVS or some similar system. +__version__ = "" + +# XXX Replace this with an appropriate author or supybot.Author instance. +__author__ = supybot.authors.unknown + +# This is a dictionary mapping supybot.Author instances to lists of +# contributions. +__contributors__ = {} + +# This is a url where the most recent plugin package can be downloaded. +__url__ = '' + +from . import config +from . import plugin +if sys.version_info >= (3, 4): + from importlib import reload +else: + from imp import reload +# In case we're being reloaded. +reload(config) +reload(plugin) +# Add more reloads here if you add third-party modules and want them to be +# reloaded when this plugin is reloaded. Don't forget to import them as well! + +if world.testing: + from . import test + +Class = plugin.Class +configure = config.configure + + +# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79: diff --git a/AzuraCast/config.py b/AzuraCast/config.py new file mode 100644 index 0000000..4e19ccb --- /dev/null +++ b/AzuraCast/config.py @@ -0,0 +1,36 @@ +### +# Copyright (c) 2018, cottongin +# All rights reserved. +# +# +### + +from supybot import conf, registry +try: + from supybot.i18n import PluginInternationalization + _ = PluginInternationalization('AzuraCast') +except: + # Placeholder that allows to run the plugin on a bot + # without the i18n module + _ = lambda x: x + + +def configure(advanced): + # This will be called by supybot to configure this module. advanced is + # a bool that specifies whether the user identified themself as an advanced + # user or not. You should effect your configuration by manipulating the + # registry as appropriate. + from supybot.questions import expect, anything, something, yn + conf.registerPlugin('AzuraCast', True) + + +AzuraCast = conf.registerPlugin('AzuraCast') +# This is where your configuration variables (if any) should go. For example: +# conf.registerGlobalValue(AzuraCast, 'someConfigVariableName', +# registry.Boolean(False, _("""Help for someConfigVariableName."""))) +conf.registerGlobalValue(AzuraCast, 'AzuraAPI', + registry.String('', _("""AzuraCast local API URL"""))) +conf.registerGlobalValue(AzuraCast, 'PublicURL', + registry.String('', _("""Public URL for your radio"""))) + +# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79: diff --git a/AzuraCast/plugin.py b/AzuraCast/plugin.py new file mode 100644 index 0000000..9c27e72 --- /dev/null +++ b/AzuraCast/plugin.py @@ -0,0 +1,164 @@ +### +# Copyright (c) 2018, cottongin +# All rights reserved. +# see LICENSE.txt +# +### + +import requests + +from supybot import utils, plugins, ircutils, callbacks +from supybot.commands import * +try: + from supybot.i18n import PluginInternationalization + _ = PluginInternationalization('AzuraCast') +except ImportError: + # Placeholder that allows to run the plugin on a bot + # without the i18n module + _ = lambda x: x + + +class AzuraCast(callbacks.Plugin): + """Plugin for the AzuraCast API""" + threaded = True + + def __init__(self, irc): + self.__parent = super(AzuraCast, self) + self.__parent.__init__(irc) + + self.BASE_API = self.registryValue('AzuraAPI') + '{endpoint}' + self.PUB_URL = self.registryValue('PublicURL') + '{name}' + + def _fetchURL(self, url, headers=None): + return requests.get(url, headers=headers).json() + + def _parseData(self, data): + stations = {} + for station in data: + tmp_dict = {} + code = station['station']['shortcode'] + tmp_dict['id'] = station['station']['id'] + tmp_dict['name'] = station['station']['name'] + tmp_dict['description'] = station['station']['description'] + tmp_dict['player_url'] = station['station']['listen_url'].split('?')[0] \ + if station['station']['is_public'] else '' + tmp_dict['public_url'] = self.PUB_URL.format( + name=code) if station['station']['is_public'] else '' + tmp_dict['listeners'] = station['listeners'] + tmp_dict['nowplaying'] = station['now_playing'] + tmp_dict['url'] = station['station']['listen_url'] + stations[code] = tmp_dict + return stations + + @wrap([getopts({'station': 'somethingWithoutSpaces'})]) + def nowplaying(self, irc, msg, args, options): + """ + Fetches what is now playing + """ + options = dict(options) + station = options.get('station') + endpoint = 'nowplaying' + url = self.BASE_API.format(endpoint=endpoint) + + data = self._fetchURL(url) + + if not data: + irc.reply('ERROR: Something went wrong fetching data @ {}'.format(url)) + return + + data = self._parseData(data) + + output = [] + if station: + # one station only + d = data.get(station.lower()) + prefix = ircutils.bold('Now Playing on {}:'.format(d['name'])) + album = ' [{}]'.format(d['nowplaying']['song']['album']) \ + if d['nowplaying']['song']['album'] else '' + url = ' | {}'.format(d['url']) + np = '{}'.format(d['nowplaying']['song']['text']) + listeners = " | Listeners: {}".format(d['listeners']['current']) + string = '{} {}{}{}{}'.format(prefix, np, album, listeners, url) + output.append(string) + else: + # all stations? + for s,d in data.items(): + prefix = ircutils.bold('Now Playing on {}:'.format(d['name'])) + album = ' [{}]'.format(d['nowplaying']['song']['album']) \ + if d['nowplaying']['song']['album'] else '' + url = ' | {}'.format(d['url']) + np = '{}'.format(d['nowplaying']['song']['text']) + listeners = " | Listeners: {}".format(d['listeners']['current']) + string = '{} {}{}{}{}'.format(prefix, np, album, listeners, url) + output.append(string) + + for string in output: + irc.reply(string) + + return + + @wrap([getopts({'station': 'somethingWithoutSpaces'})]) + def listeners(self, irc, msg, args, options): + """ + Fetches listeners + """ + options = dict(options) + station = options.get('station') + endpoint = 'nowplaying' + url = self.BASE_API.format(endpoint=endpoint) + + data = self._fetchURL(url) + + if not data: + irc.reply('ERROR: Something went wrong fetching data @ {}'.format(url)) + return + + data = self._parseData(data) + + output = [] + if station: + # one station only + d = data.get(station.lower()) + count = d['listeners']['current'] + if count > 1 and count != 0: + cur = 'are currently' + plr = ' {} listeners '.format(ircutils.bold(count)) + elif count == 1: + cur = 'is currently' + plr = ' {} listener '.format(ircutils.bold(count)) + else: + cur = 'are no listeners' + plr = ' ' + string = 'There {}{}on {}'.format( + cur, plr, + ircutils.bold(d['name'])) + output.append(string) + else: + # all stations? + for s,d in data.items(): + count = d['listeners']['current'] + if count > 1 and count != 0: + cur = 'are currently' + plr = ' {} listeners '.format(ircutils.bold(count)) + elif count == 1: + cur = 'is currently' + plr = ' {} listener '.format(ircutils.bold(count)) + else: + cur = 'are no listeners' + plr = ' ' + string = 'There {}{}on {}'.format( + cur, plr, + ircutils.bold(d['name'])) + output.append(string) + + + for string in output: + irc.reply(string) + + return + + +Class = AzuraCast + + +# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79: diff --git a/AzuraCast/requirements.txt b/AzuraCast/requirements.txt new file mode 100644 index 0000000..247e33f --- /dev/null +++ b/AzuraCast/requirements.txt @@ -0,0 +1 @@ +requests>=2.19.1 \ No newline at end of file diff --git a/AzuraCast/test.py b/AzuraCast/test.py new file mode 100644 index 0000000..df22f54 --- /dev/null +++ b/AzuraCast/test.py @@ -0,0 +1,15 @@ +### +# Copyright (c) 2018, cottongin +# All rights reserved. +# +# +### + +from supybot.test import * + + +class AzuraCastTestCase(PluginTestCase): + plugins = ('AzuraCast',) + + +# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79: diff --git a/AzuraIRC b/AzuraIRC deleted file mode 160000 index 88f0f5e..0000000 --- a/AzuraIRC +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 88f0f5e8b543f8bb1548c45e42a183381c2008c5