diff --git a/README.md b/README.md index b8bce70..47965b5 100644 --- a/README.md +++ b/README.md @@ -4,24 +4,37 @@ Given a subreddit name and a keyword, RPST will return all posts from a specifie [![Upload Python Package](https://github.com/bellingcat/reddit-post-scraping-tool/actions/workflows/python-publish.yml/badge.svg)](https://github.com/rly0nheart/reddit-post-scraping-tool/actions/workflows/python-publish.yml) [![CodeQL](https://github.com/bellingcat/reddit-post-scraping-tool/actions/workflows/codeql.yml/badge.svg)](https://github.com/rly0nheart/reddit-post-scraping-tool/actions/workflows/codeql.yml) ![.Net](https://img.shields.io/badge/.NET-5C2D91?style=flat&logo=.net&logoColor=white) ![Python](https://img.shields.io/badge/python-3670A0?style=flat&logo=python&logoColor=ffdd54) # ✅ Features -## GUI +## *GUI* - [x] Dark mode (*Right-click*) - [x] Saves results to a JSON file (*Right-click*) - [x] Logs errors to a file +- [x] In-App feature to check for Updates -## CLI +## *CLI* - [x] Saves results to JSON (*specifiy* `--json`) - [x] Saves results to CSV (*specify* `--csv`) - [x] Automatically checks for new updates, and notifies user if updates were found. # 📃 TODO -## GUI +## *GUI* - [ ] Make it installable with a setup.exe/setup.msi file. - [x] Add manual dark mode option, that will be persistent in all sessions - [ ] Make it save results to a CSV file +# 🖥️ Tested environments +## *GUI* +- [x] Microsoft Windows 11 + +## *CLI* +- [x] Android Termux +- [x] Microsoft Windows 11 +- [x] Ubuntu 22.04 - latest versions + # 📖 Wiki [Refer to the Wiki](https://github.com/bellingcat/reddit-post-scraping-tool/wiki) for installation instructions, in addition to all other documentation. + +# 🖼️ Screenshots +You can view a collection of screenshots for both the *CLI* and *GUI* [here](https://github.com/bellingcat/reddit-post-scraping-tool/tree/master/images) *** diff --git a/RPST GUI/RPST/RPST.vbproj b/RPST GUI/RPST/RPST.vbproj index 4a1f375..a1e4aa7 100644 --- a/RPST GUI/RPST/RPST.vbproj +++ b/RPST GUI/RPST/RPST.vbproj @@ -13,11 +13,11 @@ https://github.com/bellingcat/reddit-post-scraping-tool README.md https://github.com/bellingcat/reddit-post-scraping-tool - 1.7.0.1 - 1.7.0.1 + 1.7.1.0 + 1.7.1.0 LICENSE True - 1.7.0 + 1.7.1 reddit;scraper;reddit-scraper;osint 6.0-recommended diff --git a/pyproject.toml b/pyproject.toml index bca19e5..76502f2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ packages = ["rpst"] [project] name = "reddit-post-scraping-tool" -version = "1.7.0.1" +version = "1.7.1.0" description = "Given a subreddit name and a keyword, RPST returns all top (by default) posts that contain the specified keyword." readme = "README.md" requires-python = ">=3.8" diff --git a/rpst/main.py b/rpst/main.py index d8dd5cf..616d743 100644 --- a/rpst/main.py +++ b/rpst/main.py @@ -14,20 +14,20 @@ def run(): parser = create_parser() args = parser.parse_args() - log = set_loglevel(args=args) + log = set_loglevel(debug_mode=args.debug) # Record the start time start_time = datetime.now() try: # Check for updates - check_updates(version_tag="1.7.0.1") + check_updates(version_tag="1.7.1.0") # Get posts with the provided/parsed arguments get_posts(args=args) except KeyboardInterrupt: - log.warning("User interruption detected.") + log.warning("User interruption detected ([yellow]Ctrl+C[/]).") except Exception as e: - log.error(f"An error occurred: {e}") + log.error(f"An error occurred: [red]{e}[/]") finally: log.info(f"Finished in {datetime.now() - start_time} seconds.") diff --git a/rpst/rpst.py b/rpst/rpst.py index c62f848..d30f8b9 100644 --- a/rpst/rpst.py +++ b/rpst/rpst.py @@ -3,8 +3,8 @@ from datetime import datetime import requests from glyphoji import glyph +from rich import print from rich.tree import Tree -from rich import print as xprint from .utils import convert_timestamp_to_datetime, write_post_data @@ -128,4 +128,4 @@ def get_posts(args: argparse): f"{glyph.check_mark_button} Keyword ('{keyword}') was found in " f"{found_posts}/{len(response['data']['children'])} {listing} posts from r/{subreddit}." ) - xprint(main_tree) + print(main_tree) diff --git a/rpst/utils.py b/rpst/utils.py index 27fec42..affbda2 100644 --- a/rpst/utils.py +++ b/rpst/utils.py @@ -7,8 +7,9 @@ from datetime import datetime import requests from glyphoji import glyph +from rich import print from rich.tree import Tree -from rich import print as xprint + from rich.markdown import Markdown from rich.logging import RichHandler @@ -84,7 +85,7 @@ def create_parser(): parser.add_argument( "-d", "--debug", - help="run rpst in debug mode (show network logs)", + help="run rpst in debug mode", action="store_true", ) @@ -110,50 +111,30 @@ def check_updates(version_tag: str): raw_release_notes = response["body"] # Log an info message about the new release. - xprint( + print( f"{glyph.up_arrow} A new release of RPST is available ({response['tag_name']}). " f"Run 'pip install --upgrade reddit-post-scraping-tool' to get the updates." ) # Print the release notes. - xprint(Markdown(raw_release_notes)) + print(Markdown(raw_release_notes)) -def set_loglevel(args: argparse) -> logging.getLogger: +def set_loglevel(debug_mode: bool) -> logging.getLogger: """ - Configures the logging level based on the provided arguments. + Configure and return a logging object with the specified log level. - If `args.debug` is True, the logging level is set to "NOTSET," allowing all log messages to be displayed. - Otherwise, the logging level is set to "INFO," and only informational and higher-severity messages are displayed. - - The function also configures a RichHandler for formatting the log messages, - including a specific time format and hiding the log level. - - :param args: A namespace object from argparse containing the debugging option (args.debug). - :return: A logger object associated with the name "rich." + :param debug_mode: If True, the log level is set to "NOTSET". Otherwise, it is set to "INFO". + :return: A logging object configured with the specified log level. """ - if args.debug: - logging.basicConfig( - level="NOTSET", - format="%(message)s", - handlers=[ - RichHandler( - markup=True, log_time_format="[%H:%M:%S%p]", show_level=False - ) - ], - ) - else: - logging.basicConfig( - level="INFO", - format="%(message)s", - handlers=[ - RichHandler( - markup=True, log_time_format="[%H:%M:%S%p]", show_level=False - ) - ], - ) - - return logging.getLogger("rich") + logging.basicConfig( + level="NOTSET" if debug_mode else "INFO", + format="%(message)s", + handlers=[ + RichHandler(markup=True, log_time_format="[%I:%M:%S %p]", show_level=False) + ], + ) + return logging.getLogger("RPST") def write_post_data(post_data: dict, filename: str, args, tree_branch: Tree):