spotify-cmd 0.1.2__tar.gz → 0.1.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. {spotify-cmd-0.1.2/spotify_cmd.egg-info → spotify-cmd-0.1.4}/PKG-INFO +6 -5
  2. {spotify-cmd-0.1.2 → spotify-cmd-0.1.4}/README.md +4 -3
  3. {spotify-cmd-0.1.2 → spotify-cmd-0.1.4}/setup.py +2 -2
  4. {spotify-cmd-0.1.2 → spotify-cmd-0.1.4/spotify_cmd.egg-info}/PKG-INFO +6 -5
  5. {spotify-cmd-0.1.2 → spotify-cmd-0.1.4}/spotify_cmd.egg-info/SOURCES.txt +10 -0
  6. {spotify-cmd-0.1.2 → spotify-cmd-0.1.4}/spotify_cmd.egg-info/requires.txt +1 -1
  7. {spotify-cmd-0.1.2 → spotify-cmd-0.1.4}/src/spotify_cmd_client/client.py +2 -30
  8. spotify-cmd-0.1.4/src/spotify_cmd_client/data_presenter.py +59 -0
  9. {spotify-cmd-0.1.2 → spotify-cmd-0.1.4}/src/spotify_cmd_client/main.py +12 -2
  10. {spotify-cmd-0.1.2 → spotify-cmd-0.1.4}/src/spotify_cmd_daemon/main.py +2 -2
  11. {spotify-cmd-0.1.2 → spotify-cmd-0.1.4}/src/spotify_cmd_daemon/operations/__init__.py +1 -0
  12. spotify-cmd-0.1.4/src/spotify_cmd_daemon/operations/get_library_albums.py +18 -0
  13. spotify-cmd-0.1.4/src/spotify_cmd_daemon/operations/get_library_playlists.py +16 -0
  14. spotify-cmd-0.1.4/src/spotify_cmd_daemon/operations/presenters/__init__.py +7 -0
  15. spotify-cmd-0.1.4/src/spotify_cmd_daemon/operations/presenters/albums_presenter.py +14 -0
  16. spotify-cmd-0.1.4/src/spotify_cmd_daemon/operations/presenters/artists_presenter.py +14 -0
  17. spotify-cmd-0.1.4/src/spotify_cmd_daemon/operations/presenters/collection_presenter.py +12 -0
  18. spotify-cmd-0.1.4/src/spotify_cmd_daemon/operations/presenters/episodes_presenter.py +14 -0
  19. spotify-cmd-0.1.4/src/spotify_cmd_daemon/operations/presenters/playlists_presenter.py +14 -0
  20. spotify-cmd-0.1.4/src/spotify_cmd_daemon/operations/presenters/shows_presenter.py +14 -0
  21. spotify-cmd-0.1.4/src/spotify_cmd_daemon/operations/presenters/tracks_presenter.py +14 -0
  22. spotify-cmd-0.1.4/src/spotify_cmd_daemon/operations/search.py +22 -0
  23. {spotify-cmd-0.1.2 → spotify-cmd-0.1.4}/src/spotify_cmd_daemon/spotify_controller.py +9 -0
  24. spotify-cmd-0.1.2/src/spotify_cmd_daemon/operations/get_library_albums.py +0 -22
  25. spotify-cmd-0.1.2/src/spotify_cmd_daemon/operations/get_library_playlists.py +0 -21
  26. {spotify-cmd-0.1.2 → spotify-cmd-0.1.4}/LICENSE.md +0 -0
  27. {spotify-cmd-0.1.2 → spotify-cmd-0.1.4}/setup.cfg +0 -0
  28. {spotify-cmd-0.1.2 → spotify-cmd-0.1.4}/spotify_cmd.egg-info/dependency_links.txt +0 -0
  29. {spotify-cmd-0.1.2 → spotify-cmd-0.1.4}/spotify_cmd.egg-info/entry_points.txt +0 -0
  30. {spotify-cmd-0.1.2 → spotify-cmd-0.1.4}/spotify_cmd.egg-info/top_level.txt +0 -0
  31. {spotify-cmd-0.1.2 → spotify-cmd-0.1.4}/src/__init__.py +0 -0
  32. {spotify-cmd-0.1.2 → spotify-cmd-0.1.4}/src/common/__init__.py +0 -0
  33. {spotify-cmd-0.1.2 → spotify-cmd-0.1.4}/src/common/config.py +0 -0
  34. {spotify-cmd-0.1.2 → spotify-cmd-0.1.4}/src/common/socket_data_handler.py +0 -0
  35. {spotify-cmd-0.1.2 → spotify-cmd-0.1.4}/src/common/socket_message.py +0 -0
  36. {spotify-cmd-0.1.2 → spotify-cmd-0.1.4}/src/spotify_cmd_client/__init__.py +0 -0
  37. {spotify-cmd-0.1.2 → spotify-cmd-0.1.4}/src/spotify_cmd_daemon/__init__.py +0 -0
  38. {spotify-cmd-0.1.2 → spotify-cmd-0.1.4}/src/spotify_cmd_daemon/operations/helpers/__init__.py +0 -0
  39. {spotify-cmd-0.1.2 → spotify-cmd-0.1.4}/src/spotify_cmd_daemon/operations/helpers/check_resource_existence.py +0 -0
  40. {spotify-cmd-0.1.2 → spotify-cmd-0.1.4}/src/spotify_cmd_daemon/operations/helpers/get_album.py +0 -0
  41. {spotify-cmd-0.1.2 → spotify-cmd-0.1.4}/src/spotify_cmd_daemon/operations/helpers/get_playlist.py +0 -0
  42. {spotify-cmd-0.1.2 → spotify-cmd-0.1.4}/src/spotify_cmd_daemon/operations/helpers/get_resource_from_library.py +0 -0
  43. {spotify-cmd-0.1.2 → spotify-cmd-0.1.4}/src/spotify_cmd_daemon/operations/helpers/get_resource_uri.py +0 -0
  44. {spotify-cmd-0.1.2 → spotify-cmd-0.1.4}/src/spotify_cmd_daemon/operations/next_track.py +0 -0
  45. {spotify-cmd-0.1.2 → spotify-cmd-0.1.4}/src/spotify_cmd_daemon/operations/pause_playback.py +0 -0
  46. {spotify-cmd-0.1.2 → spotify-cmd-0.1.4}/src/spotify_cmd_daemon/operations/previous_track.py +0 -0
  47. {spotify-cmd-0.1.2 → spotify-cmd-0.1.4}/src/spotify_cmd_daemon/operations/resume_playback.py +0 -0
  48. {spotify-cmd-0.1.2 → spotify-cmd-0.1.4}/src/spotify_cmd_daemon/operations/set_shuffle.py +0 -0
  49. {spotify-cmd-0.1.2 → spotify-cmd-0.1.4}/src/spotify_cmd_daemon/operations/set_volume.py +0 -0
  50. {spotify-cmd-0.1.2 → spotify-cmd-0.1.4}/src/spotify_cmd_daemon/operations/start_playback.py +0 -0
  51. {spotify-cmd-0.1.2 → spotify-cmd-0.1.4}/src/spotify_cmd_daemon/operations/validators/__init__.py +0 -0
  52. {spotify-cmd-0.1.2 → spotify-cmd-0.1.4}/src/spotify_cmd_daemon/operations/validators/validate_resource_uri.py +0 -0
  53. {spotify-cmd-0.1.2 → spotify-cmd-0.1.4}/src/spotify_cmd_daemon/operations/validators/validate_volume_percent.py +0 -0
  54. {spotify-cmd-0.1.2 → spotify-cmd-0.1.4}/src/spotify_cmd_daemon/socket_server.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: spotify-cmd
3
- Version: 0.1.2
3
+ Version: 0.1.4
4
4
  Summary: Command line Spotify client
5
5
  Home-page: https://github.com/ciembor/spotify-cmd
6
6
  Author: Maciej Ciemborowicz
@@ -25,11 +25,11 @@ License-File: LICENSE.md
25
25
  Requires-Dist: argparse==1.4.0
26
26
  Requires-Dist: configparser==5.0.2
27
27
  Requires-Dist: spotipy==2.23.0
28
- Requires-Dist: daemon==1.2
28
+ Requires-Dist: python-daemon==3.0.1
29
29
 
30
- # 💚 spotify-cmd v0.1.2
30
+ # 💚 spotify-cmd v0.1.3
31
31
 
32
- `spotify-cmd` is a Spotify client that allows controlling the playback of albums and playlists from a *user's library* (based on names or Spotify URIs) and individual tracks (based solely on Spotify URIs). The application is intended for use with [spotifyd](https://github.com/Spotifyd/spotifyd), but it works with any Spotify-enabled device.
32
+ `spotify-cmd` is a Spotify client that allows controlling the playback of **albums and playlists from a user's library** (based on names or Spotify URIs) and individual tracks (based solely on Spotify URIs). The application is intended for use with [spotifyd](https://github.com/Spotifyd/spotifyd), but it works with any Spotify-enabled device.
33
33
 
34
34
  ## Installation
35
35
 
@@ -71,6 +71,7 @@ socket_buffer_size = 1024
71
71
  * `play`, `pause`, `next`, `previous`: Controls playback.
72
72
  * `set shuffle <on|off>`: Toggles shuffle mode.
73
73
  * `set volume <0-100>`: Sets the volume level.
74
+ * `find <search_type> <query>`: Searches for items on Spotify. Acceptable search types are `album`, `artist`, `playlist`, `track`, `episode`, and `show`.
74
75
 
75
76
  ## Output Format
76
77
 
@@ -99,7 +100,7 @@ Developers can create interfaces for `spotify-cmd-daemon` using `/tmp/spotify-cm
99
100
  * Displaying tracks from specific albums or playlists.
100
101
  * MPRIS D-Bus interface support to reduce server queries.
101
102
  * `spotify-cmd-ui`: A ncurses-based UI for track display and control, working with the same daemon.
102
- * Search functionality.
103
+ * ~~Search functionality.~~ [Done in 0.1.4]
103
104
  * Support for other resource types like artists.
104
105
 
105
106
  ## License
@@ -1,6 +1,6 @@
1
- # 💚 spotify-cmd v0.1.2
1
+ # 💚 spotify-cmd v0.1.3
2
2
 
3
- `spotify-cmd` is a Spotify client that allows controlling the playback of albums and playlists from a *user's library* (based on names or Spotify URIs) and individual tracks (based solely on Spotify URIs). The application is intended for use with [spotifyd](https://github.com/Spotifyd/spotifyd), but it works with any Spotify-enabled device.
3
+ `spotify-cmd` is a Spotify client that allows controlling the playback of **albums and playlists from a user's library** (based on names or Spotify URIs) and individual tracks (based solely on Spotify URIs). The application is intended for use with [spotifyd](https://github.com/Spotifyd/spotifyd), but it works with any Spotify-enabled device.
4
4
 
5
5
  ## Installation
6
6
 
@@ -42,6 +42,7 @@ socket_buffer_size = 1024
42
42
  * `play`, `pause`, `next`, `previous`: Controls playback.
43
43
  * `set shuffle <on|off>`: Toggles shuffle mode.
44
44
  * `set volume <0-100>`: Sets the volume level.
45
+ * `find <search_type> <query>`: Searches for items on Spotify. Acceptable search types are `album`, `artist`, `playlist`, `track`, `episode`, and `show`.
45
46
 
46
47
  ## Output Format
47
48
 
@@ -70,7 +71,7 @@ Developers can create interfaces for `spotify-cmd-daemon` using `/tmp/spotify-cm
70
71
  * Displaying tracks from specific albums or playlists.
71
72
  * MPRIS D-Bus interface support to reduce server queries.
72
73
  * `spotify-cmd-ui`: A ncurses-based UI for track display and control, working with the same daemon.
73
- * Search functionality.
74
+ * ~~Search functionality.~~ [Done in 0.1.4]
74
75
  * Support for other resource types like artists.
75
76
 
76
77
  ## License
@@ -6,13 +6,13 @@ with open("README.md", "r", encoding="utf-8") as fh:
6
6
 
7
7
  setup(
8
8
  name="spotify-cmd",
9
- version="0.1.2",
9
+ version="0.1.4",
10
10
  packages=find_packages(),
11
11
  install_requires=[
12
12
  'argparse==1.4.0',
13
13
  'configparser==5.0.2',
14
14
  'spotipy==2.23.0',
15
- 'daemon==1.2'
15
+ 'python-daemon==3.0.1'
16
16
  ],
17
17
  entry_points={
18
18
  'console_scripts': [
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: spotify-cmd
3
- Version: 0.1.2
3
+ Version: 0.1.4
4
4
  Summary: Command line Spotify client
5
5
  Home-page: https://github.com/ciembor/spotify-cmd
6
6
  Author: Maciej Ciemborowicz
@@ -25,11 +25,11 @@ License-File: LICENSE.md
25
25
  Requires-Dist: argparse==1.4.0
26
26
  Requires-Dist: configparser==5.0.2
27
27
  Requires-Dist: spotipy==2.23.0
28
- Requires-Dist: daemon==1.2
28
+ Requires-Dist: python-daemon==3.0.1
29
29
 
30
- # 💚 spotify-cmd v0.1.2
30
+ # 💚 spotify-cmd v0.1.3
31
31
 
32
- `spotify-cmd` is a Spotify client that allows controlling the playback of albums and playlists from a *user's library* (based on names or Spotify URIs) and individual tracks (based solely on Spotify URIs). The application is intended for use with [spotifyd](https://github.com/Spotifyd/spotifyd), but it works with any Spotify-enabled device.
32
+ `spotify-cmd` is a Spotify client that allows controlling the playback of **albums and playlists from a user's library** (based on names or Spotify URIs) and individual tracks (based solely on Spotify URIs). The application is intended for use with [spotifyd](https://github.com/Spotifyd/spotifyd), but it works with any Spotify-enabled device.
33
33
 
34
34
  ## Installation
35
35
 
@@ -71,6 +71,7 @@ socket_buffer_size = 1024
71
71
  * `play`, `pause`, `next`, `previous`: Controls playback.
72
72
  * `set shuffle <on|off>`: Toggles shuffle mode.
73
73
  * `set volume <0-100>`: Sets the volume level.
74
+ * `find <search_type> <query>`: Searches for items on Spotify. Acceptable search types are `album`, `artist`, `playlist`, `track`, `episode`, and `show`.
74
75
 
75
76
  ## Output Format
76
77
 
@@ -99,7 +100,7 @@ Developers can create interfaces for `spotify-cmd-daemon` using `/tmp/spotify-cm
99
100
  * Displaying tracks from specific albums or playlists.
100
101
  * MPRIS D-Bus interface support to reduce server queries.
101
102
  * `spotify-cmd-ui`: A ncurses-based UI for track display and control, working with the same daemon.
102
- * Search functionality.
103
+ * ~~Search functionality.~~ [Done in 0.1.4]
103
104
  * Support for other resource types like artists.
104
105
 
105
106
  ## License
@@ -14,6 +14,7 @@ src/common/socket_data_handler.py
14
14
  src/common/socket_message.py
15
15
  src/spotify_cmd_client/__init__.py
16
16
  src/spotify_cmd_client/client.py
17
+ src/spotify_cmd_client/data_presenter.py
17
18
  src/spotify_cmd_client/main.py
18
19
  src/spotify_cmd_daemon/__init__.py
19
20
  src/spotify_cmd_daemon/main.py
@@ -26,6 +27,7 @@ src/spotify_cmd_daemon/operations/next_track.py
26
27
  src/spotify_cmd_daemon/operations/pause_playback.py
27
28
  src/spotify_cmd_daemon/operations/previous_track.py
28
29
  src/spotify_cmd_daemon/operations/resume_playback.py
30
+ src/spotify_cmd_daemon/operations/search.py
29
31
  src/spotify_cmd_daemon/operations/set_shuffle.py
30
32
  src/spotify_cmd_daemon/operations/set_volume.py
31
33
  src/spotify_cmd_daemon/operations/start_playback.py
@@ -35,6 +37,14 @@ src/spotify_cmd_daemon/operations/helpers/get_album.py
35
37
  src/spotify_cmd_daemon/operations/helpers/get_playlist.py
36
38
  src/spotify_cmd_daemon/operations/helpers/get_resource_from_library.py
37
39
  src/spotify_cmd_daemon/operations/helpers/get_resource_uri.py
40
+ src/spotify_cmd_daemon/operations/presenters/__init__.py
41
+ src/spotify_cmd_daemon/operations/presenters/albums_presenter.py
42
+ src/spotify_cmd_daemon/operations/presenters/artists_presenter.py
43
+ src/spotify_cmd_daemon/operations/presenters/collection_presenter.py
44
+ src/spotify_cmd_daemon/operations/presenters/episodes_presenter.py
45
+ src/spotify_cmd_daemon/operations/presenters/playlists_presenter.py
46
+ src/spotify_cmd_daemon/operations/presenters/shows_presenter.py
47
+ src/spotify_cmd_daemon/operations/presenters/tracks_presenter.py
38
48
  src/spotify_cmd_daemon/operations/validators/__init__.py
39
49
  src/spotify_cmd_daemon/operations/validators/validate_resource_uri.py
40
50
  src/spotify_cmd_daemon/operations/validators/validate_volume_percent.py
@@ -1,4 +1,4 @@
1
1
  argparse==1.4.0
2
2
  configparser==5.0.2
3
3
  spotipy==2.23.0
4
- daemon==1.2
4
+ python-daemon==3.0.1
@@ -9,6 +9,7 @@ import json
9
9
  from socket_message import SocketMessage
10
10
  from socket_data_handler import SocketDataHandler
11
11
  from config import Config
12
+ from .data_presenter import DataPresenter
12
13
 
13
14
  class Client:
14
15
  def __init__(self):
@@ -43,38 +44,9 @@ class Client:
43
44
  formatted_response = json.dumps(response_dict['payload'], indent=2)
44
45
  print(formatted_response)
45
46
  else:
46
- self.__print_output(response_dict['payload'])
47
+ DataPresenter.print_output(response_dict['payload'])
47
48
  except socket.error as msg:
48
49
  print(f"Error receiving response from daemon: {msg}")
49
50
 
50
51
  def close(self):
51
52
  self.sock.close()
52
-
53
- def __print_output(self, data):
54
- if 'error' in data:
55
- print(f"Error: {data['error']}")
56
- elif 'notification' in data:
57
- print(data['notification'])
58
- elif 'albums' in data:
59
- self.__print_collection('albums', data['albums'])
60
- elif 'playlists' in data:
61
- self.__print_collection('playlists', data['playlists'])
62
-
63
- def __print_collection(self, type, items):
64
- print("──────────────────────────────────────────")
65
- for item in items:
66
- if (type=='albums'):
67
- self.__print_album(item)
68
- elif (type=='playlists'):
69
- self.__print_playlist(item)
70
- print("──────────────────────────────────────────")
71
-
72
- def __print_album(self, album_data):
73
- print(f"Artist: {album_data['artists']}")
74
- print(f"Album: {album_data['name']}")
75
- print(f"URI: spotify:album:{album_data['spotify_id']}")
76
-
77
- def __print_playlist(self, playlist_data):
78
- print(f"Owner: {playlist_data['owner']}")
79
- print(f"Name: {playlist_data['name']}")
80
- print(f"URI: spotify:playlist:{playlist_data['spotify_id']}")
@@ -0,0 +1,59 @@
1
+ class DataPresenter:
2
+ PRINT_TEMPLATES = {
3
+ 'albums': [
4
+ ('Artist', 'artists'),
5
+ ('Album', 'name'),
6
+ ('URI', lambda d: f"spotify:album:{d['spotify_id']}")
7
+ ],
8
+ 'artists': [
9
+ ('Artist', 'name'),
10
+ ('Followers', 'followers'),
11
+ ('URI', lambda d: f"spotify:artist:{d['spotify_id']}")
12
+ ],
13
+ 'playlists': [
14
+ ('Owner', 'owner'),
15
+ ('Name', 'name'),
16
+ ('URI', lambda d: f"spotify:playlist:{d['spotify_id']}")
17
+ ],
18
+ 'tracks': [
19
+ ('Artist', 'artists'),
20
+ ('Name', 'name'),
21
+ ('URI', lambda d: f"spotify:track:{d['spotify_id']}")
22
+ ],
23
+ 'episodes': [
24
+ ('Name', 'name'),
25
+ ('Description', 'description'),
26
+ ('URI', lambda d: f"spotify:episode:{d['spotify_id']}")
27
+ ],
28
+ 'shows': [
29
+ ('Name', 'name'),
30
+ ('Description', 'description'),
31
+ ('URI', lambda d: f"spotify:show:{d['spotify_id']}")
32
+ ],
33
+ }
34
+
35
+ @staticmethod
36
+ def print_output(data):
37
+ if 'error' in data:
38
+ print(f"Error: {data['error']}")
39
+ elif 'notification' in data:
40
+ print(data['notification'])
41
+ else:
42
+ for key, value in data.items():
43
+ if key in DataPresenter.PRINT_TEMPLATES:
44
+ DataPresenter.__print_collection(key, value)
45
+ break
46
+
47
+ @staticmethod
48
+ def __print_collection(collection_type, items):
49
+ horizontal_line = "─" * 50
50
+ print(horizontal_line)
51
+ for item in items:
52
+ DataPresenter.__print_item(collection_type, item)
53
+ print(horizontal_line)
54
+
55
+ @staticmethod
56
+ def __print_item(collection_type, item_data):
57
+ for label, key in DataPresenter.PRINT_TEMPLATES[collection_type]:
58
+ value = key(item_data) if callable(key) else item_data[key]
59
+ print(f"{label}: {value}")
@@ -45,6 +45,10 @@ def main():
45
45
  play_uri_parser = play_type_parser.add_parser('uri', help='play resource by spotify URI')
46
46
  play_uri_parser.add_argument('uri', type=str, help='spotify uri')
47
47
 
48
+ find_parser = subparsers.add_parser('find', help='find items based on search query')
49
+ find_parser.add_argument('search_type', choices=['album', 'artist', 'playlist', 'track', 'episode', 'show'], help='type of item to find')
50
+ find_parser.add_argument('search_query', type=str, help='search query string')
51
+
48
52
  parser.add_argument('--format', choices=['json', 'text', 'verbose'], default='text', help='output format')
49
53
 
50
54
  args = parser.parse_args()
@@ -52,8 +56,14 @@ def main():
52
56
  payload = {
53
57
  'command': args.command,
54
58
  'setting': getattr(args, 'setting', None),
55
- 'type': getattr(args, 'get_type', None) or getattr(args, 'play_type', None),
56
- 'value': getattr(args, 'state', None) or getattr(args, 'level', None) or getattr(args, 'name', None) or getattr(args, 'uri', None)
59
+ 'type': (getattr(args, 'get_type', None) or
60
+ getattr(args, 'play_type', None) or
61
+ getattr(args, 'search_type', None)),
62
+ 'value': (getattr(args, 'state', None) or
63
+ getattr(args, 'level', None) or
64
+ getattr(args, 'name', None) or
65
+ getattr(args, 'uri', None) or
66
+ getattr(args, 'search_query', None))
57
67
  }
58
68
 
59
69
  client = Client()
@@ -23,9 +23,9 @@ args = parser.parse_args()
23
23
  spotify = SpotifyController()
24
24
  server = SocketServer(spotify)
25
25
 
26
- lock_file = "/tmp/myapp.lock"
26
+ lock_file = "/tmp/spotify-cmd-daemon.lock"
27
27
  if os.path.exists(lock_file):
28
- print("Application already running.")
28
+ print(f"Daemon already running ({lock_file} exists).")
29
29
  sys.exit(1)
30
30
  else:
31
31
  with open(lock_file, 'w'): pass
@@ -7,3 +7,4 @@ from .resume_playback import resume_playback
7
7
  from .set_shuffle import set_shuffle
8
8
  from .set_volume import set_volume
9
9
  from .start_playback import start_playback
10
+ from .search import search
@@ -0,0 +1,18 @@
1
+ from .presenters.albums_presenter import AlbumsPresenter
2
+
3
+ def get_library_albums(spotipy_client):
4
+ albums = []
5
+ limit = 50
6
+ offset = 0
7
+
8
+ while True:
9
+ results = spotipy_client.current_user_saved_albums(limit=limit, offset=offset)
10
+ raw_albums = list(map(lambda item: item['album'], results['items']))
11
+
12
+ albums += AlbumsPresenter(raw_albums).format()
13
+
14
+ offset += limit
15
+ if len(results['items']) < limit:
16
+ break
17
+
18
+ return {'albums': albums}
@@ -0,0 +1,16 @@
1
+ from .presenters.playlists_presenter import PlaylistsPresenter
2
+
3
+ def get_library_playlists(spotipy_client):
4
+ playlists = []
5
+ limit = 50
6
+ offset = 0
7
+
8
+ while True:
9
+ results = spotipy_client.current_user_playlists(limit=limit, offset=offset)
10
+ playlists += PlaylistsPresenter(results['items']).format()
11
+
12
+ offset += limit
13
+ if len(results['items']) < limit:
14
+ break
15
+
16
+ return {'playlists': playlists}
@@ -0,0 +1,7 @@
1
+ from .collection_presenter import CollectionPresenter
2
+ from .albums_presenter import AlbumsPresenter
3
+ from .artists_presenter import ArtistsPresenter
4
+ from .playlists_presenter import PlaylistsPresenter
5
+ from .tracks_presenter import TracksPresenter
6
+ from .shows_presenter import ShowsPresenter
7
+ from .episodes_presenter import EpisodesPresenter
@@ -0,0 +1,14 @@
1
+ from .collection_presenter import CollectionPresenter
2
+
3
+ class AlbumsPresenter(CollectionPresenter):
4
+ def format(self):
5
+ albums = []
6
+
7
+ for item in self.items:
8
+ album_info = super().format_item(item)
9
+ album_info.update({
10
+ 'artists': ', '.join([artist['name'] for artist in item['artists']]),
11
+ 'name': item['name']
12
+ })
13
+ albums.append(album_info)
14
+ return albums
@@ -0,0 +1,14 @@
1
+ from .collection_presenter import CollectionPresenter
2
+
3
+ class ArtistsPresenter(CollectionPresenter):
4
+ def format(self):
5
+ artists = []
6
+
7
+ for item in self.items:
8
+ artist_info = super().format_item(item)
9
+ artist_info.update({
10
+ 'name': item['name'],
11
+ 'followers': item['followers']['total']
12
+ })
13
+ artists.append(artist_info)
14
+ return artists
@@ -0,0 +1,12 @@
1
+ class CollectionPresenter:
2
+ def __init__(self, items):
3
+ self.items = items
4
+ print(items)
5
+ def format_item(self, item):
6
+ return {
7
+ 'spotify_id': item['id'],
8
+ 'type': self.get_type()
9
+ }
10
+
11
+ def get_type(self):
12
+ return self.__class__.__name__.replace('Presenter', '').lower()
@@ -0,0 +1,14 @@
1
+ from .collection_presenter import CollectionPresenter
2
+
3
+ class EpisodesPresenter(CollectionPresenter):
4
+ def format(self):
5
+ episodes = []
6
+
7
+ for item in self.items:
8
+ episode_info = super().format_item(item)
9
+ episode_info.update({
10
+ 'name': item['name'],
11
+ 'description': item['description']
12
+ })
13
+ episodes.append(episode_info)
14
+ return episodes
@@ -0,0 +1,14 @@
1
+ from .collection_presenter import CollectionPresenter
2
+
3
+ class PlaylistsPresenter(CollectionPresenter):
4
+ def format(self):
5
+ playlists = []
6
+
7
+ for item in self.items:
8
+ playlist_info = super().format_item(item)
9
+ playlist_info.update({
10
+ 'owner': item['owner']['display_name'],
11
+ 'name': item['name']
12
+ })
13
+ playlists.append(playlist_info)
14
+ return playlists
@@ -0,0 +1,14 @@
1
+ from .collection_presenter import CollectionPresenter
2
+
3
+ class ShowsPresenter(CollectionPresenter):
4
+ def format(self):
5
+ shows = []
6
+
7
+ for item in self.items:
8
+ show_info = super().format_item(item)
9
+ show_info.update({
10
+ 'name': item['name'],
11
+ 'description': item['description']
12
+ })
13
+ shows.append(show_info)
14
+ return shows
@@ -0,0 +1,14 @@
1
+ from .collection_presenter import CollectionPresenter
2
+
3
+ class TracksPresenter(CollectionPresenter):
4
+ def format(self):
5
+ tracks = []
6
+
7
+ for item in self.items:
8
+ track_info = super().format_item(item)
9
+ track_info.update({
10
+ 'artists': ', '.join([artist['name'] for artist in item['artists']]),
11
+ 'name': item['name']
12
+ })
13
+ tracks.append(track_info)
14
+ return tracks
@@ -0,0 +1,22 @@
1
+ from .presenters import *
2
+
3
+ def search(spotipy_client, search_query, resource_type):
4
+ response = spotipy_client.search(q=search_query, type=resource_type)
5
+ collection_key = next(iter(response.keys()))
6
+ items = response[collection_key].get('items', [])
7
+ result = None
8
+
9
+ if resource_type == 'album':
10
+ result = AlbumsPresenter(items).format()
11
+ elif resource_type == 'artist':
12
+ result = ArtistsPresenter(items).format()
13
+ elif resource_type == 'playlist':
14
+ result = PlaylistsPresenter(items).format()
15
+ elif resource_type == 'track':
16
+ result = TracksPresenter(items).format()
17
+ elif resource_type == 'show':
18
+ result = ShowsPresenter(items).format()
19
+ elif resource_type == 'episode':
20
+ result = EpisodesPresenter(items).format()
21
+
22
+ return { f"{resource_type}s": result }
@@ -49,6 +49,8 @@ class SpotifyController:
49
49
  self.handle_set(command_data)
50
50
  elif command == 'get':
51
51
  self.handle_get(command_data)
52
+ elif command == 'find':
53
+ self.handle_search(command_data)
52
54
  except SpotifyException as e:
53
55
  print(f"Spotify error: {e}")
54
56
  self.response = {"error": str(e)}
@@ -56,6 +58,13 @@ class SpotifyController:
56
58
  print(f"Error: {e}")
57
59
  self.response = {"error": str(e)}
58
60
 
61
+ def handle_search(self, command_data):
62
+ type = command_data.get('type')
63
+ search_query = command_data.get('value')
64
+
65
+ self.response = operations.search(self.spotipy_client, search_query, type)
66
+
67
+
59
68
  def handle_play(self, command_data):
60
69
  type = command_data.get('type')
61
70
 
@@ -1,22 +0,0 @@
1
- def get_library_albums(spotipy_client):
2
- albums = []
3
- limit = 50
4
- offset = 0
5
-
6
- while True:
7
- results = spotipy_client.current_user_saved_albums(limit=limit, offset=offset)
8
- for item in results['items']:
9
- album = item['album']
10
- album_info = {
11
- 'spotify_id': album['id'],
12
- 'type': 'album',
13
- 'artists': ', '.join([artist['name'] for artist in album['artists']]),
14
- 'name': album['name']
15
- }
16
- albums.append(album_info)
17
-
18
- offset += limit
19
- if len(results['items']) < limit:
20
- break
21
-
22
- return { 'albums': albums }
@@ -1,21 +0,0 @@
1
- def get_library_playlists(spotipy_client):
2
- playlists = []
3
- limit = 50
4
- offset = 0
5
-
6
- while True:
7
- results = spotipy_client.current_user_playlists(limit=limit, offset=offset)
8
- for item in results['items']:
9
- playlist_info = {
10
- 'spotify_id': item['id'],
11
- 'type': 'playlist',
12
- 'owner': item['owner']['display_name'],
13
- 'name': item['name']
14
- }
15
- playlists.append(playlist_info)
16
-
17
- offset += limit
18
- if len(results['items']) < limit:
19
- break
20
-
21
- return { 'playlists': playlists }
File without changes
File without changes
File without changes