Add json output flag (#139)

This commit is contained in:
Dave G
2022-07-05 00:11:00 -04:00
committed by GitHub
parent 3df07dc65e
commit 260ef74d4e
7 changed files with 148 additions and 57 deletions

View File

@@ -65,7 +65,7 @@ def get_posts(post):
Args:
post (str): either full url or postid
Yields:
Returns:
list(Post): Posts
"""
if is_valid_url(post):
@@ -81,22 +81,28 @@ def get_posts(post):
total_pages = response.json().get("pager").get("total_pages")
posts = []
for page in range(0, total_pages + 1):
response = requests.get(
f"{API_BASE_URL}/api/topics/{post_id}/posts?per_page=40&page={page}"
)
users = create_user_map(response.json().get("users"))
posts = response.json().get("posts")
current_posts = response.json().get("posts")
for i in posts:
for _post in current_posts:
# Sometimes votes is null
if i.get("votes") is not None:
calculated_score = calculate_score(i)
if _post.get("votes") is not None:
calculated_score = calculate_score(_post)
else:
calculated_score = 0
yield Post(
body=strip_html(i.get("body")),
score=calculated_score,
user=users[i.get("author_id")],
posts.append(
Post(
body=strip_html(_post.get("body")),
score=calculated_score,
user=users[_post.get("author_id")],
)
)
return posts

View File

@@ -3,6 +3,7 @@ from __future__ import unicode_literals
import logging
import sys
import json
import click
try:
@@ -11,8 +12,14 @@ except ImportError: # for Python<3.8
import importlib_metadata as metadata
from colorama import init
from .api import get_threads, get_posts
from .threads import parse_threads, search_threads, sort_threads, generate_thread_output
from .posts import generate_posts_output
from .threads import (
parse_threads,
search_threads,
sort_threads,
generate_thread_output,
ThreadEncoder,
)
from .posts import generate_posts_output, PostEncoder
init()
@@ -51,7 +58,10 @@ def cli(ctx):
@cli.command(short_help="Display all posts in a thread.")
@click.argument("post_id")
def posts(post_id):
@click.option(
"--output", default=None, help="Defaults to custom formatting. Other options: json"
)
def posts(post_id, output):
"""Iterate all pages and display all posts in a thread.
post_id can be a full url or post id only
@@ -63,12 +73,23 @@ def posts(post_id):
"""
try:
click.echo_via_pager(generate_posts_output(get_posts(post=post_id)))
if output == "json":
click.echo_via_pager(
json.dumps(
get_posts(post=post_id),
cls=PostEncoder,
indent=2,
sort_keys=True,
)
)
else:
click.echo_via_pager(generate_posts_output(get_posts(post=post_id)))
except ValueError:
click.echo("Invalid post id.")
sys.exit(1)
except AttributeError:
click.echo("The RFD API did not return the expected data.")
except AttributeError as err:
click.echo("The RFD API did not return the expected data. %s", err)
sys.exit(1)
@@ -76,7 +97,10 @@ def posts(post_id):
@click.option("--forum-id", default=9, help="The forum id number")
@click.option("--pages", default=1, help="Number of pages to show. Defaults to 1.")
@click.option("--sort-by", default=None, help="Sort threads by")
def threads(forum_id, pages, sort_by):
@click.option(
"--output", default=None, help="Defaults to custom formatting. Other options: json"
)
def threads(forum_id, pages, sort_by, output):
"""Display threads in the specified forum id. Defaults to 9 (hot deals).
Popular forum ids:
@@ -96,7 +120,18 @@ def threads(forum_id, pages, sort_by):
_threads = sort_threads(
parse_threads(get_threads(forum_id, pages)), sort_by=sort_by
)
click.echo_via_pager(generate_thread_output(_threads))
if output == "json":
click.echo_via_pager(
json.dumps(
sort_threads(_threads, sort_by=sort_by),
cls=ThreadEncoder,
indent=2,
sort_keys=True,
)
)
else:
click.echo_via_pager(generate_thread_output(_threads))
@cli.command(short_help="Search deals based on a regular expression.")
@@ -105,8 +140,11 @@ def threads(forum_id, pages, sort_by):
"--forum-id", default=9, help="The forum id number. Defaults to 9 (hot deals)."
)
@click.option("--sort-by", default=None, help="Sort threads by")
@click.option(
"--output", default=None, help="Defaults to custom formatting. Other options: json"
)
@click.argument("regex")
def search(pages, forum_id, sort_by, regex):
def search(pages, forum_id, sort_by, output, regex):
"""Search deals based on regex.
Popular forum ids:
@@ -129,6 +167,17 @@ def search(pages, forum_id, sort_by, regex):
_threads = parse_threads(get_threads(forum_id, pages=pages))
for thread in search_threads(threads=_threads, regex=regex):
matched_threads.append(thread)
click.echo_via_pager(
generate_thread_output(sort_threads(matched_threads, sort_by=sort_by))
)
if output == "json":
click.echo_via_pager(
json.dumps(
sort_threads(matched_threads, sort_by=sort_by),
indent=2,
sort_keys=True,
cls=ThreadEncoder,
)
)
else:
click.echo_via_pager(
generate_thread_output(sort_threads(matched_threads, sort_by=sort_by))
)

View File

@@ -1,5 +1,6 @@
# pylint: disable=old-style-class
import os
import json
from colorama import Fore, Style
from .scores import get_vote_color
@@ -11,6 +12,17 @@ class Post:
self.user = user
class PostEncoder(json.JSONEncoder):
def default(self, o):
if isinstance(o, Post):
return dict(
body=o.body,
score=o.score,
user=o.user,
)
return json.JSONEncoder.default(self, o)
def get_terminal_width():
_, columns = os.popen("stty size", "r").read().split()
return int(columns)

View File

@@ -1,4 +1,5 @@
import re
import json
from colorama import Fore, Style
from . import API_BASE_URL
from .scores import calculate_score, get_vote_color
@@ -16,6 +17,19 @@ class Thread:
return f"Thread({self.title})"
class ThreadEncoder(json.JSONEncoder):
def default(self, o):
if isinstance(o, Thread):
return dict(
dealer_name=o.dealer_name,
score=o.score,
title=o.title,
url=o.url,
views=o.views,
)
return json.JSONEncoder.default(self, o)
def build_web_path(slug):
return f"{API_BASE_URL}{slug}"