added last.fm chart playlists
added front end support for library tracks
This commit is contained in:
parent
71fdb6620d
commit
f5eb07ca21
@ -95,9 +95,14 @@ def playlist(username=None):
|
|||||||
playlist_add_this_month = request_json.get('add_this_month', None)
|
playlist_add_this_month = request_json.get('add_this_month', None)
|
||||||
playlist_add_last_month = request_json.get('add_last_month', None)
|
playlist_add_last_month = request_json.get('add_last_month', None)
|
||||||
|
|
||||||
|
playlist_library_tracks = request_json.get('include_library_tracks', None)
|
||||||
|
|
||||||
playlist_recommendation = request_json.get('include_recommendations', None)
|
playlist_recommendation = request_json.get('include_recommendations', None)
|
||||||
playlist_recommendation_sample = request_json.get('recommendation_sample', None)
|
playlist_recommendation_sample = request_json.get('recommendation_sample', None)
|
||||||
|
|
||||||
|
playlist_chart_range = request_json.get('chart_range', None)
|
||||||
|
playlist_chart_limit = request_json.get('chart_limit', None)
|
||||||
|
|
||||||
queried_playlist = [i for i in playlists.where(u'name', u'==', playlist_name).stream()]
|
queried_playlist = [i for i in playlists.where(u'name', u'==', playlist_name).stream()]
|
||||||
|
|
||||||
if request.method == 'PUT':
|
if request.method == 'PUT':
|
||||||
@ -111,6 +116,7 @@ def playlist(username=None):
|
|||||||
'name': playlist_name,
|
'name': playlist_name,
|
||||||
'parts': playlist_parts if playlist_parts is not None else [],
|
'parts': playlist_parts if playlist_parts is not None else [],
|
||||||
'playlist_references': playlist_references if playlist_references is not None else [],
|
'playlist_references': playlist_references if playlist_references is not None else [],
|
||||||
|
'include_library_tracks': playlist_library_tracks if playlist_library_tracks is not None else False,
|
||||||
'include_recommendations': playlist_recommendation if playlist_recommendation is not None else False,
|
'include_recommendations': playlist_recommendation if playlist_recommendation is not None else False,
|
||||||
'recommendation_sample': playlist_recommendation_sample if playlist_recommendation_sample is not None else 10,
|
'recommendation_sample': playlist_recommendation_sample if playlist_recommendation_sample is not None else 10,
|
||||||
'uri': None,
|
'uri': None,
|
||||||
@ -127,6 +133,10 @@ def playlist(username=None):
|
|||||||
to_add['add_this_month'] = playlist_add_this_month if playlist_add_this_month is not None else False
|
to_add['add_this_month'] = playlist_add_this_month if playlist_add_this_month is not None else False
|
||||||
to_add['add_last_month'] = playlist_add_last_month if playlist_add_last_month is not None else False
|
to_add['add_last_month'] = playlist_add_last_month if playlist_add_last_month is not None else False
|
||||||
|
|
||||||
|
if playlist_type == 'fmchart':
|
||||||
|
to_add['chart_range'] = playlist_chart_range
|
||||||
|
to_add['chart_limit'] = playlist_chart_limit if playlist_chart_limit is not None else 50
|
||||||
|
|
||||||
playlists.document().set(to_add)
|
playlists.document().set(to_add)
|
||||||
logger.info(f'added {username} / {playlist_name}')
|
logger.info(f'added {username} / {playlist_name}')
|
||||||
|
|
||||||
@ -171,15 +181,28 @@ def playlist(username=None):
|
|||||||
if playlist_add_last_month is not None:
|
if playlist_add_last_month is not None:
|
||||||
dic['add_last_month'] = playlist_add_last_month
|
dic['add_last_month'] = playlist_add_last_month
|
||||||
|
|
||||||
|
if playlist_library_tracks is not None:
|
||||||
|
dic['include_library_tracks'] = playlist_library_tracks
|
||||||
|
|
||||||
if playlist_recommendation is not None:
|
if playlist_recommendation is not None:
|
||||||
dic['include_recommendations'] = playlist_recommendation
|
dic['include_recommendations'] = playlist_recommendation
|
||||||
|
|
||||||
if playlist_recommendation_sample is not None:
|
if playlist_recommendation_sample is not None:
|
||||||
dic['recommendation_sample'] = playlist_recommendation_sample
|
dic['recommendation_sample'] = playlist_recommendation_sample
|
||||||
|
|
||||||
|
if playlist_chart_range is not None:
|
||||||
|
dic['chart_range'] = playlist_chart_range
|
||||||
|
|
||||||
|
if playlist_chart_limit is not None:
|
||||||
|
dic['chart_limit'] = playlist_chart_limit
|
||||||
|
|
||||||
if playlist_type is not None:
|
if playlist_type is not None:
|
||||||
dic['type'] = playlist_type
|
dic['type'] = playlist_type
|
||||||
|
|
||||||
|
if playlist_type == 'fmchart':
|
||||||
|
dic['chart_range'] = 'YEAR'
|
||||||
|
dic['chart_limit'] = 50
|
||||||
|
|
||||||
if len(dic) == 0:
|
if len(dic) == 0:
|
||||||
logger.warning(f'no changes to make for {username} / {playlist_name}')
|
logger.warning(f'no changes to make for {username} / {playlist_name}')
|
||||||
return jsonify({"message": 'no changes to make', "status": "error"}), 400
|
return jsonify({"message": 'no changes to make', "status": "error"}), 400
|
||||||
|
@ -8,7 +8,7 @@ from spotframework.net.network import Network as SpotifyNetwork
|
|||||||
from fmframework.net.network import Network as FmNetwork
|
from fmframework.net.network import Network as FmNetwork
|
||||||
from music.db.user import DatabaseUser
|
from music.db.user import DatabaseUser
|
||||||
from music.model.user import User
|
from music.model.user import User
|
||||||
from music.model.playlist import Playlist, RecentsPlaylist, Sort
|
from music.model.playlist import Playlist, RecentsPlaylist, LastFMChartPlaylist, Sort
|
||||||
|
|
||||||
db = firestore.Client()
|
db = firestore.Client()
|
||||||
|
|
||||||
@ -260,6 +260,39 @@ def parse_playlist_reference(username, playlist_ref=None, playlist_snapshot=None
|
|||||||
add_this_month=playlist_dict.get('add_this_month'),
|
add_this_month=playlist_dict.get('add_this_month'),
|
||||||
day_boundary=playlist_dict.get('day_boundary'))
|
day_boundary=playlist_dict.get('day_boundary'))
|
||||||
|
|
||||||
|
elif playlist_dict.get('type') == 'fmchart':
|
||||||
|
return LastFMChartPlaylist(uri=playlist_dict.get('uri'),
|
||||||
|
name=playlist_dict.get('name'),
|
||||||
|
username=username,
|
||||||
|
|
||||||
|
db_ref=playlist_ref,
|
||||||
|
|
||||||
|
include_recommendations=playlist_dict.get('include_recommendations', False),
|
||||||
|
recommendation_sample=playlist_dict.get('recommendation_sample', 0),
|
||||||
|
include_library_tracks=playlist_dict.get('include_library_tracks', False),
|
||||||
|
|
||||||
|
parts=playlist_dict.get('parts'),
|
||||||
|
playlist_references=playlist_dict.get('playlist_references'),
|
||||||
|
shuffle=playlist_dict.get('shuffle'),
|
||||||
|
|
||||||
|
sort=Sort[playlist_dict.get('sort', 'release_date')],
|
||||||
|
|
||||||
|
description_overwrite=playlist_dict.get('description_overwrite'),
|
||||||
|
description_suffix=playlist_dict.get('description_suffix'),
|
||||||
|
|
||||||
|
lastfm_stat_count=playlist_dict.get('lastfm_stat_count', 0),
|
||||||
|
lastfm_stat_album_count=playlist_dict.get('lastfm_stat_album_count', 0),
|
||||||
|
lastfm_stat_artist_count=playlist_dict.get('lastfm_stat_artist_count', 0),
|
||||||
|
|
||||||
|
lastfm_stat_percent=playlist_dict.get('lastfm_stat_percent', 0),
|
||||||
|
lastfm_stat_album_percent=playlist_dict.get('lastfm_stat_album_percent', 0),
|
||||||
|
lastfm_stat_artist_percent=playlist_dict.get('lastfm_stat_artist_percent', 0),
|
||||||
|
|
||||||
|
lastfm_stat_last_refresh=playlist_dict.get('lastfm_stat_last_refresh'),
|
||||||
|
|
||||||
|
chart_limit=playlist_dict.get('chart_limit'),
|
||||||
|
chart_range=FmNetwork.Range[playlist_dict.get('chart_range')])
|
||||||
|
|
||||||
|
|
||||||
def update_playlist(username: str, name: str, updates: dict) -> None:
|
def update_playlist(username: str, name: str, updates: dict) -> None:
|
||||||
if len(updates) > 0:
|
if len(updates) > 0:
|
||||||
|
@ -3,6 +3,8 @@ from enum import Enum
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from google.cloud.firestore import DocumentReference
|
from google.cloud.firestore import DocumentReference
|
||||||
|
|
||||||
|
from fmframework.net.network import Network
|
||||||
|
|
||||||
import music.db.database as database
|
import music.db.database as database
|
||||||
|
|
||||||
|
|
||||||
@ -73,6 +75,7 @@ class Playlist:
|
|||||||
return {
|
return {
|
||||||
'uri': self.uri,
|
'uri': self.uri,
|
||||||
'name': self.name,
|
'name': self.name,
|
||||||
|
'type': 'default',
|
||||||
|
|
||||||
'include_recommendations': self.include_recommendations,
|
'include_recommendations': self.include_recommendations,
|
||||||
'recommendation_sample': self.recommendation_sample,
|
'recommendation_sample': self.recommendation_sample,
|
||||||
@ -325,7 +328,8 @@ class RecentsPlaylist(Playlist):
|
|||||||
response.update({
|
response.update({
|
||||||
'add_last_month': self.add_last_month,
|
'add_last_month': self.add_last_month,
|
||||||
'add_this_month': self.add_this_month,
|
'add_this_month': self.add_this_month,
|
||||||
'day_boundary': self.day_boundary
|
'day_boundary': self.day_boundary,
|
||||||
|
'type': 'recents'
|
||||||
})
|
})
|
||||||
return response
|
return response
|
||||||
|
|
||||||
@ -355,3 +359,97 @@ class RecentsPlaylist(Playlist):
|
|||||||
def day_boundary(self, value):
|
def day_boundary(self, value):
|
||||||
database.update_playlist(self.username, self.name, {'day_boundary': value})
|
database.update_playlist(self.username, self.name, {'day_boundary': value})
|
||||||
self._day_boundary = value
|
self._day_boundary = value
|
||||||
|
|
||||||
|
|
||||||
|
class LastFMChartPlaylist(Playlist):
|
||||||
|
def __init__(self,
|
||||||
|
uri: str,
|
||||||
|
name: str,
|
||||||
|
username: str,
|
||||||
|
|
||||||
|
chart_range: Network.Range,
|
||||||
|
|
||||||
|
db_ref: DocumentReference,
|
||||||
|
|
||||||
|
|
||||||
|
include_recommendations: bool,
|
||||||
|
recommendation_sample: int,
|
||||||
|
include_library_tracks: bool,
|
||||||
|
|
||||||
|
parts: List[str],
|
||||||
|
playlist_references: List[DocumentReference],
|
||||||
|
shuffle: bool,
|
||||||
|
|
||||||
|
chart_limit: int = 50,
|
||||||
|
|
||||||
|
sort: Sort = None,
|
||||||
|
|
||||||
|
description_overwrite: str = None,
|
||||||
|
description_suffix: str = None,
|
||||||
|
|
||||||
|
lastfm_stat_count: int = None,
|
||||||
|
lastfm_stat_album_count: int = None,
|
||||||
|
lastfm_stat_artist_count: int = None,
|
||||||
|
|
||||||
|
lastfm_stat_percent: int = None,
|
||||||
|
lastfm_stat_album_percent: int = None,
|
||||||
|
lastfm_stat_artist_percent: int = None,
|
||||||
|
|
||||||
|
lastfm_stat_last_refresh: datetime = None):
|
||||||
|
super().__init__(uri=uri,
|
||||||
|
name=name,
|
||||||
|
username=username,
|
||||||
|
|
||||||
|
db_ref=db_ref,
|
||||||
|
|
||||||
|
include_recommendations=include_recommendations,
|
||||||
|
recommendation_sample=recommendation_sample,
|
||||||
|
include_library_tracks=include_library_tracks,
|
||||||
|
|
||||||
|
parts=parts,
|
||||||
|
playlist_references=playlist_references,
|
||||||
|
shuffle=shuffle,
|
||||||
|
|
||||||
|
sort=sort,
|
||||||
|
|
||||||
|
description_overwrite=description_overwrite,
|
||||||
|
description_suffix=description_suffix,
|
||||||
|
|
||||||
|
lastfm_stat_count=lastfm_stat_count,
|
||||||
|
lastfm_stat_album_count=lastfm_stat_album_count,
|
||||||
|
lastfm_stat_artist_count=lastfm_stat_artist_count,
|
||||||
|
|
||||||
|
lastfm_stat_percent=lastfm_stat_percent,
|
||||||
|
lastfm_stat_album_percent=lastfm_stat_album_percent,
|
||||||
|
lastfm_stat_artist_percent=lastfm_stat_artist_percent,
|
||||||
|
|
||||||
|
lastfm_stat_last_refresh=lastfm_stat_last_refresh)
|
||||||
|
self._chart_range = chart_range
|
||||||
|
self._chart_limit = chart_limit
|
||||||
|
|
||||||
|
def to_dict(self):
|
||||||
|
response = super().to_dict()
|
||||||
|
response.update({
|
||||||
|
'chart_limit': self.chart_limit,
|
||||||
|
'chart_range': self.chart_range.name,
|
||||||
|
'type': 'fmchart'
|
||||||
|
})
|
||||||
|
return response
|
||||||
|
|
||||||
|
@property
|
||||||
|
def chart_range(self):
|
||||||
|
return self._chart_range
|
||||||
|
|
||||||
|
@chart_range.setter
|
||||||
|
def chart_range(self, value):
|
||||||
|
database.update_playlist(self.username, self.name, {'chart_range': value.name})
|
||||||
|
self._chart_range = value
|
||||||
|
|
||||||
|
@property
|
||||||
|
def chart_limit(self):
|
||||||
|
return self._chart_limit
|
||||||
|
|
||||||
|
@chart_limit.setter
|
||||||
|
def chart_limit(self, value):
|
||||||
|
database.update_playlist(self.username, self.name, {'chart_limit': value})
|
||||||
|
self._chart_limit = value
|
||||||
|
@ -10,9 +10,11 @@ from spotframework.engine.processor.deduplicate import DeduplicateByID
|
|||||||
|
|
||||||
from spotframework.model.uri import Uri
|
from spotframework.model.uri import Uri
|
||||||
|
|
||||||
|
from spotfm.engine.chart_source import ChartSource
|
||||||
|
|
||||||
import music.db.database as database
|
import music.db.database as database
|
||||||
from music.db.part_generator import PartGenerator
|
from music.db.part_generator import PartGenerator
|
||||||
from music.model.playlist import RecentsPlaylist
|
from music.model.playlist import RecentsPlaylist, LastFMChartPlaylist
|
||||||
|
|
||||||
db = firestore.Client()
|
db = firestore.Client()
|
||||||
|
|
||||||
@ -34,20 +36,20 @@ def run_user_playlist(username, playlist_name):
|
|||||||
logger.critical(f'no playlist id to populate ({username}/{playlist_name})')
|
logger.critical(f'no playlist id to populate ({username}/{playlist_name})')
|
||||||
return None
|
return None
|
||||||
|
|
||||||
if len(playlist.parts) == 0 and len(playlist.playlist_references) == 0:
|
|
||||||
logger.critical(f'no playlists to use for creation ({username}/{playlist_name})')
|
|
||||||
return None
|
|
||||||
|
|
||||||
net = database.get_authed_spotify_network(username)
|
net = database.get_authed_spotify_network(username)
|
||||||
|
|
||||||
engine = PlaylistEngine(net)
|
engine = PlaylistEngine(net)
|
||||||
|
|
||||||
|
if isinstance(playlist, LastFMChartPlaylist) and user.lastfm_username is not None:
|
||||||
|
engine.sources.append(ChartSource(spotnet=net, fmnet=database.get_authed_lastfm_network(user.username)))
|
||||||
|
|
||||||
processors = [DeduplicateByID()]
|
processors = [DeduplicateByID()]
|
||||||
|
|
||||||
if playlist.shuffle is True:
|
if not isinstance(playlist, LastFMChartPlaylist):
|
||||||
processors.append(Shuffle())
|
if playlist.shuffle is True:
|
||||||
else:
|
processors.append(Shuffle())
|
||||||
processors.append(SortReleaseDate(reverse=True))
|
else:
|
||||||
|
processors.append(SortReleaseDate(reverse=True))
|
||||||
|
|
||||||
part_generator = PartGenerator(user=user)
|
part_generator = PartGenerator(user=user)
|
||||||
submit_parts = part_generator.get_recursive_parts(playlist.name)
|
submit_parts = part_generator.get_recursive_parts(playlist.name)
|
||||||
@ -62,6 +64,9 @@ def run_user_playlist(username, playlist_name):
|
|||||||
if playlist.include_library_tracks:
|
if playlist.include_library_tracks:
|
||||||
params.append(LibraryTrackSource.Params())
|
params.append(LibraryTrackSource.Params())
|
||||||
|
|
||||||
|
if isinstance(playlist, LastFMChartPlaylist):
|
||||||
|
params.append(ChartSource.Params(chart_range=playlist.chart_range, limit=playlist.chart_limit))
|
||||||
|
|
||||||
if isinstance(playlist, RecentsPlaylist):
|
if isinstance(playlist, RecentsPlaylist):
|
||||||
boundary_date = datetime.datetime.now(datetime.timezone.utc) - \
|
boundary_date = datetime.datetime.now(datetime.timezone.utc) - \
|
||||||
datetime.timedelta(days=int(playlist.day_boundary))
|
datetime.timedelta(days=int(playlist.day_boundary))
|
||||||
|
@ -45,6 +45,9 @@ class Edit extends Component{
|
|||||||
playlist_references: [],
|
playlist_references: [],
|
||||||
type: 'default',
|
type: 'default',
|
||||||
|
|
||||||
|
chart_limit: '',
|
||||||
|
chart_range: '',
|
||||||
|
|
||||||
day_boundary: '',
|
day_boundary: '',
|
||||||
recommendation_sample: '',
|
recommendation_sample: '',
|
||||||
newPlaylistName: '',
|
newPlaylistName: '',
|
||||||
@ -66,9 +69,15 @@ class Edit extends Component{
|
|||||||
this.handleRun = this.handleRun.bind(this);
|
this.handleRun = this.handleRun.bind(this);
|
||||||
|
|
||||||
this.handleShuffleChange = this.handleShuffleChange.bind(this);
|
this.handleShuffleChange = this.handleShuffleChange.bind(this);
|
||||||
|
|
||||||
|
this.handleIncludeLibraryTracksChange = this.handleIncludeLibraryTracksChange.bind(this);
|
||||||
|
|
||||||
this.handleIncludeRecommendationsChange = this.handleIncludeRecommendationsChange.bind(this);
|
this.handleIncludeRecommendationsChange = this.handleIncludeRecommendationsChange.bind(this);
|
||||||
this.handleThisMonthChange = this.handleThisMonthChange.bind(this);
|
this.handleThisMonthChange = this.handleThisMonthChange.bind(this);
|
||||||
this.handleLastMonthChange = this.handleLastMonthChange.bind(this);
|
this.handleLastMonthChange = this.handleLastMonthChange.bind(this);
|
||||||
|
|
||||||
|
this.handleChartLimitChange = this.handleChartLimitChange.bind(this);
|
||||||
|
this.handleChartRangeChange = this.handleChartRangeChange.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount(){
|
componentDidMount(){
|
||||||
@ -124,6 +133,12 @@ class Edit extends Component{
|
|||||||
if(event.target.name == 'type'){
|
if(event.target.name == 'type'){
|
||||||
this.handleTypeChange(event.target.value);
|
this.handleTypeChange(event.target.value);
|
||||||
}
|
}
|
||||||
|
if(event.target.name == 'chart_range'){
|
||||||
|
this.handleChartRangeChange(event.target.value);
|
||||||
|
}
|
||||||
|
if(event.target.name == 'chart_limit'){
|
||||||
|
this.handleChartLimitChange(event.target.value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleDayBoundaryChange(boundary) {
|
handleDayBoundaryChange(boundary) {
|
||||||
@ -213,6 +228,36 @@ class Edit extends Component{
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleIncludeLibraryTracksChange(event) {
|
||||||
|
this.setState({
|
||||||
|
include_library_tracks: event.target.checked
|
||||||
|
});
|
||||||
|
axios.post('/api/playlist', {
|
||||||
|
name: this.state.name,
|
||||||
|
include_library_tracks: event.target.checked
|
||||||
|
}).catch((error) => {
|
||||||
|
showMessage(`error updating library tracks (${error.response.status})`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
handleChartRangeChange(value) {
|
||||||
|
axios.post('/api/playlist', {
|
||||||
|
name: this.state.name,
|
||||||
|
chart_range: value
|
||||||
|
}).catch((error) => {
|
||||||
|
showMessage(`error updating chart range (${error.response.status})`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
handleChartLimitChange(value) {
|
||||||
|
axios.post('/api/playlist', {
|
||||||
|
name: this.state.name,
|
||||||
|
chart_limit: parseInt(value)
|
||||||
|
}).catch((error) => {
|
||||||
|
showMessage(`error updating limit (${error.response.status})`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
handleAddPart(event){
|
handleAddPart(event){
|
||||||
|
|
||||||
if(this.state.newPlaylistName.length != 0){
|
if(this.state.newPlaylistName.length != 0){
|
||||||
@ -325,26 +370,22 @@ class Edit extends Component{
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleRun(event){
|
handleRun(event){
|
||||||
if(this.state.playlist_references.length > 0 || this.state.parts.length > 0){
|
axios.get('/api/user')
|
||||||
axios.get('/api/user')
|
.then((response) => {
|
||||||
.then((response) => {
|
if(response.data.spotify_linked == true){
|
||||||
if(response.data.spotify_linked == true){
|
axios.get('/api/playlist/run', {params: {name: this.state.name}})
|
||||||
axios.get('/api/playlist/run', {params: {name: this.state.name}})
|
.then((reponse) => {
|
||||||
.then((reponse) => {
|
showMessage(`${this.state.name} ran`);
|
||||||
showMessage(`${this.state.name} ran`);
|
})
|
||||||
})
|
.catch((error) => {
|
||||||
.catch((error) => {
|
showMessage(`error running ${this.state.name} (${error.response.status})`);
|
||||||
showMessage(`error running ${this.state.name} (${error.response.status})`);
|
});
|
||||||
});
|
}else{
|
||||||
}else{
|
showMessage(`link spotify before running`);
|
||||||
showMessage(`link spotify before running`);
|
}
|
||||||
}
|
}).catch((error) => {
|
||||||
}).catch((error) => {
|
showMessage(`error running ${this.state.name} (${error.response.status})`);
|
||||||
showMessage(`error running ${this.state.name} (${error.response.status})`);
|
});
|
||||||
});
|
|
||||||
}else{
|
|
||||||
showMessage(`add either playlists or parts`);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render(){
|
render(){
|
||||||
@ -411,6 +452,16 @@ class Edit extends Component{
|
|||||||
onChange={this.handleIncludeRecommendationsChange}></input>
|
onChange={this.handleIncludeRecommendationsChange}></input>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td className="center-text ui-text text-no-select">
|
||||||
|
include library tracks?
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input type="checkbox"
|
||||||
|
checked={this.state.include_library_tracks}
|
||||||
|
onChange={this.handleIncludeLibraryTracksChange}></input>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td className="center-text ui-text text-no-select">
|
<td className="center-text ui-text text-no-select">
|
||||||
number of recommendations
|
number of recommendations
|
||||||
@ -423,6 +474,42 @@ class Edit extends Component{
|
|||||||
onChange={this.handleInputChange}></input>
|
onChange={this.handleInputChange}></input>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
{ this.state.type == 'fmchart' &&
|
||||||
|
<tr>
|
||||||
|
<td className="center-text ui-text text-no-select">
|
||||||
|
limit
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input type="number"
|
||||||
|
name="chart_limit"
|
||||||
|
className="full-width"
|
||||||
|
value={this.state.chart_limit}
|
||||||
|
onChange={this.handleInputChange}></input>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
}
|
||||||
|
{ this.state.type == 'fmchart' &&
|
||||||
|
<tr>
|
||||||
|
<td className="center-text ui-text text-no-select">
|
||||||
|
chart range
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<select className="full-width"
|
||||||
|
name="chart_range"
|
||||||
|
onChange={this.handleInputChange}
|
||||||
|
value={this.state.chart_range}>
|
||||||
|
<option value="WEEK">7 day</option>
|
||||||
|
<option value="MONTH">30 day</option>
|
||||||
|
<option value="QUARTER">90 day</option>
|
||||||
|
<option value="HALFYEAR">180 day</option>
|
||||||
|
<option value="YEAR">365 day</option>
|
||||||
|
<option value="OVERALL">overall</option>
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
}
|
||||||
|
|
||||||
{ this.state.type == 'recents' &&
|
{ this.state.type == 'recents' &&
|
||||||
<tr>
|
<tr>
|
||||||
<td className="center-text ui-text text-no-select">
|
<td className="center-text ui-text text-no-select">
|
||||||
@ -461,6 +548,8 @@ class Edit extends Component{
|
|||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td className="center-text ui-text text-no-select">
|
<td className="center-text ui-text text-no-select">
|
||||||
playlist type
|
playlist type
|
||||||
@ -472,6 +561,7 @@ class Edit extends Component{
|
|||||||
value={this.state.type}>
|
value={this.state.type}>
|
||||||
<option value="default">default</option>
|
<option value="default">default</option>
|
||||||
<option value="recents">recents</option>
|
<option value="recents">recents</option>
|
||||||
|
<option value="fmchart">last.fm chart</option>
|
||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
Loading…
Reference in New Issue
Block a user