Skip to content

Commit

Permalink
Added minor changes (#27)
Browse files Browse the repository at this point in the history
* Create ui.py

* Create ui.tcss

* Delete musicplayer/ui directory

* Create ui.py

* Create ui.tcss

* init

* config hero section

* progress ui and helper functions

* init ui

* Added progress bar and music player

* fetch accurate metadata from spotify-api

* integrated ui with music player

* connect ui with music player

* Update spotify_importer.py

* Revamp UI

* minor UI changes

* Delete run_ui.sh

* removed ds_store files

* added queue

* test commit

* added error handling and help commands

* added fetch playlist helper function

* fix track time errors

* Revert "fix track time errors"

This reverts commit c86682c.

* minor changes

* Update .env.example

* Update requirements.txt

* Update argparser.py

* Update main.py

* Update spotify_importer.py

* Update textual_app.py

* Update player.py
  • Loading branch information
techie-coder authored Feb 8, 2025
1 parent d9b02c6 commit 8abd166
Show file tree
Hide file tree
Showing 10 changed files with 481 additions and 314 deletions.
5 changes: 4 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,8 @@ MUSIC_FOLDER=/path/to/your/music
# Spotify client id and secret for searching tracks:
# visit https://developer.spotify.com/documentation/web-api to get your client id and secret.
SPOTIFY_CLIENT_ID=your_spotify_client_id

SPOTIFY_CLIENT_SECRET=your_spotify_client_secret
REDIRECT_URI=http://localhost:3000

REDIRECT_URI=http://localhost:3000

2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ docs/_build/

#extra
.cache

.DS_Store
private/

#shell-script
Expand Down
91 changes: 91 additions & 0 deletions ethos/argparser.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import argparse
from ethos.utils import get_audio_url, fetch_tracks_list
from ethos.player import MusicPlayer, TrackInfo
from ethos.tools import helper
from rich.console import Console
import asyncio
import time

class ArgumentParser():
"""Argument Parser class for ethos cli"""

def __init__(self):
self.parser = argparse.ArgumentParser(description="Ethos CLI App")
self.console = Console(color_system='256')
self.player = MusicPlayer()

def start(self, args) -> None:
"""Start the player"""
self.console.print("[magenta]Starting ethos cli...")

def stop(self, args) -> None:
"""Stop the player"""
self.console.print("[magenta]Stopping ethos cli...")

def status(self, args) -> None:
"""Sets the status of the player"""
self.console.print("[magenta]Status ethos cli...")

async def play(self, args) -> None:
"""Plays a track provided by the user"""

track = args.track if args.track else str(input("Enter track name to play :"))
self.console.print(f"[cyan]Fetching track: {track}")
tracks_list = await fetch_tracks_list(track)
track_no = 0
if not args.track_no:
if tracks_list:
self.console.print("Search results :")
self.console.print("\n".join(tracks_list))
track_no = int(input("Enter track number :"))
track_name = helper.Format.clean_hashtag(tracks_list[track_no-1])
track_url = get_audio_url(track_name+"official music video")

if not track_url:
self.console.print(f"[red]Could not fetch URL for {track_name}")
return

volume = args.volume if args.volume else 50
self.console.print("[deep pink]Playing at default volume: 50")
self.player.set_volume(volume)
self.player.play(track_url)

self.console.print(f"[deep pink]Playing {track_name}")
track_length = TrackInfo.get_audio_duration_int(track_url)
while TrackInfo.get_current_time_int(self.player) < track_length:
time.sleep(1)
if TrackInfo.get_current_time_int(self.player) == track_length:
return

async def listen(self) -> None:
"""Listens to commands from cli"""
self.subparsers = self.parser.add_subparsers(dest="command", help="Available commands:")

self.start_parser = self.subparsers.add_parser("start", help="Start the app")
self.start_parser.set_defaults(func=self.start)

self.stop_parser = self.subparsers.add_parser("stop", help="Stop the parser")
self.stop_parser.set_defaults(func=self.stop)

self.status_parser = self.subparsers.add_parser("status", help="Check status")
self.status_parser.set_defaults(func=self.status)

self.play_parser = self.subparsers.add_parser("play", help="play a track")
self.play_parser.add_argument("track", type=str, nargs="?", help="name of the track you want to play")
self.play_parser.add_argument("track_no", type=int, nargs="?", help="track no. of track to be played from search results")
self.play_parser.add_argument("volume", type=int, nargs="?", help="volume of the player")
self.play_parser.set_defaults(func=self.play)

self.args = self.parser.parse_args()

if hasattr(self.args, "func"):
await self.args.func(self.args)

else:
self.parser.print_help()


if __name__ == "__main__":
arg_parser = ArgumentParser()
asyncio.run(arg_parser.listen())

1 change: 1 addition & 0 deletions ethos/main.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

########################
# Entry point of Ethos #
########################
Expand Down
2 changes: 1 addition & 1 deletion ethos/player.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,4 +226,4 @@ def get_progress(music_player: "MusicPlayer") -> float:

if duration > 0:
return (current_time / duration) * 100
return 0.0
return 0.0
2 changes: 1 addition & 1 deletion ethos/spotify_importer.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,4 +115,4 @@ def refresh_playlist(self, playlist_id: str, playlist_name: str):

print(f"Playlist '{selected_playlist['name']}' has been saved.")

# importer.refresh_all_playlists() # Refresh all playlists
importer.refresh_all_playlists() # Refresh all playlists
12 changes: 9 additions & 3 deletions ethos/tools/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,21 @@ def parse_command(command: str):

command_type, value = parts

if command_type == '/play' or command_type == '/queue-add' or command_type == '/queue-remove':
if command_type == '/play' or command_type == '/queue-add' or command_type == '/queue-remove' or command_type == "/vp":
return value
elif command_type == '/volume' or command_type == '/qp':
try:
return int(value)
except ValueError:
raise ValueError("Volume must be a number")
else:
raise ValueError("Unknown command")
elif command_type == '/ap':
try:
parts = value.split(maxsplit=1)
playlist_name, track_name = parts
return playlist_name, track_name
except:
pass



@staticmethod
Expand Down
Loading

0 comments on commit 8abd166

Please sign in to comment.