From 4f1ecbd83c3cf07face0a2a8baf2da66d864ed76 Mon Sep 17 00:00:00 2001 From: Quentin Dauchy Date: Tue, 14 Aug 2018 18:04:22 +0200 Subject: [PATCH 1/3] Add fixes suggested in comments --- fediplay/cli.py | 5 +++-- fediplay/mastodon.py | 18 +++++++++++++++--- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/fediplay/cli.py b/fediplay/cli.py index a704aa2..6f889c3 100644 --- a/fediplay/cli.py +++ b/fediplay/cli.py @@ -79,10 +79,11 @@ def login(instance): @cli.command() @click.argument('instance') -def stream(instance): +@click.argument('users', nargs=-1) +def stream(instance, users): '''Stream music from your timeline.''' client_id, client_secret = get_client_credentials(instance) access_token = get_access_token(instance) - mastodon.stream(instance, client_id, client_secret, access_token, cache_dir=DIRS.user_cache_dir) + mastodon.stream(instance, users, client_id, client_secret, access_token, cache_dir=DIRS.user_cache_dir) diff --git a/fediplay/mastodon.py b/fediplay/mastodon.py index 2347ec1..09eb5d6 100644 --- a/fediplay/mastodon.py +++ b/fediplay/mastodon.py @@ -21,10 +21,13 @@ def api_base_url(instance): class StreamListener(mastodon.StreamListener): '''Listens to a Mastodon timeline and adds links the given Queue.''' - def __init__(self, queue): + def __init__(self, queue, users): self.queue = queue + self.users = users def on_update(self, status): + if self.users and status.account.username not in self.users: + return tags = extract_tags(status) if 'fediplay' in tags: links = extract_links(status) @@ -61,11 +64,12 @@ def login(instance, client_id, client_secret, grant_code): access_token = client.log_in(code=grant_code, scopes=['read']) keyring.set_credential(instance, keyring.CREDENTIAL_ACCESS_TOKEN, access_token) -def stream(instance, client_id, client_secret, access_token, cache_dir='.'): +def stream(instance, users, client_id, client_secret, access_token, cache_dir='.'): '''Stream statuses and add them to a queue.''' client = build_client(instance, client_id, client_secret, access_token) - listener = StreamListener(Queue(cache_dir)) + users = [normalize_username(u, instance) for u in users] + listener = StreamListener(Queue(cache_dir), users) click.echo('==> Streaming from {}'.format(instance)) client.stream_user(listener) @@ -74,6 +78,14 @@ def extract_tags(toot): return [tag['name'] for tag in toot['tags']] +def normalize_username(user, instance): + # If user was specified with an @ at beggining, remove it + user = user.lstrip('@') + tmp = user.split('@') + # remove instance if it is our own instance + return user if (len(tmp) == 1 or tmp[1] != instance) else tmp[0] + + def link_is_internal(link): '''Determines if a link is internal to the Mastodon instance.''' From 1488ceb964febc9fdbc16d56ae3103c7b4ec9bfe Mon Sep 17 00:00:00 2001 From: Matt Behrens Date: Mon, 22 Oct 2018 18:44:23 -0400 Subject: [PATCH 2/3] debug support --- fediplay/cli.py | 7 ++++++- fediplay/mastodon.py | 13 +++++++++++-- fediplay/queue.py | 9 ++++++++- 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/fediplay/cli.py b/fediplay/cli.py index 6f889c3..3a0d238 100644 --- a/fediplay/cli.py +++ b/fediplay/cli.py @@ -1,5 +1,7 @@ '''Entry point for command-line interface.''' +options = {'debug': False} + import os path = os.path import sys @@ -49,9 +51,12 @@ def get_client_credentials(instance): ) @click.group() -def cli(): +@click.option('-d', '--debug', is_flag=True, help='Print debug messages.') +def cli(debug): '''A program to play music your friends post on Mastodon.''' + options['debug'] = debug + ensure_dirs() @cli.command() diff --git a/fediplay/mastodon.py b/fediplay/mastodon.py index 09eb5d6..28e2db9 100644 --- a/fediplay/mastodon.py +++ b/fediplay/mastodon.py @@ -7,6 +7,7 @@ from lxml.etree import HTML # pylint: disable=no-name-in-module import mastodon from youtube_dl.utils import DownloadError +from fediplay.cli import options import fediplay.keyring as keyring from fediplay.queue import Queue @@ -25,9 +26,18 @@ class StreamListener(mastodon.StreamListener): self.queue = queue self.users = users + if options['debug']: + print('listener initialized with users={}'.format(self.users)) + def on_update(self, status): + if options['debug']: + print('incoming toot: username={}'.format(status.account.username)) + if self.users and status.account.username not in self.users: + if options['debug']: + print('skipping toot due to username filtering') return + tags = extract_tags(status) if 'fediplay' in tags: links = extract_links(status) @@ -68,7 +78,7 @@ def stream(instance, users, client_id, client_secret, access_token, cache_dir='. '''Stream statuses and add them to a queue.''' client = build_client(instance, client_id, client_secret, access_token) - users = [normalize_username(u, instance) for u in users] + users = [normalize_username(user, instance) for user in users] listener = StreamListener(Queue(cache_dir), users) click.echo('==> Streaming from {}'.format(instance)) client.stream_user(listener) @@ -85,7 +95,6 @@ def normalize_username(user, instance): # remove instance if it is our own instance return user if (len(tmp) == 1 or tmp[1] != instance) else tmp[0] - def link_is_internal(link): '''Determines if a link is internal to the Mastodon instance.''' diff --git a/fediplay/queue.py b/fediplay/queue.py index ffc5d06..6b06805 100644 --- a/fediplay/queue.py +++ b/fediplay/queue.py @@ -8,6 +8,7 @@ from threading import Thread, Lock import click from youtube_dl import YoutubeDL, utils +from fediplay.cli import options import fediplay.env as env @@ -62,7 +63,13 @@ class Getter(object): self.cache_dir = cache_dir def _progress_hook(self, progress): - if progress['status'] == 'downloading' and progress['filename'] not in self.filenames: + if options['debug']: + print('progress hook: status {}, filename {}'.format( + progress['status'], progress['filename'] + )) + + if (progress['status'] == 'downloading' and + progress['filename'] not in self.filenames): self.filenames.append(progress['filename']) def get(self, url): From 4f1521f286b5b72eaeaa91c602cabd7528977176 Mon Sep 17 00:00:00 2001 From: Matt Behrens Date: Mon, 22 Oct 2018 19:04:21 -0400 Subject: [PATCH 3/3] fix username filtering, cache play (fixes #21) --- fediplay/mastodon.py | 22 ++++++++++++++-------- fediplay/queue.py | 4 ++-- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/fediplay/mastodon.py b/fediplay/mastodon.py index 28e2db9..20a3e3e 100644 --- a/fediplay/mastodon.py +++ b/fediplay/mastodon.py @@ -22,8 +22,9 @@ def api_base_url(instance): class StreamListener(mastodon.StreamListener): '''Listens to a Mastodon timeline and adds links the given Queue.''' - def __init__(self, queue, users): + def __init__(self, queue, instance, users): self.queue = queue + self.instance = instance self.users = users if options['debug']: @@ -31,9 +32,10 @@ class StreamListener(mastodon.StreamListener): def on_update(self, status): if options['debug']: - print('incoming toot: username={}'.format(status.account.username)) + print('status: {}'.format(repr(status))) + print('incoming toot: username={}'.format(status.account.acct)) - if self.users and status.account.username not in self.users: + if self.users and normalize_username(status.account.acct, self.instance) not in self.users: if options['debug']: print('skipping toot due to username filtering') return @@ -79,7 +81,7 @@ def stream(instance, users, client_id, client_secret, access_token, cache_dir='. client = build_client(instance, client_id, client_secret, access_token) users = [normalize_username(user, instance) for user in users] - listener = StreamListener(Queue(cache_dir), users) + listener = StreamListener(Queue(cache_dir), instance, users) click.echo('==> Streaming from {}'.format(instance)) client.stream_user(listener) @@ -89,11 +91,15 @@ def extract_tags(toot): return [tag['name'] for tag in toot['tags']] def normalize_username(user, instance): - # If user was specified with an @ at beggining, remove it user = user.lstrip('@') - tmp = user.split('@') - # remove instance if it is our own instance - return user if (len(tmp) == 1 or tmp[1] != instance) else tmp[0] + parts = user.split('@') + if options['debug']: + print('parts: {}'.format(repr(parts))) + + if len(parts) == 1 or parts[1] == instance: + return parts[0] + else: + return user def link_is_internal(link): '''Determines if a link is internal to the Mastodon instance.''' diff --git a/fediplay/queue.py b/fediplay/queue.py index 6b06805..0417715 100644 --- a/fediplay/queue.py +++ b/fediplay/queue.py @@ -65,10 +65,10 @@ class Getter(object): def _progress_hook(self, progress): if options['debug']: print('progress hook: status {}, filename {}'.format( - progress['status'], progress['filename'] + repr(progress['status']), repr(progress['filename']) )) - if (progress['status'] == 'downloading' and + if (progress['status'] in ('downloading', 'finished') and progress['filename'] not in self.filenames): self.filenames.append(progress['filename'])