mirror of
https://github.com/davegallant/rfd.git
synced 2025-08-07 00:58:14 +00:00
3
.gitignore
vendored
3
.gitignore
vendored
@@ -5,5 +5,4 @@
|
|||||||
.pytest_cache/
|
.pytest_cache/
|
||||||
build/
|
build/
|
||||||
dist/
|
dist/
|
||||||
venv/
|
venv/
|
||||||
setup.py
|
|
@@ -61,7 +61,6 @@ disable=
|
|||||||
protected-access,
|
protected-access,
|
||||||
too-few-public-methods,
|
too-few-public-methods,
|
||||||
|
|
||||||
|
|
||||||
[LOGGING]
|
[LOGGING]
|
||||||
|
|
||||||
# Logging modules to check that the string format arguments are in logging
|
# Logging modules to check that the string format arguments are in logging
|
||||||
|
@@ -5,7 +5,7 @@ python:
|
|||||||
- "3.4"
|
- "3.4"
|
||||||
- "3.5"
|
- "3.5"
|
||||||
- "3.6"
|
- "3.6"
|
||||||
- "3.7-dev"
|
# - "3.7-dev"
|
||||||
install:
|
install:
|
||||||
- pip install tox-travis
|
- pip install tox-travis
|
||||||
script:
|
script:
|
||||||
|
43
README.rst
43
README.rst
@@ -6,12 +6,51 @@ RFD CLI
|
|||||||
|
|
||||||
|
|
||||||
Installation:
|
Installation:
|
||||||
|
=============
|
||||||
|
|
||||||
|
.. code-block::
|
||||||
|
|
||||||
pip install rfd
|
pip install rfd
|
||||||
|
|
||||||
Usage
|
Usage
|
||||||
|
=====
|
||||||
|
|
||||||
rfd threads 9 --count 10
|
.. code-block::
|
||||||
|
|
||||||
|
|
||||||
.. image:: images/rfd_threads_9.png
|
rfd threads 9 [--count 5]
|
||||||
|
|
||||||
|
|
||||||
|
.. image:: https://user-images.githubusercontent.com/4519234/37319853-3a03fb9c-2647-11e8-806e-17156541cf43.png
|
||||||
|
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
=========
|
||||||
|
|
||||||
|
|
||||||
|
tail a post:
|
||||||
|
---------------
|
||||||
|
|
||||||
|
.. code-block::
|
||||||
|
|
||||||
|
|
||||||
|
▶ rfd posts https://forums.redflagdeals.com/koodo-targeted-public-mobile-12-120-koodo-6gb-40-no-referrals-2176935/ --tail 4
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
- [0] For those worried about credit ratings, according to Boworell, my credit score rose by 44 points since last month. I did absolutely nothing except open 3 Koodo lines all with medium tabs and I paid off 1 in full the very next day (Shaner)
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
- [0] If we want to keep our PM plan but use the code to set up a spouse on the plan is that still okay?
|
||||||
|
I've read that the port can only be used once now, but does it matter which phone number is ported in? (kid_icarus)
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
- [0] blackboxvr6 wrote: ↑Mar 12th, 2018 2:13 pm
|
||||||
|
Legit 1st line on Wednesday, no shipping email yet...
|
||||||
|
|
||||||
|
|
||||||
|
Tuesday before noon and still waiting. (gardener28)
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
- [0] Ordered a SIM last Wednesday, haven't heard a peep from Koodo since the initial order confirmation e-mail. (DaJinx)
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
Binary file not shown.
Before Width: | Height: | Size: 386 KiB After Width: | Height: | Size: 348 KiB |
69
rfd/api.py
69
rfd/api.py
@@ -67,7 +67,16 @@ def get_threads(forum_id, limit):
|
|||||||
return threads[:limit]
|
return threads[:limit]
|
||||||
|
|
||||||
|
|
||||||
def get_posts(post, limit=5):
|
def get_posts(post, count=5, tail=False, per_page=40):
|
||||||
|
"""Retrieve posts from a thread.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
post (str): either post id or full url
|
||||||
|
count (int, optional): Description
|
||||||
|
|
||||||
|
Yields:
|
||||||
|
list(dict): body, score, and user
|
||||||
|
"""
|
||||||
if is_valid_url(post):
|
if is_valid_url(post):
|
||||||
post_id = extract_post_id(post)
|
post_id = extract_post_id(post)
|
||||||
elif is_int(post):
|
elif is_int(post):
|
||||||
@@ -75,28 +84,62 @@ def get_posts(post, limit=5):
|
|||||||
else:
|
else:
|
||||||
raise ValueError()
|
raise ValueError()
|
||||||
|
|
||||||
if limit == 0:
|
response = requests.get(
|
||||||
response = requests.get(
|
"https://forums.redflagdeals.com/api/topics/{}/posts?per_page=40&page=1".format(post_id))
|
||||||
"https://forums.redflagdeals.com/api/topics/{}/posts?per_page=40&page=1".format(post_id))
|
total_posts = response.json().get('pager').get('total')
|
||||||
pages = response.json().get('pager').get('total_pages')
|
total_pages = response.json().get('pager').get('total_pages')
|
||||||
elif limit > 40:
|
|
||||||
pages = ceil(limit / 40)
|
if count == 0:
|
||||||
|
pages = total_pages
|
||||||
|
if count > per_page:
|
||||||
|
if count > total_posts:
|
||||||
|
count = total_posts
|
||||||
|
pages = ceil(count / per_page)
|
||||||
else:
|
else:
|
||||||
pages = 1
|
if tail:
|
||||||
|
pages = total_pages
|
||||||
|
else:
|
||||||
|
pages = 1
|
||||||
|
|
||||||
|
if tail:
|
||||||
|
start_page = ceil((total_posts + 1 - count) / per_page)
|
||||||
|
start_post = (total_posts + 1 - count) % per_page
|
||||||
|
if start_post == 0:
|
||||||
|
start_post = per_page
|
||||||
|
else:
|
||||||
|
start_page, start_post = 0, 0
|
||||||
|
|
||||||
# Go through as many pages as necessary
|
# Go through as many pages as necessary
|
||||||
for page in range(pages):
|
for page in range(start_page, pages + 1):
|
||||||
page = page + 1 # page 0 causes issues
|
|
||||||
response = requests.get(
|
response = requests.get(
|
||||||
"https://forums.redflagdeals.com/api/topics/{}/posts?per_page={}&page={}".format(post_id,
|
"https://forums.redflagdeals.com/api/topics/{}/posts?per_page={}&page={}".format(post_id,
|
||||||
get_safe_per_page(
|
get_safe_per_page(
|
||||||
limit),
|
per_page),
|
||||||
page))
|
page))
|
||||||
|
|
||||||
users = users_to_dict(response.json().get('users'))
|
users = users_to_dict(response.json().get('users'))
|
||||||
for _post in response.json().get('posts'):
|
|
||||||
|
_posts = response.json().get('posts')
|
||||||
|
|
||||||
|
# Determine which post to start with (for --tail)
|
||||||
|
if page == start_page and not start_post == 0:
|
||||||
|
if tail:
|
||||||
|
_posts = _posts[start_post - 1:]
|
||||||
|
else:
|
||||||
|
_posts = _posts[:start_post]
|
||||||
|
|
||||||
|
for _post in _posts:
|
||||||
|
count -= 1
|
||||||
|
if count < 0:
|
||||||
|
return
|
||||||
|
# Sometimes votes is null
|
||||||
|
if _post.get('votes') is not None:
|
||||||
|
calculated_score = get_vote_score(_post.get('votes').get(
|
||||||
|
'total_up'), _post.get('votes').get('total_down'))
|
||||||
|
else:
|
||||||
|
calculated_score = 0
|
||||||
yield{
|
yield{
|
||||||
'body': strip_html(_post.get('body')),
|
'body': strip_html(_post.get('body')),
|
||||||
'score': get_vote_score(_post.get('votes').get('total_up'), _post.get('votes').get('total_down')),
|
'score': calculated_score,
|
||||||
'user': users[_post.get('author_id')],
|
'user': users[_post.get('author_id')],
|
||||||
}
|
}
|
||||||
|
@@ -28,9 +28,10 @@ def cli():
|
|||||||
|
|
||||||
|
|
||||||
@cli.command(short_help="Displays posts in a specific thread.")
|
@cli.command(short_help="Displays posts in a specific thread.")
|
||||||
@click.option('--count', default=5, help='Number of topics. 0 for all topics')
|
@click.option('--head', default=0, help='Number of topics. Default is 0, for all topics')
|
||||||
|
@click.option('--tail', default=0, help='Number of topics. Default is disabled. This will override head.')
|
||||||
@click.argument('post_id')
|
@click.argument('post_id')
|
||||||
def posts(count, post_id):
|
def posts(post_id, head, tail):
|
||||||
"""Displays posts in a specific thread.
|
"""Displays posts in a specific thread.
|
||||||
|
|
||||||
post_id can be a full url or post id only
|
post_id can be a full url or post id only
|
||||||
@@ -41,13 +42,23 @@ def posts(count, post_id):
|
|||||||
url: https://forums.redflagdeals.com/koodo-targeted-public-mobile-12-120-koodo-5gb-40-no-referrals-2173603
|
url: https://forums.redflagdeals.com/koodo-targeted-public-mobile-12-120-koodo-5gb-40-no-referrals-2173603
|
||||||
post_id: 2173603
|
post_id: 2173603
|
||||||
"""
|
"""
|
||||||
if count < 0:
|
if head < 0:
|
||||||
click.echo("Invalid count.")
|
click.echo("Invalid head.")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
if tail < 0:
|
||||||
|
click.echo("Invalid tail.")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# Tail overrides head
|
||||||
|
if tail > 0:
|
||||||
|
count = tail
|
||||||
|
else:
|
||||||
|
count = head
|
||||||
|
|
||||||
try:
|
try:
|
||||||
click.echo("-" * get_terminal_width())
|
click.echo("-" * get_terminal_width())
|
||||||
for post in get_posts(post_id, count):
|
for post in get_posts(post=post_id, count=count, tail=tail > 0):
|
||||||
click.echo(" -" + get_vote_color(post.get('score')) + Fore.RESET +
|
click.echo(" -" + get_vote_color(post.get('score')) + Fore.RESET +
|
||||||
post.get('body') + Fore.YELLOW + " ({})".format(post.get('user')))
|
post.get('body') + Fore.YELLOW + " ({})".format(post.get('user')))
|
||||||
click.echo(Style.RESET_ALL)
|
click.echo(Style.RESET_ALL)
|
||||||
|
36
setup.py
Normal file
36
setup.py
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
import io # for python2
|
||||||
|
from os import path
|
||||||
|
from setuptools import setup
|
||||||
|
|
||||||
|
|
||||||
|
here = path.abspath(path.dirname(__file__))
|
||||||
|
|
||||||
|
# Get the long description from the relevant file
|
||||||
|
with io.open(path.join(here, 'README.rst'), encoding='utf-8') as f:
|
||||||
|
long_description = f.read()
|
||||||
|
|
||||||
|
setup(
|
||||||
|
name='rfd',
|
||||||
|
version='0.0.5',
|
||||||
|
packages=['rfd'],
|
||||||
|
keywords='cli redflagdeals',
|
||||||
|
install_requires=[
|
||||||
|
'PyYAML>=3.11',
|
||||||
|
'beautifulsoup4>=4.6.0',
|
||||||
|
'click>=6.7',
|
||||||
|
'colorama>=0.3.9',
|
||||||
|
'pytest>=3.4.2',
|
||||||
|
'requests>=2.18.4'
|
||||||
|
],
|
||||||
|
url='https://github.com/davegallant/rfd_cli',
|
||||||
|
license='Apache License, Version 2.0',
|
||||||
|
author='Dave Gallant',
|
||||||
|
author_email='davegallant@gmail.com',
|
||||||
|
description='CLI for RedFlagDeals.com',
|
||||||
|
long_description=long_description,
|
||||||
|
entry_points={
|
||||||
|
'console_scripts': [
|
||||||
|
'rfd = rfd.rfd_cli:cli',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
Reference in New Issue
Block a user