funkwlmpv/src/fw_api.py

432 lines
12 KiB
Python
Raw Permalink Normal View History

from src.settings import get_config
2022-12-18 03:02:53 +02:00
import requests
import json
import time
2022-11-21 00:49:19 +02:00
import urllib.parse
2022-11-09 12:11:36 +02:00
import os
2022-11-01 12:15:28 +02:00
from loguru import logger
2023-02-06 01:01:53 +02:00
attempts_for_federate = 3
2022-11-09 12:11:36 +02:00
auth_file = '.auth.json'
if os.path.exists(auth_file):
with open('.auth.json', 'rt') as f:
auth = json.loads(f.read())
else:
# The default umask is 0o22 which turns off write permission of group and others
os.umask(0)
descriptor = os.open(
path=auth_file,
flags=(
os.O_WRONLY # access mode: write only
| os.O_CREAT # create if not exists
| os.O_TRUNC # truncate the file to zero
),
mode=0o600)
with open(descriptor, 'wt') as f:
f.write('{}')
auth = {}
2022-11-01 12:15:28 +02:00
2022-12-04 03:01:11 +02:00
class current_instance:
s = requests.Session()
2023-06-16 14:45:20 +03:00
s.headers.update({
"Accept-encoding": 'gzip, br, deflate',
2023-08-03 11:35:37 +03:00
"User-Agent": "funkwlmpv/latest-commit; +https://git.phreedom.club/localhost_frssoft/funkwlmpv"
2023-06-16 14:45:20 +03:00
})
2022-12-04 03:01:11 +02:00
instance = get_config('instance')
token = auth.get(instance)
listen_token = None
2022-12-04 03:01:11 +02:00
@logger.catch
def select_instance(new_instance=None):
current_instance.instance = new_instance
with open(auth_file, 'rt') as f:
2023-06-14 15:27:15 +03:00
auth = json.load(f)
2022-12-04 03:01:11 +02:00
new_token = auth.get(current_instance.instance)
2023-01-02 17:43:18 +02:00
current_instance.s.headers.update({"Authorization": None})
current_instance.token = new_token
current_instance.listen_token = None
2022-12-04 03:01:11 +02:00
if new_token:
current_instance.s.get(f'https://{current_instance.instance}', timeout=30)
2023-06-14 15:27:15 +03:00
current_instance.s.headers.update({"Authorization": "Bearer " + new_token})
2022-12-04 03:01:11 +02:00
if current_instance.token:
2023-01-02 17:43:18 +02:00
current_instance.s.headers.update({"Authorization": "Bearer " + current_instance.token})
else:
2022-12-18 03:02:53 +02:00
# Get cookies from unauthorized instance for working some functionality (radios)
current_instance.s.get(f'https://{current_instance.instance}/', timeout=30)
2023-06-14 00:59:09 +03:00
@logger.catch
def get_me():
'''Return current user if token avalaible'''
if not current_instance.token:
return
r = current_instance.s.get(f'https://{current_instance.instance}/api/v1/users/me')
r.raise_for_status()
resp = r.json()
current_instance.listen_token = resp['tokens']['listen']
2023-06-14 00:59:09 +03:00
return resp
def get_instance_settings():
2022-12-18 03:02:53 +02:00
r = current_instance.s.get(
f'https://{current_instance.instance}/api/v1/instance/settings')
return r.json()
def get_node_info():
r = current_instance.s.get(
f'https://{current_instance.instance}/api/v1/instance/nodeinfo/2.0/',
timeout=30)
r.raise_for_status()
return r.json()
@logger.catch
2023-06-14 00:59:09 +03:00
def get_audio_file(track_uuid, listen_url=False, download=False,
external_transcoding=get_config('external_transcoder_http_proxy_path'),
transcoding=get_config('enable_server_transcoding'), to='ogg', max_bitrate=128):
params = {
2022-12-18 03:02:53 +02:00
"download": download,
"to": to,
"max_bitrate": max_bitrate
}
if current_instance.token and not current_instance.listen_token:
get_me()
if current_instance.listen_token:
params['token'] = current_instance.listen_token
2022-12-20 03:05:54 +02:00
if not transcoding:
del params['to']
del params['max_bitrate']
if listen_url:
2022-12-04 03:01:11 +02:00
url = f'https://{current_instance.instance}{track_uuid}?'
else:
2022-12-04 03:01:11 +02:00
url = f'https://{current_instance.instance}/api/v1/listen/{track_uuid}?'
if external_transcoding != "":
url = external_transcoding + url
2022-12-20 03:05:54 +02:00
return url + urllib.parse.urlencode(params, doseq=True)
2022-11-01 12:15:28 +02:00
2022-11-08 19:58:27 +02:00
@logger.catch
2023-06-18 00:53:00 +03:00
def get_tracks(page=None, ordering=None, q=None, page_size=None,
artist=None, album=None, library=None,
2022-11-30 02:17:18 +02:00
tag=None, favourites=None, include_channels=None, pg=None):
'''This function get tracks by params'''
params = {
2022-12-18 03:02:53 +02:00
'page': page,
2023-06-18 00:53:00 +03:00
'page_size': page_size,
'ordering': ordering,
2022-12-18 03:02:53 +02:00
'q': q,
'artist': artist,
'album': album,
'tag': tag,
'favourites': favourites,
'library': library,
2022-12-18 03:02:53 +02:00
'include_channels': include_channels
}
2022-11-08 19:58:27 +02:00
if pg:
2022-12-04 03:01:11 +02:00
r = current_instance.s.get(pg)
2022-11-08 19:58:27 +02:00
else:
2022-12-18 03:02:53 +02:00
r = current_instance.s.get(
f'https://{current_instance.instance}/api/v1/tracks', params=params)
2022-11-08 19:58:27 +02:00
return r.json()
2022-11-15 03:22:32 +02:00
@logger.catch
def get_favorires_tracks(page=None, q=None, scope=None, include_channels=None, pg=None):
'''Get favorites tracks (not only for user)'''
2022-11-15 03:22:32 +02:00
params = {
2022-12-18 03:02:53 +02:00
'page': page,
'q': q,
'scope': scope,
'include_channels': include_channels
2022-11-15 03:22:32 +02:00
}
if pg:
2022-12-04 03:01:11 +02:00
r = current_instance.s.get(pg)
2022-11-15 03:22:32 +02:00
else:
2022-12-18 03:02:53 +02:00
r = current_instance.s.get(
f'https://{current_instance.instance}/api/v1/favorites/tracks/', params=params)
2022-11-15 03:22:32 +02:00
return r.json()
@logger.catch
def get_recently_listened(page=None, q=None, scope=None, include_channels=None, pg=None):
'''Get recently listened tracks (not only for user)'''
params = {
'page': page,
'q': q,
'scope': scope,
'include_channels': include_channels
}
if pg:
r = current_instance.s.get(pg)
else:
r = current_instance.s.get(
f'https://{current_instance.instance}/api/v1/history/listenings', params=params)
return r.json()
2022-11-08 19:58:27 +02:00
@logger.catch
2023-06-18 01:34:02 +03:00
def get_artists(page=None, q=None, artist=None, album=None, tag=None,
2023-06-12 14:30:49 +03:00
library=None, scope=None, favourites=None, refresh=False, pg=None):
2022-11-08 19:58:27 +02:00
'''This function get artists by params'''
params = {
2022-12-18 03:02:53 +02:00
'page': page,
'q': q,
'artist': artist,
'album': album,
2023-06-18 01:34:02 +03:00
'tag': tag,
'library': library,
2023-06-12 14:30:49 +03:00
'scope': scope,
2022-12-18 03:02:53 +02:00
'favourites': favourites,
'refresh': refresh
2022-11-08 19:58:27 +02:00
}
if pg:
2022-12-04 03:01:11 +02:00
r = current_instance.s.get(pg)
2022-11-08 19:58:27 +02:00
else:
2022-12-18 03:02:53 +02:00
r = current_instance.s.get(
f'https://{current_instance.instance}/api/v1/artists', params=params)
return r.json()
2022-11-08 19:58:27 +02:00
@logger.catch
def get_albums(page=None, q=None, ordering=None,
artist=None, library=None, include_channels=None, refresh=False, pg=None):
2022-11-08 19:58:27 +02:00
'''This function get artists by params'''
params = {
2022-12-18 03:02:53 +02:00
'page': page,
'ordering': ordering,
2022-12-18 03:02:53 +02:00
'q': q,
'artist': artist,
'library': library,
2022-12-18 03:02:53 +02:00
'include_channels': include_channels,
'refresh': refresh
2022-11-08 19:58:27 +02:00
}
if pg:
2022-12-04 03:01:11 +02:00
r = current_instance.s.get(pg)
2022-11-08 19:58:27 +02:00
else:
2022-12-18 03:02:53 +02:00
r = current_instance.s.get(
f'https://{current_instance.instance}/api/v1/albums', params=params)
2022-11-08 19:58:27 +02:00
return r.json()
@logger.catch
def get_channels(page=None, q=None, tag=None, pg=None):
params = {
2022-12-18 03:02:53 +02:00
'page': page,
'q': q,
'tag': tag
}
if pg:
2022-12-04 03:01:11 +02:00
r = current_instance.s.get(pg)
else:
2022-12-18 03:02:53 +02:00
r = current_instance.s.get(
f'https://{current_instance.instance}/api/v1/channels', params=params)
return r.json()
2022-11-10 17:55:36 +02:00
@logger.catch
def get_playlists(page=None, page_size=None, q=None, ordering='-modification_date', pg=None):
2022-11-10 17:55:36 +02:00
'''List playlists'''
params = {
2022-12-18 03:02:53 +02:00
'page': page,
'page_size': page_size,
'q': q,
'ordering': ordering
2022-11-10 17:55:36 +02:00
}
if pg:
2022-12-04 03:01:11 +02:00
r = current_instance.s.get(pg)
2022-11-10 17:55:36 +02:00
else:
2022-12-18 03:02:53 +02:00
r = current_instance.s.get(
f'https://{current_instance.instance}/api/v1/playlists', params=params)
2022-11-10 17:55:36 +02:00
r.raise_for_status()
return r.json()
@logger.catch
def get_playlist_tracks(playlist_id, pg=None):
'''Retrieve all tracks in the playlist'''
if pg:
2022-12-04 03:01:11 +02:00
r = current_instance.s.get(pg)
2022-11-10 17:55:36 +02:00
else:
2022-12-18 03:02:53 +02:00
r = current_instance.s.get(
f'https://{current_instance.instance}/api/v1/playlists/{playlist_id}/tracks')
2022-11-10 17:55:36 +02:00
return r.json()
@logger.catch
def list_libraries(page=None, page_size=None, q=None, scope='all', pg=None):
2022-11-08 02:29:44 +02:00
params = {
2022-12-18 03:02:53 +02:00
'page': page,
'page_size': page_size,
'q': q,
'scope': scope,
2022-11-08 02:29:44 +02:00
}
if pg:
2022-12-04 03:01:11 +02:00
r = current_instance.s.get(pg)
else:
2022-12-18 03:02:53 +02:00
r = current_instance.s.get(
f'https://{current_instance.instance}/api/v1/libraries', params=params)
2022-11-08 02:29:44 +02:00
return r.json()
2022-12-18 03:02:53 +02:00
2023-08-03 00:18:48 +03:00
@logger.catch
def assigned_libraries_on_track(track_id, page=None, page_size=None, pg=None):
params = {
'page': page,
'page_size': page_size,
}
if pg:
r = current_instance.s.get(pg)
else:
r = current_instance.s.get(
f'https://{current_instance.instance}/api/v1/tracks/{track_id}/libraries', params=params)
return r.json()
2022-11-30 02:17:18 +02:00
@logger.catch
2023-06-17 23:44:32 +03:00
def get_tags(q=None, ordering='-creation_date', pg=None):
2022-11-30 02:17:18 +02:00
params = {
2022-12-18 03:02:53 +02:00
'q': q,
2023-06-17 23:44:32 +03:00
'ordering': ordering
2022-11-30 02:17:18 +02:00
}
if pg:
2022-12-04 03:01:11 +02:00
r = current_instance.s.get(pg)
2022-11-30 02:17:18 +02:00
else:
2022-12-18 03:02:53 +02:00
r = current_instance.s.get(
f'https://{current_instance.instance}/api/v1/tags', params=params)
2022-11-30 02:17:18 +02:00
return r.json()
2022-11-08 02:29:44 +02:00
@logger.catch
def federate_search_by_url(object):
params = {
2022-12-18 03:02:53 +02:00
'object': object
}
2023-02-06 01:01:53 +02:00
for i in range(attempts_for_federate):
try:
r = current_instance.s.post(
f'https://{current_instance.instance}/api/v1/federation/fetches', json=params)
r.raise_for_status()
break
except Exception as Err:
logger.error(f'Attempt {i}: {Err}')
time.sleep(3)
return r.json()
2022-12-18 03:02:53 +02:00
@logger.catch
def federate_remote_library(fid):
'''Fetch remote library for follow and scan'''
params = {
'fid': fid
}
2023-02-06 01:01:53 +02:00
for i in range(attempts_for_federate):
try:
r = current_instance.s.post(
f'https://{current_instance.instance}/api/v1/federation/libraries/fetch', json=params)
r.raise_for_status()
break
except Exception as Err:
logger.error(f'Attempt {i}: {Err}')
time.sleep(3)
return r.json()
@logger.catch
def scan_remote_library(uuid):
2023-02-06 01:01:53 +02:00
for i in range(attempts_for_federate):
try:
r = current_instance.s.post(
f'https://{current_instance.instance}/api/v1/federation/libraries/{uuid}/scan')
2023-02-06 01:01:53 +02:00
r.raise_for_status()
break
except Exception as Err:
logger.error(f'Attempt {i}: {Err}')
time.sleep(3)
return r.json()
@logger.catch
def follow_on_remote_library(uuid):
params = {'target': uuid}
for i in range(attempts_for_federate):
try:
r = current_instance.s.post(
f'https://{current_instance.instance}/api/v1/federation/follows/library/',
json=params)
r.raise_for_status()
break
except Exception as Err:
logger.error(f'Attempt follow {i}: {Err}')
time.sleep(3)
return r.json()
@logger.catch
def unfollow_remote_library(uuid):
r = current_instance.s.delete(
f'https://{current_instance.instance}/api/v1/federation/follows/library/{uuid}/')
r.raise_for_status()
return r.json()
@logger.catch
def record_track_in_history(track_id):
params = {
2022-12-18 03:02:53 +02:00
'track': int(track_id)
}
2022-12-18 03:02:53 +02:00
r = current_instance.s.post(
f'https://{current_instance.instance}/api/v1/history/listenings', json=params)
r.raise_for_status()
return r.json
2022-12-18 03:02:53 +02:00
2022-11-08 21:23:19 +02:00
@logger.catch
def favorite_track(track_id):
2022-12-18 03:02:53 +02:00
r = current_instance.s.post(
f'https://{current_instance.instance}/api/v1/favorites/tracks', json={'track': int(track_id)})
2022-11-08 21:23:19 +02:00
r.raise_for_status()
return r.json
@logger.catch
def unfavorite_track(track_id):
2022-12-18 03:02:53 +02:00
r = current_instance.s.post(
f'https://{current_instance.instance}/api/v1/favorites/tracks/delete', json={'track': int(track_id)})
2022-11-08 21:23:19 +02:00
r.raise_for_status()
2022-12-18 03:02:53 +02:00
return r.json
2022-11-08 21:23:19 +02:00
@logger.catch
def hide_content(content):
'''This function hide content (write permission)'''
2022-12-18 03:02:53 +02:00
r = current_instance.s.post(
f'https://{current_instance.instance}/api/v1/moderation/content-filters/', json=content)
2022-11-08 21:23:19 +02:00
r.raise_for_status()
return r.json
2022-11-01 12:15:28 +02:00
# [FunkWhale radios]
def get_radios():
2022-12-18 03:02:53 +02:00
r = current_instance.s.get(
f'https://{current_instance.instance}/api/v1/radios/radios/')
2022-11-01 12:15:28 +02:00
return r.json()
def post_radio_session(requested_radio):
2022-12-18 03:02:53 +02:00
r = current_instance.s.post(
f'https://{current_instance.instance}/api/v1/radios/sessions/', json=requested_radio)
2022-11-01 12:15:28 +02:00
return r.json()
@logger.catch
2022-11-01 12:15:28 +02:00
def get_track_radio(radio_session):
2022-12-18 03:02:53 +02:00
r = current_instance.s.post(
f'https://{current_instance.instance}/api/v1/radios/tracks/', json=radio_session)
return r.json()