added open in tag UI, added include_spotify_owned
This commit is contained in:
parent
79c841d9d8
commit
365cafe004
@ -54,6 +54,8 @@ class Playlist(Model):
|
|||||||
add_this_month = BooleanField(default=False)
|
add_this_month = BooleanField(default=False)
|
||||||
day_boundary = NumberField(default=21)
|
day_boundary = NumberField(default=21)
|
||||||
|
|
||||||
|
include_spotify_owned = BooleanField(default=True)
|
||||||
|
|
||||||
chart_range = TextField(default='MONTH')
|
chart_range = TextField(default='MONTH')
|
||||||
chart_limit = NumberField(default=50)
|
chart_limit = NumberField(default=50)
|
||||||
|
|
||||||
|
@ -89,3 +89,11 @@ class User(Model):
|
|||||||
return matches[0]
|
return matches[0]
|
||||||
else:
|
else:
|
||||||
return exact_match, matches
|
return exact_match, matches
|
||||||
|
|
||||||
|
def get_playlists(self):
|
||||||
|
"""Get all playlists for a user
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
List[Playlist]: List of users playlists
|
||||||
|
"""
|
||||||
|
return Playlist.collection.parent(self.key).fetch()
|
||||||
|
@ -77,7 +77,10 @@ def run_user_playlist(user: User, playlist: Playlist, spotnet: SpotNetwork = Non
|
|||||||
raise NameError(f'No Spotify network returned ({username} / {playlist_name})')
|
raise NameError(f'No Spotify network returned ({username} / {playlist_name})')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
user_playlists = [(i.name, i.uri) for i in spotnet.playlists()]
|
if not playlist.include_spotify_owned:
|
||||||
|
user_playlists = [(i.name, i.uri) for i in spotnet.playlists() if 'spotify' not in i.owner.display_name.lower()]
|
||||||
|
else:
|
||||||
|
user_playlists = [(i.name, i.uri) for i in spotnet.playlists()]
|
||||||
except SpotifyNetworkException as e:
|
except SpotifyNetworkException as e:
|
||||||
logger.exception(f'error occured while retrieving playlists {username} / {playlist_name}')
|
logger.exception(f'error occured while retrieving playlists {username} / {playlist_name}')
|
||||||
raise e
|
raise e
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import React, { Component } from "react";
|
import React, { Component } from "react";
|
||||||
const axios = require('axios');
|
const axios = require('axios');
|
||||||
|
|
||||||
import { Card, Button, CardActions, CardContent, FormControl, InputLabel, Select, Typography, Grid, TextField, MenuItem, FormControlLabel, Switch } from '@material-ui/core';
|
import { Card, Button, ButtonGroup, CardActions, CardContent, FormControl, InputLabel, Select, Typography, Grid, TextField, MenuItem, FormControlLabel, Switch } from '@material-ui/core';
|
||||||
import { Delete } from '@material-ui/icons';
|
import { Delete, ExitToApp } from '@material-ui/icons';
|
||||||
import { makeStyles } from '@material-ui/core/styles';
|
import { makeStyles } from '@material-ui/core/styles';
|
||||||
|
|
||||||
import showMessage from "../Toast.js";
|
import showMessage from "../Toast.js";
|
||||||
@ -28,6 +28,7 @@ class TagView extends Component{
|
|||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
tag_id: props.match.params.tag_id,
|
tag_id: props.match.params.tag_id,
|
||||||
|
username: null,
|
||||||
tag: {
|
tag: {
|
||||||
name: "",
|
name: "",
|
||||||
tracks: [],
|
tracks: [],
|
||||||
@ -44,6 +45,7 @@ class TagView extends Component{
|
|||||||
}
|
}
|
||||||
this.handleInputChange = this.handleInputChange.bind(this);
|
this.handleInputChange = this.handleInputChange.bind(this);
|
||||||
this.handleRun = this.handleRun.bind(this);
|
this.handleRun = this.handleRun.bind(this);
|
||||||
|
this.handleView = this.handleView.bind(this);
|
||||||
this.handleRemoveObj = this.handleRemoveObj.bind(this);
|
this.handleRemoveObj = this.handleRemoveObj.bind(this);
|
||||||
|
|
||||||
this.handleCheckChange = this.handleCheckChange.bind(this);
|
this.handleCheckChange = this.handleCheckChange.bind(this);
|
||||||
@ -58,6 +60,7 @@ class TagView extends Component{
|
|||||||
*/
|
*/
|
||||||
componentDidMount(){
|
componentDidMount(){
|
||||||
this.getTag();
|
this.getTag();
|
||||||
|
this.getUserInfo();
|
||||||
// var intervalId = setInterval(() => {this.getTag(false)}, 5000);
|
// var intervalId = setInterval(() => {this.getTag(false)}, 5000);
|
||||||
// var timeoutId = setTimeout(() => {clearInterval(this.state.intervalId)}, 300000);
|
// var timeoutId = setTimeout(() => {clearInterval(this.state.intervalId)}, 300000);
|
||||||
|
|
||||||
@ -72,6 +75,26 @@ class TagView extends Component{
|
|||||||
// clearTimeout(this.state.timeoutId);
|
// clearTimeout(this.state.timeoutId);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get user info from API
|
||||||
|
*/
|
||||||
|
getUserInfo(){
|
||||||
|
this.userInfoCancelToken = axios.CancelToken.source();
|
||||||
|
|
||||||
|
var self = this;
|
||||||
|
axios.get('/api/user', {
|
||||||
|
cancelToken: this.userInfoCancelToken.token
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
self.setState({
|
||||||
|
username: response.data.lastfm_username
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
showMessage(`error getting user info (${error.response.status})`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get tag info from API
|
* Get tag info from API
|
||||||
* @param {*} error_toast Whether to show toast on network error
|
* @param {*} error_toast Whether to show toast on network error
|
||||||
@ -173,6 +196,30 @@ class TagView extends Component{
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open a tag element in Last.fm
|
||||||
|
* @param {*} music_obj Tag element to be viewed
|
||||||
|
* @param {*} addType Tag type, artist, album etc
|
||||||
|
* @param {*} event
|
||||||
|
*/
|
||||||
|
handleView(music_obj, addType, event){
|
||||||
|
let url = `https://last.fm/user/${this.state.username}/library/music/`;
|
||||||
|
|
||||||
|
switch(addType) {
|
||||||
|
case "artists":
|
||||||
|
url = url + encodeURI(music_obj.name);
|
||||||
|
break;
|
||||||
|
case "albums":
|
||||||
|
url = `${url}${encodeURI(music_obj.artist)}/${encodeURI(music_obj.name)}`;
|
||||||
|
break;
|
||||||
|
case "tracks":
|
||||||
|
url = `${url}${encodeURI(music_obj.artist)}/_/${encodeURI(music_obj.name)}`;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.open(url);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle remove watched part
|
* Handle remove watched part
|
||||||
* @param {*} music_obj Subject object to remove
|
* @param {*} music_obj Subject object to remove
|
||||||
@ -334,17 +381,17 @@ class TagView extends Component{
|
|||||||
{/* ARTISTS TITLE */}
|
{/* ARTISTS TITLE */}
|
||||||
{ this.state.tag.artists.length > 0 && <Grid item xs={12} ><Typography color="textSecondary" variant="h4">Artists</Typography></Grid> }
|
{ this.state.tag.artists.length > 0 && <Grid item xs={12} ><Typography color="textSecondary" variant="h4">Artists</Typography></Grid> }
|
||||||
{/* ARTIST CARDS */}
|
{/* ARTIST CARDS */}
|
||||||
{ this.state.tag.artists.length > 0 && <ListBlock handler={this.handleRemoveObj} list={this.state.tag.artists} addType="artists" showTime={this.state.tag.time_objects}/> }
|
{ this.state.tag.artists.length > 0 && <ListBlock viewHandler={this.handleView} deleteHandler={this.handleRemoveObj} list={this.state.tag.artists} addType="artists" showTime={this.state.tag.time_objects}/> }
|
||||||
|
|
||||||
{/* ALBUMS TITLE */}
|
{/* ALBUMS TITLE */}
|
||||||
{ this.state.tag.albums.length > 0 && <Grid item xs={12} ><Typography color="textSecondary" variant="h4">Albums</Typography></Grid> }
|
{ this.state.tag.albums.length > 0 && <Grid item xs={12} ><Typography color="textSecondary" variant="h4">Albums</Typography></Grid> }
|
||||||
{/* ALBUM CARDS */}
|
{/* ALBUM CARDS */}
|
||||||
{ this.state.tag.albums.length > 0 && <ListBlock handler={this.handleRemoveObj} list={this.state.tag.albums} addType="albums" showTime={this.state.tag.time_objects}/> }
|
{ this.state.tag.albums.length > 0 && <ListBlock viewHandler={this.handleView} deleteHandler={this.handleRemoveObj} list={this.state.tag.albums} addType="albums" showTime={this.state.tag.time_objects}/> }
|
||||||
|
|
||||||
{/* TRACKS TITLE */}
|
{/* TRACKS TITLE */}
|
||||||
{ this.state.tag.tracks.length > 0 && <Grid item xs={12} ><Typography color="textSecondary" variant="h4">Tracks</Typography></Grid> }
|
{ this.state.tag.tracks.length > 0 && <Grid item xs={12} ><Typography color="textSecondary" variant="h4">Tracks</Typography></Grid> }
|
||||||
{/* TRACK CARDS */}
|
{/* TRACK CARDS */}
|
||||||
{ this.state.tag.tracks.length > 0 && <ListBlock handler={this.handleRemoveObj} list={this.state.tag.tracks} addType="tracks" showTime={this.state.tag.time_objects}/> }
|
{ this.state.tag.tracks.length > 0 && <ListBlock viewHandler={this.handleView} deleteHandler={this.handleRemoveObj} list={this.state.tag.tracks} addType="tracks" showTime={this.state.tag.time_objects}/> }
|
||||||
|
|
||||||
{/* NAME TEXTBOX */}
|
{/* NAME TEXTBOX */}
|
||||||
<Grid item xs={12} sm={this.state.addType != 'artists' ? 3 : 4} md={this.state.addType != 'artists' ? 3 : 4}>
|
<Grid item xs={12} sm={this.state.addType != 'artists' ? 3 : 4} md={this.state.addType != 'artists' ? 3 : 4}>
|
||||||
@ -458,7 +505,7 @@ function ListBlock(props) {
|
|||||||
alignItems="flex-start"
|
alignItems="flex-start"
|
||||||
style={{padding: '24px'}}>
|
style={{padding: '24px'}}>
|
||||||
{props.list.map((music_obj) => <BlockGridItem music_obj={ music_obj } key={ music_obj.name }
|
{props.list.map((music_obj) => <BlockGridItem music_obj={ music_obj } key={ music_obj.name }
|
||||||
handler={ props.handler } addType={ props.addType } showTime={ props.showTime }/>)}
|
deleteHandler={ props.deleteHandler } viewHandler={ props.viewHandler } addType={ props.addType } showTime={ props.showTime }/>)}
|
||||||
</Grid>
|
</Grid>
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -504,9 +551,14 @@ function BlockGridItem (props) {
|
|||||||
|
|
||||||
{/* DELETE BUTTON */}
|
{/* DELETE BUTTON */}
|
||||||
<CardActions>
|
<CardActions>
|
||||||
<Button className="full-width" color="secondary" variant="contained" aria-label="delete" onClick={(e) => props.handler(props.music_obj, props.addType, e)} startIcon={<Delete />}>
|
<ButtonGroup className="full-width" orientation="vertical" color="secondary" variant="contained">
|
||||||
Delete
|
<Button className="full-width" aria-label="goto" onClick={(e) => props.viewHandler(props.music_obj, props.addType, e)} startIcon={<ExitToApp />}>
|
||||||
</Button>
|
View
|
||||||
|
</Button>
|
||||||
|
<Button className="full-width" aria-label="delete" onClick={(e) => props.deleteHandler(props.music_obj, props.addType, e)} startIcon={<Delete />}>
|
||||||
|
Delete
|
||||||
|
</Button>
|
||||||
|
</ButtonGroup>
|
||||||
</CardActions>
|
</CardActions>
|
||||||
</Card>
|
</Card>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
Loading…
Reference in New Issue
Block a user