Skip to content
Snippets Groups Projects
Verified Commit 9f8ce428 authored by Eliot Berriot's avatar Eliot Berriot
Browse files

Support for listing, adding and removing channels

parent 3f2513ec
No related branches found
No related tags found
No related merge requests found
from . import auth
from . import albums
from . import artists
from . import channels
from . import favorites
from . import libraries
from . import playlists
......@@ -14,6 +15,7 @@ __all__ = [
"auth",
"albums",
"artists",
"channels",
"favorites",
"libraries",
"playlists",
......
......@@ -135,6 +135,14 @@ def async_command(f):
return functools.update_wrapper(wrapper, f)
async def check_status(response):
text = await response.text()
try:
response.raise_for_status()
except aiohttp.client_exceptions.ClientError as e:
raise click.ClickException(str(e) + ": {}".format(text))
SERVER_DECORATOR = click.option(
"-H",
"--url",
......@@ -240,6 +248,7 @@ def get_ls_command(
pagination=True,
filter=True,
ordering=True,
scope=False,
with_id=False,
owned_conf=None,
name="ls",
......@@ -271,6 +280,8 @@ def get_ls_command(
ordering_decorator = (
click.option("--ordering", "-o", default=None) if ordering else noop_decorator
)
scope_decorator = click.option("--scope", default=None) if scope else noop_decorator
filter_decorator = (
click.option("--filter", "-f", multiple=True) if filter else noop_decorator
)
......@@ -291,6 +302,7 @@ def get_ls_command(
@page_decorator
@page_size_decorator
@ordering_decorator
@scope_decorator
@filter_decorator
@limit_decorator
@owned_decorator
......@@ -310,6 +322,7 @@ def get_ls_command(
page = kwargs.get("page")
page_size = kwargs.get("page_size")
ordering = kwargs.get("ordering")
scope = kwargs.get("scope")
filter = kwargs.get("filter")
query = kwargs.get("query")
owned = kwargs.get("owned")
......@@ -335,6 +348,8 @@ def get_ls_command(
params["page_size"] = page_size
if ordering:
params["ordering"] = ordering
if scope:
params["scope"] = scope
if query:
params["q"] = " ".join(query)
if filter:
......
import click
import json
from . import base
from .. import output
@base.cli.group()
@click.pass_context
def channels(ctx):
"""
Manage channels
"""
channels_ls = base.get_ls_command(
channels,
"api/v1/channels/",
scope=True,
output_conf={
"labels": ["UUID", "Name", "Category", "Username", "Tags"],
"type": "CHANNEL",
},
)
channels_rm = base.get_delete_command(channels, "api/v1/channels/{}/")
@channels.command("create")
@click.option("--name", prompt=True)
@click.option("--username", prompt=True)
@click.option("--cover")
@click.option("--description")
@click.option("--tags", default="")
@click.option("--itunes-category", default=None)
@click.option("--language", default=None)
@click.option(
"--content-category",
type=click.Choice(["music", "podcast", "other"]),
default="podcast",
prompt=True,
)
@click.option("--raw", is_flag=True)
@click.pass_context
@base.async_command
async def channels_create(
ctx,
raw,
name,
username,
cover,
description,
tags,
language,
itunes_category,
content_category,
):
data = {
"name": name,
"username": username,
"content_category": content_category,
}
if description:
data["description"] = {
"text": description,
"content_type": "text/markdown",
}
else:
data["description"] = None
if cover:
data["cover"] = cover
missing_fields = []
if not itunes_category:
missing_fields.append(("--itunes-category", "itunes_category"))
if not language:
missing_fields.append(("--language", "language"))
if content_category == "podcast" and missing_fields:
click.secho(
"You must provide adequate values for these fields: {}. Allowed values are listed below".format(
", ".join([f for f, _ in missing_fields])
),
fg="red",
)
async with ctx.obj["remote"]:
result = await ctx.obj["remote"].request(
"get", "api/v1/channels/metadata-choices"
)
choices = await result.json()
for flag, field in missing_fields:
click.echo(
"{}: {}".format(flag, ", ".join([c["value"] for c in choices[field]]))
)
raise click.ClickException("Missing params")
data["tags"] = [t.strip() for t in tags.replace(" ", ",").split(",") if t]
if content_category == "podcast":
data["metadata"] = {
"itunes_category": itunes_category,
"language": language,
}
async with ctx.obj["remote"]:
result = await ctx.obj["remote"].request("post", "api/v1/channels/", json=data)
await base.check_status(result)
payload = await result.json()
if raw:
click.echo(json.dumps(payload, sort_keys=True, indent=4))
else:
click.echo("Channel created:")
click.echo(
output.table(
[payload], ["UUID", "Name", "Category", "Username"], type="CHANNEL"
)
)
import tabulate
def comma_separated(it):
return ", ".join(it)
FIELDS = {
"ARTIST": {
"ID": {"field": "id", "truncate": 0},
......@@ -19,6 +23,16 @@ FIELDS = {
"Tracks": {"field": "tracks", "handler": lambda v: len(v), "truncate": 0},
"Artist": {"field": "artist.name"},
},
"CHANNEL": {
"Category": {"field": "artist.content_category", "truncate": 0},
"Username": {"field": "actor.full_username", "truncate": 0},
"Name": {"field": "artist.name"},
"Descsription": {"field": "artist.description.text"},
"RSS URL": {"field": "rss_url"},
"Artist": {"field": "artist.id"},
"Metadata": {"field": "metadata"},
"Tags": {"field": "artist.tags", "handler": ", ".join,},
},
"TRACK": {
"ID": {"field": "id", "truncate": 0},
"Title": {"field": "title"},
......@@ -75,6 +89,7 @@ FIELDS = {
"Modified": {"field": "modification_date"},
"UUID": {"field": "uuid", "truncate": 0},
"ID": {"field": "id", "truncate": 0},
"Tags": {"field": "tags", "handler": ", ".join,},
},
}
......
......@@ -467,3 +467,105 @@ def test_playlists_tracks(cli_ctx, session, responses, get_requests):
requests = get_requests("get", url)
assert len(requests) == 1
def test_channel_create_music(cli_ctx, session, responses, get_requests):
command = cli.channels.channels_create
url = "https://test.funkwhale/api/v1/channels/"
responses.post(url)
command.callback(
name="test",
cover="uuid",
username="hello",
content_category="music",
description="description text",
tags='punk,rock, ska',
language=None,
itunes_category=None,
raw=False,
_async_reraise=True
)
requests = get_requests("post", url)
assert len(requests) == 1
assert requests[0].kwargs["json"] == {
"name": "test",
"cover": "uuid",
"username": "hello",
"content_category": "music",
"description": {"text": "description text", "content_type": "text/markdown"},
"tags": ["punk", "rock", "ska"],
}
def test_channel_create_podcast(cli_ctx, session, responses, get_requests):
command = cli.channels.channels_create
url = "https://test.funkwhale/api/v1/channels/"
responses.post(url)
command.callback(
name="test",
cover="uuid",
username="hello",
content_category="podcast",
description="description text",
tags='punk,rock, ska',
language="en",
itunes_category="Leisure",
raw=False,
_async_reraise=True
)
requests = get_requests("post", url)
assert len(requests) == 1
assert requests[0].kwargs["json"] == {
"name": "test",
"cover": "uuid",
"username": "hello",
"content_category": "podcast",
"description": {"text": "description text", "content_type": "text/markdown"},
"tags": ["punk", "rock", "ska"],
"metadata": {
"itunes_category": "Leisure",
"language": "en",
}
}
def test_channels_ls(cli_ctx, session, responses, get_requests):
command = cli.channels.channels_ls
url = "https://test.funkwhale/api/v1/channels/?ordering=-creation_date&page=1&page_size=5&q=hello&scope=me"
responses.get(
url, payload={"results": [], "next": None, "previous": None, "count": 0}
)
command.callback(
raw=False,
page=1,
page_size=5,
ordering="-creation_date",
filter="subscribed=true",
scope="me",
query=["hello"],
column=None,
format=None,
no_headers=False,
ids=False,
limit=1,
)
requests = get_requests("get", url)
assert len(requests) == 1
def test_channels_rm(cli_ctx, session, responses, get_requests):
command = cli.channels.channels_rm
url = "https://test.funkwhale/api/v1/channels/"
responses.delete(url + "uuid1/")
responses.delete(url + "uuid2/")
command.callback(id=["uuid1", "uuid2"], raw=False, no_input=True, _async_reraise=True)
assert len(get_requests("delete", url + "uuid1/")) == 1
assert len(get_requests("delete", url + "uuid2/")) == 1
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment