Switch to unified view

a b/src/radio_scripts/radio-paradise-get-flac.py
1
#!/usr/bin/env python3
2
from __future__ import print_function
3
# Copyright (C) 2017-2018 J.F.Dockes
4
#   This program is free software; you can redistribute it and/or modify
5
#   it under the terms of the GNU General Public License as published by
6
#   the Free Software Foundation; either version 2 of the License, or
7
#   (at your option) any later version.
8
#
9
#   This program is distributed in the hope that it will be useful,
10
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
11
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
#   GNU General Public License for more details.
13
#
14
#   You should have received a copy of the GNU General Public License
15
#   along with this program; if not, write to the
16
#   Free Software Foundation, Inc.,
17
#   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18
#
19
20
# Handling the Flac channel from radio-paradise. This is made of
21
# 'blocks' which are multi-title periods with a single audio
22
# url. Metadata should be displayed according to the elapsed time in
23
# the audio (each metadata entry in the array gives the start and
24
# duration for the song in mS).  If metadata is re-fetched during the
25
# block, it is front-truncated, more or less according to the current
26
# time, and it may happen that the metadata for the song playing
27
# locally is not there any more (someone starting at this point would
28
# begin with the next point). The thing which does not change for
29
# successive fetches of the same block is the "end_event" value. We
30
# cache the first fetch for any block so that we are sure to have the
31
# right metadata available when upmpdcli calls us
32
33
34
import requests
35
import json
36
import sys
37
import os
38
39
tmpname = '/tmp/up-rp-pldata.json'
40
41
def debug(x):
42
    print("%s"%x, file=sys.stderr)
43
    pass
44
45
# Write new block data to cache. We always output the audio url in this case.
46
def newcache(jsd):
47
    global out
48
    s = json.dumps(jsd,sort_keys=True, indent=4)
49
    open(tmpname, 'wb').write(s.encode('utf-8'))
50
    os.chmod(tmpname, 0o666)
51
    out["audioUrl"] = jsd['url'] + "?src=alexa"
52
53
54
# We're expecting the current elapsed playing time in mS as arg
55
elapsedms = -1
56
try:
57
    elapsedms = int(sys.argv[1])
58
except:
59
    pass
60
61
debug("rp-get-flac: got elapsed %d" % elapsedms)
62
63
# Try to read the current cached data.
64
cached = None
65
try:
66
    s = open(tmpname, 'rb').read().decode('utf-8', errors = 'replace')
67
    cached = json.loads(s)
68
except Exception as err:
69
    debug("No cached data read: %s" % err)
70
    pass
71
72
73
r = requests.get("https://api.radioparadise.com/api/get_block",
74
                 params={"bitrate": "4", "info":"true"})
75
r.raise_for_status()
76
newjsd = r.json()
77
78
out = {}
79
80
# If we are currently playing, check if our cached data is still
81
# relevant. If it is, it is more complete than the new data which is
82
# front-truncated, so we use it, so that we can check if we are still
83
# playing a track which might not be in the new list. Also if we go to
84
# a new block, we output the audio URL
85
if cached:
86
    debug("Cached end_event %s new %s"%(cached['end_event'], newjsd['end_event']))
87
if elapsedms >= 0 and cached and 'end_event' in cached and \
88
       cached['end_event'] == newjsd['end_event']:
89
    debug("rp-get-flac: using cached data")
90
    jsd = cached
91
else:
92
    debug("outputting audio url because using new metadata or not playing")
93
    jsd = newjsd
94
    elapsedms = -1
95
    newcache(jsd)
96
    
97
currentk = None
98
if elapsedms > 0:
99
    songs = jsd['song']
100
    for k in sorted(songs.keys()):
101
        startms = songs[k]['elapsed']
102
        endms  = startms + songs[k]['duration']
103
        debug("k %s Startms %d endms %d" % (k, startms, endms))
104
        if elapsedms >= startms and elapsedms <= endms:
105
            currentk = k
106
            break
107
108
if not currentk:
109
    # Not found ?? Try to reset the thing
110
    debug(("outputting audio url because current elapsed %d " + \
111
          " not found in song array") % elapsedms)
112
    jsd = newjsd
113
    newcache(jsd)
114
    out['reload'] = 3
115
else:
116
    songs = jsd['song']
117
    out['title'] = songs[currentk]['title']
118
    out['artist'] = songs[currentk]['artist']
119
    out['album'] = songs[currentk]['album']
120
    out['artUrl'] = 'http:%s%s' % (jsd['image_base'],
121
                                  songs[currentk]['cover'])
122
    reload = int((endms - elapsedms)/1000)
123
    # Last song: reload a bit earlier so that we can queue the URL
124
    if currentk == len(songs) -1 and reload > 3:
125
        reload -= 2
126
    out['reload'] = reload
127
128
debug("%s" % json.dumps(out))
129
print("%s" % json.dumps(out))