From 365cafe004f0c8d5fae85cda183e0d51735a1e84 Mon Sep 17 00:00:00 2001 From: andy Date: Sat, 10 Jul 2021 16:00:30 +0100 Subject: [PATCH] added open in tag UI, added include_spotify_owned --- music/model/playlist.py | 2 + music/model/user.py | 8 ++++ music/tasks/run_user_playlist.py | 5 ++- src/js/Tag/View.js | 70 ++++++++++++++++++++++++++++---- 4 files changed, 75 insertions(+), 10 deletions(-) diff --git a/music/model/playlist.py b/music/model/playlist.py index 45dcf99..88e2823 100644 --- a/music/model/playlist.py +++ b/music/model/playlist.py @@ -54,6 +54,8 @@ class Playlist(Model): add_this_month = BooleanField(default=False) day_boundary = NumberField(default=21) + include_spotify_owned = BooleanField(default=True) + chart_range = TextField(default='MONTH') chart_limit = NumberField(default=50) diff --git a/music/model/user.py b/music/model/user.py index 84b1c65..1272727 100644 --- a/music/model/user.py +++ b/music/model/user.py @@ -89,3 +89,11 @@ class User(Model): return matches[0] else: 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() diff --git a/music/tasks/run_user_playlist.py b/music/tasks/run_user_playlist.py index 9b48e7a..8b3ed83 100644 --- a/music/tasks/run_user_playlist.py +++ b/music/tasks/run_user_playlist.py @@ -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})') 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: logger.exception(f'error occured while retrieving playlists {username} / {playlist_name}') raise e diff --git a/src/js/Tag/View.js b/src/js/Tag/View.js index bc6bc09..4ac4139 100644 --- a/src/js/Tag/View.js +++ b/src/js/Tag/View.js @@ -1,8 +1,8 @@ import React, { Component } from "react"; const axios = require('axios'); -import { Card, Button, CardActions, CardContent, FormControl, InputLabel, Select, Typography, Grid, TextField, MenuItem, FormControlLabel, Switch } from '@material-ui/core'; -import { Delete } from '@material-ui/icons'; +import { Card, Button, ButtonGroup, CardActions, CardContent, FormControl, InputLabel, Select, Typography, Grid, TextField, MenuItem, FormControlLabel, Switch } from '@material-ui/core'; +import { Delete, ExitToApp } from '@material-ui/icons'; import { makeStyles } from '@material-ui/core/styles'; import showMessage from "../Toast.js"; @@ -28,6 +28,7 @@ class TagView extends Component{ super(props); this.state = { tag_id: props.match.params.tag_id, + username: null, tag: { name: "", tracks: [], @@ -44,6 +45,7 @@ class TagView extends Component{ } this.handleInputChange = this.handleInputChange.bind(this); this.handleRun = this.handleRun.bind(this); + this.handleView = this.handleView.bind(this); this.handleRemoveObj = this.handleRemoveObj.bind(this); this.handleCheckChange = this.handleCheckChange.bind(this); @@ -58,6 +60,7 @@ class TagView extends Component{ */ componentDidMount(){ this.getTag(); + this.getUserInfo(); // var intervalId = setInterval(() => {this.getTag(false)}, 5000); // var timeoutId = setTimeout(() => {clearInterval(this.state.intervalId)}, 300000); @@ -72,6 +75,26 @@ class TagView extends Component{ // 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 * @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 * @param {*} music_obj Subject object to remove @@ -334,17 +381,17 @@ class TagView extends Component{ {/* ARTISTS TITLE */} { this.state.tag.artists.length > 0 && Artists } {/* ARTIST CARDS */} - { this.state.tag.artists.length > 0 && } + { this.state.tag.artists.length > 0 && } {/* ALBUMS TITLE */} { this.state.tag.albums.length > 0 && Albums } {/* ALBUM CARDS */} - { this.state.tag.albums.length > 0 && } + { this.state.tag.albums.length > 0 && } {/* TRACKS TITLE */} { this.state.tag.tracks.length > 0 && Tracks } {/* TRACK CARDS */} - { this.state.tag.tracks.length > 0 && } + { this.state.tag.tracks.length > 0 && } {/* NAME TEXTBOX */} @@ -458,7 +505,7 @@ function ListBlock(props) { alignItems="flex-start" style={{padding: '24px'}}> {props.list.map((music_obj) => )} + deleteHandler={ props.deleteHandler } viewHandler={ props.viewHandler } addType={ props.addType } showTime={ props.showTime }/>)} } @@ -504,9 +551,14 @@ function BlockGridItem (props) { {/* DELETE BUTTON */} - + + + +