funkwlmpv/src/fw_radios.py

195 lines
7.2 KiB
Python
Raw Normal View History

2022-12-04 01:01:11 +00:00
from src.fw_api import current_instance, get_radios, post_radio_session, get_track_radio, list_libraries, favorite_track, get_audio_file
2022-11-08 22:34:33 +00:00
from src.fw_libraries import libraries
2022-11-30 00:33:14 +00:00
from src.fw_tags import list_tags
from src.utils import download_track
from src.mpv_control import player, track_url_to_uuid, player_fw_storage
from src.settings import get_config
2022-11-01 10:15:28 +00:00
from pyfzf.pyfzf import FzfPrompt
from loguru import logger
import threading
import time
2022-11-01 10:15:28 +00:00
fzf = FzfPrompt()
@logger.catch
2022-11-01 10:15:28 +00:00
def list_radios():
radios = get_radios()
count = radios.get('count')
results = radios.get('results')
view = []
2022-12-18 01:02:53 +00:00
for i in results:
2022-11-01 10:15:28 +00:00
index = results.index(i)
id_radio = i.get('id')
name = i.get('name')
2022-11-23 22:48:59 +00:00
descr = i.get('description')
radio_option = name
if descr and descr != "":
radio_option += f' | {descr}'
view.append(f'{index}.{radio_option}')
2022-12-18 01:02:53 +00:00
# Radios avalaible only for auth user
if current_instance.s.headers.get('Authorization'):
view.append('Favourites')
view.append('Less listened')
2022-11-30 00:33:14 +00:00
view.extend(['Tag', 'Random', 'Libraries', 'Users', 'Recently Added'])
2022-11-02 23:58:55 +00:00
2022-12-18 01:02:53 +00:00
selected = fzf.prompt(
view, f'--header \'Found {count} radios\' --read0', delimiter="\0")[0].split('.', 1)
2022-11-02 23:58:55 +00:00
if 'Favourites' in selected:
radio_load(id_radio, 'favorites', name='your favorites tracks')
2022-11-30 00:33:14 +00:00
elif 'Tag' in selected:
tag = list_tags()
2022-11-30 00:41:14 +00:00
radio_load(type_radio='tag', name=f'by tag: {tag}', related_object=tag)
elif 'Random' in selected:
radio_load(id_radio, 'random', name='totally random')
elif 'Libraries' in selected:
2022-11-08 22:34:33 +00:00
id_radio, type_radio, name_radio, related_obj = libraries()
radio_load(id_radio, type_radio, name_radio, related_obj)
elif 'Users' in selected:
2022-11-08 00:29:44 +00:00
libs = list_libraries()['results']
libraries_listing = []
for lib_i in libs:
lib_name = lib_i.get('actor').get('full_username')
if lib_name not in libraries_listing:
libraries_listing.append(lib_name)
libraries_listing.append('Custom')
lib_addr = fzf.prompt(libraries_listing)[0]
if lib_addr == 'Custom':
print('Input remote user library (ex. nick@funkwhale.domain.example: ')
lib_addr = input()
radio_load(None, 'actor-content', lib_addr, lib_addr)
elif 'Recently Added' in selected:
2022-12-18 01:02:53 +00:00
radio_load(id_radio, 'recently-added',
name='Newest content on the network')
elif 'Less listened' in selected:
radio_load(id_radio, 'less-listened', name="Less listened tracks")
2022-11-02 23:58:55 +00:00
else:
id_selected = selected[0]
id_radio = results[int(id_selected)].get('id')
2022-11-07 11:36:02 +00:00
name_radio = results[int(id_selected)].get('name')
radio_load(id_radio, name=name_radio)
2022-11-01 10:15:28 +00:00
def radio_generator(radio_session_id):
count_t = 0
while radio_session_id != '':
time.sleep(1)
2022-12-18 01:02:53 +00:00
if not radio_event_gen.wait(0):
break
count_t += 1
if count_t >= 60:
count_t = 0
2022-12-18 01:02:53 +00:00
playlist_remaining = len(player.playlist) - \
player.playlist_current_pos
if playlist_remaining <= 2:
radio_get_track(radio_session_id)
logger.info('Radio generator stopped')
2022-12-18 01:02:53 +00:00
radio_event_gen = threading.Event()
@logger.catch
def radio_load(id_radio=None, type_radio='custom', name=None, related_object=None):
show_like_button = get_config('show_like_button')
2022-11-14 23:02:22 +00:00
player.volume = get_config('mpv_volume')
2022-11-01 10:15:28 +00:00
requested_radio = {
2022-12-18 01:02:53 +00:00
'custom_radio': id_radio,
'radio_type': type_radio,
'related_object_id': related_object
}
2022-11-01 10:15:28 +00:00
radio_session_id = post_radio_session(requested_radio).get('id')
for i in range(0, 2):
2022-11-01 10:15:28 +00:00
radio_get_track(radio_session_id)
radio_event_gen.set()
2022-12-18 01:02:53 +00:00
radio_task = threading.Thread(
target=radio_generator, args=(radio_session_id,), daemon=True)
radio_task.start()
2022-12-18 01:02:53 +00:00
player_items_menu = ['Next', 'Prev', 'Pause', 'Download', 'Info']
2022-11-18 10:22:55 +00:00
if show_like_button:
player_items_menu.append('Like')
player_items_menu.extend(['Hide artist', 'Exit'])
while True:
try:
if player.pause:
player_items_menu[2] = 'Play'
else:
player_items_menu[2] = 'Pause'
2022-12-18 01:02:53 +00:00
select = fzf.prompt(player_items_menu,
f"--header=\'Radio {name} playing...\'")[0]
if select == 'Next':
2022-12-18 01:02:53 +00:00
playlist_remaining = len(
player.playlist) - player.playlist_current_pos
if playlist_remaining <= 2:
2022-12-18 01:02:53 +00:00
threading.Thread(target=radio_get_track, args=(
radio_session_id,), daemon=True).start()
player.playlist_next()
elif select == 'Prev':
player.playlist_prev()
2022-11-18 10:22:55 +00:00
elif select in ('Pause', 'Play'):
if player.pause:
player.pause = False
else:
player.pause = True
elif select == 'Download':
name_downloaded = download_track(player.stream_open_filename)
elif select == 'Info':
track = player_fw_storage.storage.get(track_url_to_uuid())
for i in ('title', 'fid', 'license', 'album', 'artist'):
if i in ('album', 'artist'):
name_aa = track.get(i).get('name')
if not name_aa:
2022-11-18 10:22:55 +00:00
name_aa = track[i]['title']
2022-12-18 01:02:53 +00:00
print(i + ': ' + name_aa)
key = track.get(i)
if key and isinstance(key, str):
print(i + ': ' + key)
input()
2022-11-18 10:22:55 +00:00
elif select == 'Like':
2022-12-18 01:02:53 +00:00
favorite_track(player_fw_storage.storage.get(
track_url_to_uuid())['id'])
elif select == 'Exit':
try:
radio_event_gen.clear()
except:
logger.exception('Error stopping Thread radio generator')
pass
player.playlist_clear()
player.stop()
player_fw_storage.storage = {}
break
2022-12-18 01:02:53 +00:00
except:
try:
radio_event_gen.clear()
except:
logger.exception('Error stopping Thread radio generator')
pass
player.playlist_clear()
player.stop()
player_fw_storage.storage = {}
logger.exception('Radio force stopped')
break
2022-11-01 10:15:28 +00:00
def radio_get_track(radio_session_id):
radio_context = get_track_radio({'session': radio_session_id})
if not radio_context:
return
if isinstance(radio_context, str):
logger.error(radio_context)
if radio_context == "Radio doesn't have more candidates":
radio_event_gen.clear()
return
if radio_context.get('error'):
logger.error(radio_context.get('error'))
2022-11-02 23:58:55 +00:00
return
else:
track = radio_context.get('track')
listen_url = track['listen_url']
player_fw_storage.storage[track_url_to_uuid(listen_url)] = track
2022-12-18 01:02:53 +00:00
player.loadfile(get_audio_file(
listen_url, listen_url=True), 'append-play')