PUSHER_ prepends all related actions; Radio updater
This commit is contained in:
@ -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 )
|
||||
|
||||
|
||||
|
||||
##
|
||||
|
||||
@ -62,7 +62,7 @@ class WebsocketHandler(tornado.websocket.WebSocketHandler):
|
||||
|
||||
|
||||
def on_message(self, message):
|
||||
|
||||
|
||||
message = json_decode(message)
|
||||
|
||||
if 'data' in message:
|
||||
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -87,7 +87,8 @@ const SpotifyMiddleware = (function(){
|
||||
break
|
||||
|
||||
// when radio returns
|
||||
case 'RADIO':
|
||||
case 'PUSHER_RADIO_STARTED':
|
||||
case 'PUSHER_RADIO_CHANGED':
|
||||
|
||||
next(action)
|
||||
|
||||
|
||||
@ -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',
|
||||
|
||||
@ -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(
|
||||
{},
|
||||
|
||||
@ -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"}}'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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" />
|
||||
|
||||
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 />
|
||||
|
||||
Connecting
|
||||
{service}
|
||||
</span>
|
||||
)
|
||||
}else{
|
||||
return (
|
||||
<span className="text red-text connection-status">
|
||||
<span className="red-text connection-status">
|
||||
<FontAwesome name="exclamation-triangle" />
|
||||
|
||||
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') }
|
||||
|
||||
{ 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>
|
||||
|
||||
Reference in New Issue
Block a user