Compare commits

...

6 Commits

6 changed files with 45 additions and 45 deletions

View File

@ -1,6 +1,6 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from src.fw_api import current_instance, federate_search_by_url, get_instance_settings from src.fw_api import current_instance, get_instance_settings
from src.fw_radios import list_radios from src.fw_radios import list_radios
from src.fw_artists import list_artists from src.fw_artists import list_artists
from src.fw_albums import list_albums from src.fw_albums import list_albums
@ -13,7 +13,6 @@ import src.mpv_control
import json import json
import os import os
from shlex import quote from shlex import quote
from loguru import logger
from pyfzf.pyfzf import FzfPrompt from pyfzf.pyfzf import FzfPrompt
fzf = FzfPrompt() fzf = FzfPrompt()
@ -32,7 +31,6 @@ def main():
'Playlists', 'Playlists',
'Favorites', 'Favorites',
'Recently listened', 'Recently listened',
'Search',
'About instance', 'About instance',
'Switch instance'] 'Switch instance']
try: try:
@ -83,13 +81,6 @@ def main():
list_fav_or_history() list_fav_or_history()
if selected == 'Recently listened': if selected == 'Recently listened':
list_fav_or_history(is_history_view=True) list_fav_or_history(is_history_view=True)
if selected == 'Search':
search_type = fzf.prompt(('Federated', 'All types'))[0]
if search_type == 'Federated':
print('Input url:')
returned_obj = federate_search_by_url(input())
logger.info(str(returned_obj))
if selected == 'Switch instance': if selected == 'Switch instance':
with open('config.json', 'rt') as f: with open('config.json', 'rt') as f:
conf = json.loads(f.read()) conf = json.loads(f.read())
@ -104,7 +95,7 @@ def main():
if selected == 'Sign in': if selected == 'Sign in':
print(f''' print(f'''
If You want sign in, please visit: If You want sign in, please visit:
https://{instance}/settings/applications/new https://{current_instance.instance}/settings/applications/new
And fill Name funkwhale-cli And fill Name funkwhale-cli
Scopes: Read, Write (optional): write:favorites write:listenings write:filters Scopes: Read, Write (optional): write:favorites write:listenings write:filters
@ -113,13 +104,14 @@ Insert token from "Access token" here''')
with open('.auth.json', 'rt') as f: with open('.auth.json', 'rt') as f:
tkns = json.loads(f.read()) tkns = json.loads(f.read())
with open('.auth.json', 'wt') as f: with open('.auth.json', 'wt') as f:
tkns[instance] = register_token tkns[current_instance.instance] = register_token
f.write(json.dumps(tkns)) f.write(json.dumps(tkns))
del tkns del tkns
del register_token del register_token
del f del f
os.system('clear')
current_instance.select_instance(instance) current_instance.select_instance(current_instance.instance)
if selected == 'Donate': if selected == 'Donate':
os.system(f'less <<EOF\nSupport instance message:\n{support_message}') os.system(f'less <<EOF\nSupport instance message:\n{support_message}')
if selected == 'About instance': if selected == 'About instance':

View File

@ -39,14 +39,14 @@ class current_instance:
def select_instance(new_instance=None): def select_instance(new_instance=None):
current_instance.instance = new_instance current_instance.instance = new_instance
with open(auth_file, 'rt') as f: with open(auth_file, 'rt') as f:
auth = json.loads(f.read()) auth = json.load(f)
new_token = auth.get(current_instance.instance) new_token = auth.get(current_instance.instance)
current_instance.s.headers.update({"Authorization": None}) current_instance.s.headers.update({"Authorization": None})
current_instance.token = new_token current_instance.token = new_token
current_instance.listen_token = None current_instance.listen_token = None
if new_token: if new_token:
s.get(f'https://{current_instance.instance}') current_instance.s.get(f'https://{current_instance.instance}')
s.headers.update({"Authorization": "Bearer " + new_token}) current_instance.s.headers.update({"Authorization": "Bearer " + new_token})
if current_instance.token: if current_instance.token:

View File

@ -1,4 +1,4 @@
from src.fw_api import list_libraries, federate_remote_library, scan_remote_library from src.fw_api import current_instance, list_libraries, federate_remote_library, scan_remote_library
from pyfzf.pyfzf import FzfPrompt from pyfzf.pyfzf import FzfPrompt
from loguru import logger from loguru import logger
import time import time
@ -18,16 +18,18 @@ def libraries(pg=None, radio=False):
libraries_listing.append('Next') libraries_listing.append('Next')
if libs_prev: if libs_prev:
libraries_listing.append('Prev') libraries_listing.append('Prev')
if radio == False: if current_instance.s.headers.get('Authorization'):
libraries_listing.append('Add remote library') libraries_listing.append('Add remote library')
for lib_i in libs: for lib_i in libs:
index = libs.index(lib_i) index = libs.index(lib_i)
lib_name = lib_i.get('name') lib_name = lib_i.get('name')
lib_tracks_count = lib_i.get('uploads_count')
lib_by = lib_i.get('actor').get('full_username') lib_by = lib_i.get('actor').get('full_username')
libraries_listing.append(f'{index}.{lib_name} | by {lib_by}') libraries_listing.append(f'{index}.{lib_name} | {lib_by} | {lib_tracks_count}')
lib_select = fzf.prompt( lib_select = fzf.prompt(
libraries_listing, f'--header=\'found {libs_count} libraries\'')[0].split('.', 1) libraries_listing,
f'--header=\'found {libs_count} libraries\nmap: library name | owner | tracks count\'')[0].split('.', 1)
if lib_select[0] == 'Next': if lib_select[0] == 'Next':
return libraries(pg=libs_next) return libraries(pg=libs_next)
elif lib_select[0] == 'Prev': elif lib_select[0] == 'Prev':
@ -61,4 +63,3 @@ def libraries(pg=None, radio=False):
return None, 'library', f'{lib_name}\n{lib_fid}', lib_uuid return None, 'library', f'{lib_name}\n{lib_fid}', lib_uuid
else: else:
return lib_uuid return lib_uuid

View File

@ -15,7 +15,7 @@ fzf = FzfPrompt()
@logger.catch @logger.catch
def list_radios(): def list_radios(error_given=None):
radios = get_radios() radios = get_radios()
count = radios.get('count') count = radios.get('count')
@ -35,9 +35,12 @@ def list_radios():
view.append('Favourites') view.append('Favourites')
view.append('Less listened') view.append('Less listened')
view.extend(['Tag', 'Random', 'Libraries', 'Users', 'Recently Added']) view.extend(['Tag', 'Random', 'Libraries', 'Users', 'Recently Added'])
header = f'Found {count} radios'
if error_given:
header += f'\n{error_given}'
header = quote(header)
selected = fzf.prompt( selected = fzf.prompt(
view, f'--header \'Found {count} radios\' --read0', delimiter="\0")[0].split('.', 1) view, f'--header {header} --read0', delimiter="\0")[0].split('.', 1)
if 'Favourites' in selected: if 'Favourites' in selected:
radio_load(id_radio, 'favorites', name='your favorites tracks') radio_load(id_radio, 'favorites', name='your favorites tracks')
elif 'Tag' in selected: elif 'Tag' in selected:
@ -104,7 +107,10 @@ def radio_load(id_radio=None, type_radio='custom', name=None, related_object=Non
} }
radio_session_id = post_radio_session(requested_radio).get('id') radio_session_id = post_radio_session(requested_radio).get('id')
for i in range(0, 2): for i in range(0, 2):
radio_get_track(radio_session_id) try:
radio_get_track(radio_session_id, first_run=True)
except Exception as E:
return list_radios(error_given=f'Error: {E}')
radio_event_gen.set() radio_event_gen.set()
radio_task = threading.Thread( radio_task = threading.Thread(
@ -121,8 +127,12 @@ def radio_load(id_radio=None, type_radio='custom', name=None, related_object=Non
player_items_menu[2] = 'Play' player_items_menu[2] = 'Play'
else: else:
player_items_menu[2] = 'Pause' player_items_menu[2] = 'Pause'
select = fzf.prompt(player_items_menu, try:
select = fzf.prompt(player_items_menu,
quote(f"--header=\'Radio {name} playing...\'"))[0] quote(f"--header=\'Radio {name} playing...\'"))[0]
except:
select = 'Exit'
if select == 'Next': if select == 'Next':
playlist_remaining = player.playlist_count - player.playlist_current_pos playlist_remaining = player.playlist_count - player.playlist_current_pos
if playlist_remaining <= 2: if playlist_remaining <= 2:
@ -148,37 +158,28 @@ def radio_load(id_radio=None, type_radio='custom', name=None, related_object=Non
name_downloaded = download_track(player.stream_open_filename) name_downloaded = download_track(player.stream_open_filename)
elif select == 'Info': elif select == 'Info':
track = player_fw_storage.storage.get(track_url_to_uuid()) track = player_fw_storage.storage.get(track_url_to_uuid())
track['direct_url'] = player.stream_open_filename
track_info_output(track) track_info_output(track)
print('Direct link: ' + player.stream_open_filename)
input()
elif select == 'Like': elif select == 'Like':
favorite_track(player_fw_storage.storage.get( favorite_track(player_fw_storage.storage.get(
track_url_to_uuid())['id']) track_url_to_uuid())['id'])
elif select == 'Exit': elif select == 'Exit':
try: radio_event_gen.clear()
radio_event_gen.clear()
except:
logger.exception('Error stopping Thread radio generator')
pass
soft_volume_reduce() soft_volume_reduce()
player.playlist_clear() player.playlist_clear()
player.stop() player.stop()
player_fw_storage.storage = {} player_fw_storage.storage = {}
break break
except: except Exception as E:
try: radio_event_gen.clear()
radio_event_gen.clear()
except:
logger.exception('Error stopping Thread radio generator')
pass
player.playlist_clear() player.playlist_clear()
player.stop() player.stop()
player_fw_storage.storage = {} player_fw_storage.storage = {}
logger.exception('Radio force stopped') logger.exception(f'Radio force stopped: {E}')
break break
def radio_get_track(radio_session_id): def radio_get_track(radio_session_id, first_run=False):
radio_context = get_track_radio({'session': radio_session_id}) radio_context = get_track_radio({'session': radio_session_id})
if not radio_context: if not radio_context:
return return
@ -186,6 +187,9 @@ def radio_get_track(radio_session_id):
logger.error(radio_context) logger.error(radio_context)
if radio_context == "Radio doesn't have more candidates": if radio_context == "Radio doesn't have more candidates":
radio_event_gen.clear() radio_event_gen.clear()
if first_run:
radio_context = 'This radio may be private or haven\'t tracks'
raise IOError(radio_context)
return return
if radio_context.get('error'): if radio_context.get('error'):
logger.error(radio_context.get('error')) logger.error(radio_context.get('error'))

View File

@ -155,9 +155,8 @@ def player_menu(header='', storage={}):
name_downloaded = download_track(player.stream_open_filename) name_downloaded = download_track(player.stream_open_filename)
elif select == 'Info': elif select == 'Info':
track = player_fw_storage.storage.get(track_url_to_uuid()) track = player_fw_storage.storage.get(track_url_to_uuid())
track['direct_url'] = player.stream_open_filename
track_info_output(track) track_info_output(track)
print('Direct link: ' + player.stream_open_filename)
input()
elif select == 'Like': elif select == 'Like':
src.fw_api.favorite_track( src.fw_api.favorite_track(
player_fw_storage.storage.get(track_url_to_uuid())['id']) player_fw_storage.storage.get(track_url_to_uuid())['id'])

View File

@ -1,5 +1,6 @@
import src.fw_api import src.fw_api
import os
import sys import sys
import shutil import shutil
from urllib.parse import unquote from urllib.parse import unquote
@ -57,12 +58,15 @@ def print_there(x, y, text):
def track_info_output(track): def track_info_output(track):
output = []
for k, v in track.items(): for k, v in track.items():
if k not in ('cover', 'uploads', 'listen_url', 'mbid', 'id', 'is_playable') and v is not None and v != []: if k not in ('cover', 'uploads', 'listen_url', 'mbid', 'id', 'is_playable') and v is not None and v != []:
if isinstance(v, dict): if isinstance(v, dict):
for i in ('title', 'name', 'fid'): for i in ('title', 'name', 'fid'):
if v.get(i): if v.get(i):
val_override = v.get(i) val_override = v.get(i)
print(f'{k}: {val_override}') output.append(f'{k}: {val_override}')
else: else:
print(f'{k}: {v}') output.append(f'{k}: {v}')
output = '\n'.join(output)
os.system(f'less <<EOF\n{output}')