Skip to content

Commit

Permalink
Push Code
Browse files Browse the repository at this point in the history
  • Loading branch information
ZingyTomato committed Apr 21, 2022
1 parent a031ce2 commit 6d83096
Show file tree
Hide file tree
Showing 6 changed files with 434 additions and 0 deletions.
59 changes: 59 additions & 0 deletions Harmony/albums.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import requests
import json
import re
from termcolor import colored
import functions

def searchAlbums():
album = input(colored("Add albums to the Queue ", 'cyan', attrs=['bold']) + colored("(P)lay, (S)how Queue, (B)ack, (Q)uit: ", 'red'))

if re.match(functions.URL_REGEX, album):
return functions.albumLink(), searchAlbums()

elif re.match(functions.PLAYLIST_REGEX, album):
return functions.playlistLink(), searchAlbums()

if album.isnumeric() == True and album != "q" and album != "Q" and album != "p" and album != "P":
return functions.invalidString(), searchAlbums()

elif album == "q" or album == "Q":
return functions.exitProgram()

elif album == "b" or album == "B" or album == "back" or album == "Back":
return functions.emptyQueue(), functions.chooseOption()

elif album == "p" or album == "P":
return functions.playTracks(functions.item_list, functions.queue_list), functions.emptyQueue(), searchAlbums()

elif album == "s" or album == "S":
return functions.showQueue(functions.item_list), searchAlbums()

return listAlbums(album)

def listAlbums(album):
search_results = functions.getAlbums(album)

if re.match(functions.URL_REGEX, album):
return functions.albumLink(), searchPlaylists()

if len(search_results['items']) == 0:
return functions.noResults(album), searchAlbums()

return functions.showResultsAlbumsPlaylists(album, search_results), pickAlbum(search_results, album)

def pickAlbum(json, album):
option = input(colored("\nPick an option", 'cyan', attrs=['bold']) + colored(f" [0:19, (B)ack]: ", 'red'))

if option.isnumeric() == False and option != "b" and option != "B":
return functions.invalidInteger(), pickAlbum(json, album)

elif option == "b" or option == "B":
return print("\n"), searchAlbums()

if int(option) >= 19:
return functions.invalidRange(), pickAlbum(json, album)

videoid = json['items'][int(option)]['url']
title = colored(json['items'][int(option)]['name'], 'red')
author = colored(json['items'][int(option)]['uploaderName'], 'cyan')
return functions.addItems(videoid, title, author), searchAlbums()
155 changes: 155 additions & 0 deletions Harmony/functions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
import os
from termcolor import colored
import time
import requests
import json
import songs
import videos
import albums
import playlists

queue_list = []

item_list = []

headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; rv:91.0) Gecko/20100101 Firefox/91.0'
}

YOUTUBE_REGEX = r"http(?:s?):\/\/(?:www\.)?youtu(?:be\.com\/watch\?v=|\.be\/)([\w\-\_]*)(&(amp;)?‌​[\w\?‌​=]*)?"

URL_REGEX = r"(http|ftp|https):\/\/([\w\-_]+(?:(?:\.[\w\-_]+)+))([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?"

PLAYLIST_REGEX = r" /^.*(youtu.be\/|list=)([^#\&\?]*).*/"

def emptyQueue():
item_list.clear()
queue_list.clear()

def youtubeLink():
info = print(colored("\nYoutube URL detected, directly playing the link.", color='cyan', attrs=['bold']) + colored(' (q to quit)\n', 'red'))
return info

def urlLink():
info = print(colored("\nURL detected, trying to directly play the link.", color='cyan', attrs=['bold']) + colored(' (q to quit)\n', 'red'))
return info

def playlistLink():
info = print(colored("\nLinks are not supported. Use --playlist to search for playlists.", color='red', attrs=['bold']) + colored(' (q to quit)\n', 'red'))
return info

def albumLink():
info = print(colored("\nLinks are not supported. Use --album to search for albums.", color='red', attrs=['bold']) + colored(' (q to quit)\n', 'red'))
return info

def invalidString():
exitmsg = print(colored("\nPlease enter a valid string!\n", 'red', attrs=['bold']))
return exitmsg

def invalidInteger():
exitmsg = print(colored("\nPlease enter a valid integer!", 'red', attrs=['bold']))
return exitmsg

def exitProgram():
exitmsg = print(colored("\nExited.\n", 'red', attrs=['bold']))
return os.system("exit"), exitmsg

def noResults(result):
info = print(colored(f"Unable to find any results for {colored(result, 'cyan')}! \n", 'red', attrs=['bold']))
return info

def invalidRange():
exitmsg = print(colored("\nInteger out of range!", 'red', attrs=['bold']))
return exitmsg

def showQueue(item_list):
if len(item_list) == 0:
empty = print(colored("\nThe queue is empty!\n",'red', attrs=['bold']))
return empty
else:
show_queue = print(f"\n".join([f"{colored(i, 'green')}. {track} \n" for i, track in enumerate((item_list))]))
return show_queue

def showResults(query, result):
info = print(colored("Results for", 'red') + colored(f" {query}\n", 'cyan', attrs=['bold']))
lists = print(f"\n".join([f"{colored(i, 'green')}. {item['title']} - {item['uploaderName']} ({time.strftime('%M:%S',time.gmtime(item['duration']))})" for i, item in enumerate((result['items']))]))
return info, lists

def showResultsAlbumsPlaylists(query, result):
info = print(colored("Results for", 'red') + colored(f" {query}\n", 'cyan', attrs=['bold']))
lists = print(f"\n".join([f"{colored(i, 'green')}. {item['name']} - {item['uploaderName']}" for i, item in enumerate((result['items']))]))
return info, lists

def getSongs(query):
print(colored("\nSearching for songs... \n", 'cyan', attrs=['bold']))
searchurl = requests.request("GET", f"https://pipedapi.kavin.rocks/search?q={query}&filter=music_songs", headers=headers).text
searchjson = json.loads(searchurl)
return searchjson

def getVideos(query):
print(colored("\nSearching for videos... \n", 'cyan', attrs=['bold']))
searchurl = requests.request("GET", f"https://pipedapi.kavin.rocks/search?q={query}&filter=videos", headers=headers).text
searchjson = json.loads(searchurl)
return searchjson

def getAlbums(query):
print(colored("\nSearching for albums... \n", 'cyan', attrs=['bold']))
searchurl = requests.request("GET", f"https://pipedapi.kavin.rocks/search?q={query}&filter=music_albums", headers=headers).text
searchjson = json.loads(searchurl)
return searchjson

def getPlaylists(query):
print(colored("\nSearching for playlists... \n", 'cyan', attrs=['bold']))
searchurl = requests.request("GET", f"https://pipedapi.kavin.rocks/search?q={query}&filter=playlists", headers=headers).text
searchjson = json.loads(searchurl)
return searchjson

def playTracks(item_list, queue_list):
if len(item_list) == 0:
empty = print(colored("\nThe queue is empty!\n",'red', attrs=['bold']))
return empty
queuemsg = print(colored("\nPlaying items in the queue", 'cyan', attrs=['bold']) + colored(' (q to quit)\n', 'red'))
show_queue = print(f"\n".join([f"{colored(i, 'green')}. {track} \n" for i, track in enumerate((item_list))]))
play_tracks = os.system(f"mpv --vo=null --cache=yes --video=no --no-video --term-osd-bar --no-resume-playback {' '.join(queue_list)} ")
return queuemsg, show_queue, play_tracks

def playVideos(item_list, queue_list):
if len(item_list) == 0:
empty = print(colored("\nThe queue is empty!\n",'red', attrs=['bold']))
return empty
queuemsg = print(colored("\nPlaying items in the queue", 'cyan', attrs=['bold']) + colored(' (q to quit)\n', 'red'))
show_queue = print(f"\n".join([f"{colored(i, 'green')}. {track} \n" for i, track in enumerate((item_list))]))
play_videos = os.system(f"mpv --cache=yes --term-osd-bar --no-resume-playback {' '.join(queue_list)} ")
return queuemsg, show_queue, play_videos

def playVideosURL(url):
play_videos = os.system(f"mpv --cache=yes --term-osd-bar --no-resume-playback {url} ")
return play_videos

def playTracksURL(url):
play_videos = os.system(f"mpv --vo=null --cache=yes --video=no --no-video --term-osd-bar --no-resume-playback {url} ")
return play_videos

def addItems(videoid, title, author):
stream_url = "https://piped.kavin.rocks" + f"{videoid}"
queue_list.append(stream_url)
item_list.append(f"{title} - {author}")
added = print(colored(f"\n{title} - ", 'cyan') + colored(f'{author}', 'red') + colored(" has been added to the queue.\n", 'green'))
return added

def chooseOption():
option = input(colored("\nSelect an option ", 'cyan', attrs=['bold']) + colored("(S)ongs, (V)ideos, (P)laylists, (A)lbums, Q(uit): ", 'red'))
if option == "S" or option == "s":
return print("\n"), songs.searchSongs()
elif option == "V" or option == "v":
return print("\n"), videos.searchVideos()
elif option == "P" or option == "p":
return print("\n"), playlists.searchPlaylists()
elif option == "A" or option == "a":
return print("\n"), albums.searchAlbums()
elif option == "Q" or option == "q" or option == "B" or option == "b":
return exitProgram()
else:
info = print(colored("\nInvalid option entered!", 'red', attrs=['bold']))
return info, chooseOption()
return
34 changes: 34 additions & 0 deletions Harmony/harmony.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import argparse
import songs
import videos
import albums
import playlists
import functions

parser = argparse.ArgumentParser(description="An open souce video/music streamer based on MPV and piped.")

group = parser.add_mutually_exclusive_group()

group.add_argument('--song', '-s', '--s', action='store_true', help="""Searches for songs based on query. Example: harmony --song "Never gonna give you up" """)

group.add_argument('--video', '-v', '--v', action='store_true', help="""Searches for videos based on the query. Example: harmony --video "Never gonna give you up" """)

group.add_argument('--album', '-a', '--a', action='store_true', help="""Searches for albums based on the query. Example: harmony --album "All Over The Place" """)

group.add_argument('--playlist', '-p', '--p', action='store_true', help="""Searches for playlists based on the query. Example: harmony --playlist "All Over The Place" """)

parser.add_argument('query', type=str)

args = parser.parse_args()

if args.song:
songs.listTracks(args.query)

elif args.video:
videos.listVideos(args.query)

elif args.album:
albums.listAlbums(args.query)

elif args.playlist:
playlists.listPlaylists(args.query)
56 changes: 56 additions & 0 deletions Harmony/playlists.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import requests
import json
import re
from termcolor import colored
import functions

def searchPlaylists():
playlist = input(colored("Add playlists to the Queue ", 'cyan', attrs=['bold']) + colored("(P)lay, (S)how Queue, (B)ack, (Q)uit: ", 'red'))

if re.match(functions.URL_REGEX, playlist):
return functions.playlistLink(), searchPlaylists()

if playlist.isnumeric() == True and playlist != "q" and playlist != "Q" and playlist != "p" and playlist != "P":
return functions.invalidString(), searchPlaylists()

elif playlist == "q" or playlist == "Q":
return functions.exitProgram()

elif playlist == "b" or playlist == "B":
return functions.emptyQueue(), functions.chooseOption()

elif playlist == "p" or playlist == "P":
return functions.playTracks(functions.item_list, functions.queue_list), functions.emptyQueue(), searchPlaylists()

elif playlist == "s" or playlist == "S":
return functions.showQueue(functions.item_list), searchPlaylists()

return listPlaylists(playlist)

def listPlaylists(playlist):
search_results = functions.getPlaylists(playlist)

if re.match(functions.URL_REGEX, playlist):
return functions.playlistLink(), searchPlaylists()

if len(search_results['items']) == 0:
return functions.noResults(playlist), searchPlaylists()

return functions.showResultsAlbumsPlaylists(playlist, search_results), pickPlaylist(search_results, playlist)

def pickPlaylist(json, playlist):
option = input(colored("\nPick an option", 'cyan', attrs=['bold']) + colored(f" [0:19, (B)ack]: ", 'red'))

if option.isnumeric() == False and option != "b" and option != "B":
return functions.invalidInteger(), pickPlaylist(json, playlist)

elif option == "b" or option == "B":
return print("\n"), searchPlaylists()

if int(option) >= 19:
return functions.invalidRange(), pickPlaylist(json, playlist)

videoid = json['items'][int(option)]['url']
title = colored(json['items'][int(option)]['name'], 'red')
author = colored(json['items'][int(option)]['uploaderName'], 'cyan')
return functions.addItems(videoid, title, author), searchPlaylists()
65 changes: 65 additions & 0 deletions Harmony/songs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import requests
import json
import re
from termcolor import colored
import functions

def searchSongs():
song = input(colored("Add songs to the Queue ", 'cyan', attrs=['bold']) + colored("(P)lay, (S)how Queue, (B)ack, (Q)uit: ", 'red'))

if re.match(functions.YOUTUBE_REGEX, song):
return functions.youtubeLink(), functions.playTracksURL(song), searchSongs()

elif re.match(functions.URL_REGEX, song):
return functions.urlLink(), functions.playTracksURL(song), searchSongs()

elif re.match(functions.PLAYLIST_REGEX, song):
return functions.playlistLink(), searchSongs()

if song.isnumeric() == True and song != "e" and song != "E" and song != "p" and song != "P":
return functions.invalidString(), searchSongs()

elif song == "q" or song == "Q":
return functions.exitProgram()

elif song == "b" or song == "B":
return functions.emptyQueue(), functions.chooseOption()

elif song == "p" or song == "P":
return functions.playTracks(functions.item_list, functions.queue_list), functions.emptyQueue(), searchSongs()

elif song == "s" or song == "S":
return functions.showQueue(functions.item_list), searchSongs()

return listTracks(song)

def listTracks(song):
search_results = functions.getSongs(song)

if re.match(functions.YOUTUBE_REGEX, song):
return functions.youtubeLink(), functions.playTracksURL(song), searchSongs()

elif re.match(functions.URL_REGEX, song):
return functions.urlLink(), functions.playTracksURL(song), searchSongs()

if len(search_results['items']) == 0:
return functions.noResults(song), searchSongs()

return functions.showResults(song, search_results), pickTrack(search_results, song)

def pickTrack(json, song):
option = input(colored("\nPick an option", 'cyan', attrs=['bold']) + colored(f" [0:19, (B)ack]: ", 'red'))

if option.isnumeric() == False and option != "b" and option != "B":
return functions.invalidInteger(), pickTrack(json, song)

elif option == "b" or option == "B":
return print("\n"), searchSongs()

if int(option) >= 19:
return functions.invalidRange(), pickTrack(json, song)

videoid = json['items'][int(option)]['url']
title = colored(json['items'][int(option)]['title'], 'red')
author = colored(json['items'][int(option)]['uploaderName'], 'cyan')
return functions.addItems(videoid, title, author), searchSongs()
Loading

0 comments on commit 6d83096

Please sign in to comment.