Files
mopidy-webhooks/mopidy_webhooks/frontend.py
Colin Powell 52655cecfd Add Mopidy URI to data packet sent via webhook
This commit adds one new property, which is the URI that mopidy is using
as the source to play the media file.  The significance here is that if
you use something like Podgrab to auto-download and push podcasts to a
directory in Mopidy's media files, and if it has 'podcast' in the name
we can use that instead of the hit-or-miss check on the MP3 genre of
Podcast, which is a convention not many podcasts use.
2023-01-12 11:18:45 -05:00

99 lines
3.4 KiB
Python

import logging
import time
import json
import pykka
import requests
from mopidy.core import CoreListener
logger = logging.getLogger(__name__)
class WebhooksFrontend(pykka.ThreadingActor, CoreListener):
def __init__(self, config, core):
super().__init__()
self.config = config
self.webhook_urls = []
self.last_start_time = None
def on_start(self):
logger.info("Parsing webhook URLs and tokens")
self.webhook_urls = self.config["webhooks"]["urls"].split(",")
self.webhook_tokens = self.config["webhooks"]["tokens"].split(",")
def _build_post_data(self, track) -> dict:
artists = ", ".join(sorted([a.name for a in track.artists]))
artists_list = [a for a in track.artists]
try:
musicbrainz_artist_id = artists_list[0].musicbrainz_id
except IndexError:
musicbrainz_artist_id = None
duration = track.length and track.length // 1000 or 0
return {
"name": track.name,
"artist": artists,
"album": track.album.name,
"track_number": track.track_no,
"run_time_ticks": track.length,
"run_time": str(duration),
"musicbrainz_track_id": track.musicbrainz_id,
"musicbrainz_album_id": track.album.musicbrainz_id,
"musicbrainz_artist_id": musicbrainz_artist_id,
"mopidy_uri": track.uri,
}
def _post_update_to_webhooks(self, post_data: dict, status: str):
post_data["status"] = status
for index, webhook_url in enumerate(self.webhook_urls):
token = ""
headers = {}
try:
token = self.webhook_tokens[index]
except IndexError:
logger.info(f"No token found for Webhook URL: {webhook_url}")
if token:
headers["Authorization"] = "Token {token}"
response = requests.post(
webhook_url, json=json.dumps(post_data), headers=headers
)
logger.info(response)
def track_playback_started(self, tl_track):
track = tl_track.track
artists = ", ".join(sorted([a.name for a in track.artists]))
self.last_start_time = int(time.time())
logger.debug(f"Now playing track: {artists} - {track.name}")
post_data = self._build_post_data(tl_track.track)
# Build post data to send to urls
if not self.webhook_urls:
logger.info("No webhook URLS are configured ")
return
logger.info(f"Scrobbling via webhooks: {artists} - {track.name}")
self._post_update_to_webhooks(post_data, "started")
def track_playback_ended(self, tl_track, time_position):
track = tl_track.track
artists = ", ".join(sorted([a.name for a in track.artists]))
duration = track.length and track.length // 1000 or 0
time_position = time_position // 1000
post_data = self._build_post_data(tl_track.track)
if time_position < duration // 2 and time_position < 240:
logger.debug(
"Track not played long enough to scrobble. (50% or 240s)"
)
return
if self.last_start_time is None:
self.last_start_time = int(time.time()) - duration
logger.info(
f"Scrobbling finished via webhooks: {artists} - {track.name}"
)
self._post_update_to_webhooks(post_data, "stopped")