PUSHER_ prepends all related actions; Radio updater

This commit is contained in:
James Barnsley
2017-02-21 05:46:28 +13:00
parent 40b83037b3
commit 60290db452
9 changed files with 120 additions and 109 deletions

View File

@ -82,7 +82,10 @@ class IrisCore(object):
def broadcast(self, data):
for connection in self.connections.itervalues():
connection['connection'].write_message( json_encode(data) )
return {}
return {
'status': 'ok',
'message': 'Broadcast to '+str(len(self.connections))+' connections'
}
##
# Connections
@ -227,17 +230,28 @@ class IrisCore(object):
self.radio = data
self.radio['enabled'] = 1;
self.core.tracklist.clear()
self.core.tracklist.set_consume( True )
self.load_more_tracks()
self.core.playback.play()
self.broadcast({
'type': 'radio_started',
'radio': self.radio
})
return self.get_radio({})
uris = self.load_more_tracks()
# no uris means we can't play radio
if not uris:
return {
'error': 'No recommendations found'
}
# if we got recommendations
else:
self.core.tracklist.clear()
self.core.tracklist.set_consume( True )
self.core.tracklist.add( uris = uris )
self.core.playback.play()
self.broadcast({
'type': 'radio_started',
'radio': self.radio
})
return self.get_radio({})
def stop_radio(self, data):
self.radio = {
@ -280,12 +294,28 @@ class IrisCore(object):
for track in response['tracks']:
uris.append( track['uri'] )
self.core.tracklist.add( uris = uris )
return uris
except:
logger.error('IrisFrontend: Failed to fetch Spotify recommendations')
self.broadcast({
'error': 'Failed to fetch radio recommendations'
})
return False
def check_for_radio_update( self ):
tracklistLength = self.core.tracklist.length.get()
if( tracklistLength <= 5 and self.radio['enabled'] == 1 ):
uris = self.load_more_tracks()
if not uris:
self.broadcast({
'error': 'Could not fetch tracklist length',
'source': 'check_for_radio_update'
})
logger.warning('IrisFrontend: Could not fetch tracklist length')
else:
self.core.tracklist.add( uris = uris )
##

View File

@ -62,7 +62,7 @@ class WebsocketHandler(tornado.websocket.WebSocketHandler):
def on_message(self, message):
message = json_decode(message)
if 'data' in message:

View File

@ -59,21 +59,21 @@ export function sendAuthorization( recipient_connectionid, authorization, me ){
export function startRadio( uris ){
return {
type: 'START_RADIO',
type: 'PUSHER_START_RADIO',
uris: uris
}
}
export function stopRadio(){
return {
type: 'STOP_RADIO'
type: 'PUSHER_STOP_RADIO'
}
}
export function debug( data = null ){
export function debug( message = null ){
return {
type: 'PUSHER_DEBUG',
data: data
message: message
}
}

View File

@ -104,7 +104,7 @@ const PusherMiddleware = (function(){
return false
}
response.type = 'CONFIG'
response.type = 'PUSHER_CONFIG'
store.dispatch(response)
if (response.config.spotify_username){
store.dispatch(spotifyActions.getUser('spotify:user:'+response.config.spotify_username))
@ -122,7 +122,7 @@ const PusherMiddleware = (function(){
console.error(response.error)
return false
}
response.type = 'VERSION'
response.type = 'PUSHER_VERSION'
store.dispatch(response)
}
)
@ -134,7 +134,7 @@ const PusherMiddleware = (function(){
return false
}
response.type = 'RADIO'
response.type = 'PUSHER_RADIO'
store.dispatch(response)
}
)
@ -177,7 +177,7 @@ const PusherMiddleware = (function(){
store.dispatch( uiActions.createNotification('Upgrade failed, please upgrade manually','bad') )
}
response.type = 'VERSION'
response.type = 'PUSHER_VERSION'
store.dispatch(response)
}
)
@ -217,15 +217,10 @@ const PusherMiddleware = (function(){
break
case 'PUSHER_DEBUG':
request( action )
request( action.message.method, action.message.data )
.then(
response => {
if (response.error){
console.error(response.error)
return false
}
response.type = 'DEBUG'
store.dispatch(response)
response => {
store.dispatch({type: 'DEBUG', response: response})
}
)
break;
@ -262,26 +257,10 @@ const PusherMiddleware = (function(){
}
break
case 'START_RADIO':
request('broadcast', {
type: 'browser_notification',
title: 'Radio started',
body: store.getState().pusher.username +' started radio mode',
icon: ''
})
.then(
response => {
if (response.data.error){
console.error(response.data.error)
return false
}
store.dispatch(uiActions.createNotification('Starting radio...'))
}
)
case 'PUSHER_START_RADIO':
store.dispatch(uiActions.createNotification('Starting radio...'))
var data = {
method: 'start_radio',
seed_artists: [],
seed_genres: [],
seed_tracks: []
@ -301,34 +280,27 @@ const PusherMiddleware = (function(){
}
}
request( data )
request( 'start_radio', data )
.then(response => {
console.log(response)
})
break
case 'STOP_RADIO':
request('broadcast', {
type: 'browser_notification',
title: 'Radio stopped',
body: store.getState().pusher.username +' stopped radio mode',
icon: ''
})
.then(
response => {
if (response.data.error){
console.error(response.data.error)
return false
}
store.dispatch(uiActions.createNotification('Stopping radio'))
}
)
case 'PUSHER_STOP_RADIO':
store.dispatch(uiActions.createNotification('Stopping radio'))
var data = {
method: 'stop_radio',
seed_artists: [],
seed_genres: [],
seed_tracks: []
}
request( data )
// we don't need to wait for request, as change will be broadcast
request( 'stop_radio', data )
break
case 'PUSHER_BROWSER_NOTIFICATION':
store.dispatch(uiActions.createBrowserNotification(action))
break
// This action is irrelevant to us, pass it on to the next middleware

View File

@ -87,7 +87,8 @@ const SpotifyMiddleware = (function(){
break
// when radio returns
case 'RADIO':
case 'PUSHER_RADIO_STARTED':
case 'PUSHER_RADIO_CHANGED':
next(action)

View File

@ -215,6 +215,13 @@ export function closeModal(){
* Subtle info/tooltip messages
**/
export function createBrowserNotification( data ){
return {
type: 'BROWSER_NOTIFICATION',
data: data
}
}
export function createNotification( content, type = 'default' ){
return {
type: 'CREATE_NOTIFICATION',

View File

@ -13,7 +13,7 @@ export default function reducer(ui = {}, action){
case 'UI_SET':
return Object.assign({}, ui, action.data)
case 'CONFIG':
case 'PUSHER_CONFIG':
return Object.assign({}, ui, { config: action.config })
case 'TOGGLE_SIDEBAR':
@ -147,8 +147,10 @@ export default function reducer(ui = {}, action){
}
return Object.assign({}, ui, { current_tracklist: tracklist, queue_metadata: action.queue_metadata });
case 'RADIO':
case 'START_RADIO':
case 'PUSHER_RADIO':
case 'PUSHER_RADIO_STARTED':
case 'PUSHER_RADIO_CHANGED':
case 'PUSHER_RADIO_STOPPED':
return Object.assign({}, ui, { seeds_resolved: false }, { radio: action.radio })
case 'RADIO_SEEDS_RESOLVED':
@ -371,7 +373,7 @@ export default function reducer(ui = {}, action){
case 'USER_PLAYLISTS_LOADED':
var users = Object.assign([], ui.users)
var playlists_uris = []
if (users[action.key].playlists_uris) playlists_uris = users[action.key].playlists_uris
if (users[action.key] && users[action.key].playlists_uris) playlists_uris = users[action.key].playlists_uris
var artist = Object.assign(
{},

View File

@ -25,22 +25,7 @@ class Debug extends React.Component{
this.state = {
mopidy_call: 'playlists.asList',
mopidy_data: '{}',
pusher_data: '{}'
}
}
componentDidMount(){
if( this.props.connectionid ){
var data = {
action: "broadcast",
data: {
type: 'browser_notification',
title: "Title",
body: "Test notification",
icon: "http://lorempixel.com/100/100/nature/"
}
}
this.setState({ pusher_data: JSON.stringify(data) })
pusher_data: '{"method":"broadcast","data":{"type":"browser_notification","title":"Testing","body":"This is my message"}}'
}
}

View File

@ -56,28 +56,28 @@ class Settings extends React.Component{
}
renderConnectionStatus(service){
if( this.props[service].connected ){
if( this.props[service.toLowerCase()].connected ){
return (
<span className="text green-text connection-status">
<span className="green-text connection-status">
<FontAwesome name="check" />
&nbsp;
Connected
{service}
</span>
)
}else if( this.props[service].connecting ){
}else if( this.props[service.toLowerCase()].connecting ){
return (
<span className="text grey-text connection-status">
<span className="grey-text connection-status">
<FontAwesome name="circle-o-notch" spin />
&nbsp;
Connecting
{service}
</span>
)
}else{
return (
<span className="text red-text connection-status">
<span className="red-text connection-status">
<FontAwesome name="exclamation-triangle" />
&nbsp;
Not connected
{service}
</span>
)
}
@ -127,6 +127,19 @@ class Settings extends React.Component{
)
}
renderApplyButton(){
if (this.props.mopidy.host == this.state.mopidy_host && this.props.mopidy.port == this.state.mopidy_port) return null
return (
<div className="field">
<div className="name"></div>
<div className="input">
<button type="submit" className="secondary">Apply and reload</button>
</div>
</div>
)
}
render(){
var actions = (
@ -142,12 +155,16 @@ class Settings extends React.Component{
<section>
<h4 className="underline">Mopidy</h4>
<h4 className="underline">System</h4>
<form onSubmit={(e) => this.setMopidyConfig(e)}>
<div className="field">
<div className="name">Status</div>
<div className="input">
{ this.renderConnectionStatus('mopidy') }
<div className="text">
{ this.renderConnectionStatus('Mopidy') }
&nbsp;&nbsp;
{ this.renderConnectionStatus('Pusher') }
</div>
</div>
</div>
<div className="field">
@ -177,20 +194,17 @@ class Settings extends React.Component{
onChange={ e => this.setState({ mopidy_port: e.target.value })}
value={ this.state.mopidy_port } />
</div>
</div>
<div className="field">
<div className="name"></div>
<div className="input">
<button type="submit" className="secondary">Apply and reload</button>
</div>
</div>
{this.renderApplyButton()}
</form>
<h4 className="underline">Spotify</h4>
<div className="field">
<div className="name">Status</div>
<div className="input">
{ this.renderConnectionStatus('spotify') }
<div className="text">
{ this.renderConnectionStatus('Spotify') }
</div>
</div>
</div>
<form>