Compare commits
6 Commits
9ec77975e5
...
a76f36bafd
Author | SHA1 | Date |
---|---|---|
localhost_frssoft | a76f36bafd | |
localhost_frssoft | f5840926a6 | |
localhost_frssoft | 95874e2289 | |
localhost_frssoft | c93a2f0ee5 | |
localhost_frssoft | 4ab9f2db2d | |
localhost_frssoft | dc40e5331c |
|
@ -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':
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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'))
|
||||||
|
|
|
@ -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'])
|
||||||
|
|
|
@ -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}')
|
||||||
|
|
Loading…
Reference in New Issue