diff --git a/export_image.py b/export_image.py index 901999a..29930f6 100644 --- a/export_image.py +++ b/export_image.py @@ -61,13 +61,13 @@ if __name__ == "__main__": # Determine the correct URL path and filename based on arguments if args.subreddit: view_type = "weekly" if args.weekly else "daily" - url_path_to_render = f"image/{view_type}/{args.subreddit}" + # Add ?view=... and the new &image=true parameter + url_path_to_render = f"subreddit/{args.subreddit}?view={view_type}&image=true" filename_prefix_to_save = f"{args.subreddit}_{view_type}" export_image(url_path_to_render, filename_prefix_to_save) elif args.overall: - if args.weekly: - print("Warning: --weekly flag has no effect with --overall. Exporting overall summary.") - url_path_to_render = "image/overall" - filename_prefix_to_save = "overall_summary" + # For overall, we assume daily view for the image + url_path_to_render = "/?view=daily&image=true" + filename_prefix_to_save = "overall_summary_daily" export_image(url_path_to_render, filename_prefix_to_save) \ No newline at end of file diff --git a/rstat_tool/dashboard.py b/rstat_tool/dashboard.py index fa7a825..293a71d 100644 --- a/rstat_tool/dashboard.py +++ b/rstat_tool/dashboard.py @@ -4,13 +4,12 @@ from flask import Flask, render_template, request from datetime import datetime, timedelta, timezone from .logger_setup import logger as log from .database import ( - get_overall_summary, - get_subreddit_summary, get_all_scanned_subreddits, get_deep_dive_details, get_daily_summary_for_subreddit, get_weekly_summary_for_subreddit, - get_overall_image_view_summary + get_overall_daily_summary, # Now correctly imported + get_overall_weekly_summary # Now correctly imported ) app = Flask(__name__, template_folder='../templates') @@ -31,21 +30,64 @@ def format_market_cap(mc): @app.context_processor def inject_subreddits(): - """Makes the list of all scanned subreddits available to every template.""" - subreddits = get_all_scanned_subreddits() - return dict(subreddits=subreddits) + """Makes the list of all subreddits available to every template for the navbar.""" + return dict(all_subreddits=get_all_scanned_subreddits()) @app.route("/") -def index(): - """The handler for the main dashboard page.""" - tickers = get_overall_summary(limit=10) - return render_template("index.html", tickers=tickers) +def overall_dashboard(): + """Handler for the main, overall dashboard.""" + view_type = request.args.get('view', 'daily') + + is_image_mode = request.args.get('image') == 'true' + + if view_type == 'weekly': + tickers, start, end = get_overall_weekly_summary() + date_string = f"{start.strftime('%b %d')} - {end.strftime('%b %d, %Y')}" + subtitle = "All Subreddits - Top 10 Weekly" + else: # Default to daily + tickers = get_overall_daily_summary() + date_string = datetime.now(timezone.utc).strftime("%Y-%m-%d") + subtitle = "All Subreddits - Top 10 Daily" + + return render_template( + "dashboard_view.html", + title="Overall Dashboard", + subtitle=subtitle, + date_string=date_string, + tickers=tickers, + view_type=view_type, + subreddit_name=None, + is_image_mode=is_image_mode + ) @app.route("/subreddit/") def subreddit_dashboard(name): - """A dynamic route for per-subreddit dashboards.""" - tickers = get_subreddit_summary(name, limit=10) - return render_template("subreddit.html", tickers=tickers, subreddit_name=name) + """Handler for per-subreddit dashboards.""" + view_type = request.args.get('view', 'daily') + + is_image_mode = request.args.get('image') == 'true' + + if view_type == 'weekly': + today = datetime.now(timezone.utc) + target_date = today - timedelta(days=7) # Default to last week + tickers, start, end = get_weekly_summary_for_subreddit(name, target_date) + date_string = f"{start.strftime('%b %d')} - {end.strftime('%b %d, %Y')}" + subtitle = f"r/{name} - Top 10 Weekly" + else: # Default to daily + tickers = get_daily_summary_for_subreddit(name) + date_string = datetime.now(timezone.utc).strftime("%Y-%m-%d") + subtitle = f"r/{name} - Top 10 Daily" + + return render_template( + "dashboard_view.html", + title=f"r/{name} Dashboard", + subtitle=subtitle, + date_string=date_string, + tickers=tickers, + view_type=view_type, + subreddit_name=name, + is_image_mode=is_image_mode + ) @app.route("/deep-dive/") def deep_dive(symbol): @@ -54,63 +96,6 @@ def deep_dive(symbol): posts = get_deep_dive_details(symbol) return render_template("deep_dive.html", posts=posts, symbol=symbol) -@app.route("/image/daily/") -def daily_image_view(name): - """The handler for the image-style dashboard.""" - tickers = get_daily_summary_for_subreddit(name) - current_date = datetime.now(timezone.utc).strftime("%Y-%m-%d") - return render_template( - "daily_image_view.html", - tickers=tickers, - subreddit_name=name, - current_date=current_date - ) - -@app.route("/image/weekly/") -def weekly_image_view(name): - """ - The handler for the WEEKLY image-style dashboard. - Accepts an optional 'date' query parameter in YYYY-MM-DD format. - """ - # Get the date from the URL query string, e.g., ?date=2025-07-21 - date_str = request.args.get('date') - target_date = None - - if date_str: - try: - # Convert the string to a datetime object - target_date = datetime.strptime(date_str, "%Y-%m-%d").replace(tzinfo=timezone.utc) - except ValueError: - return "Invalid date format. Please use YYYY-MM-DD.", 400 - else: - # If no date is provided, default to showing LAST week - today = datetime.now(timezone.utc) - target_date = today - timedelta(days=7) - - # The query now returns the results and the date objects used - tickers, start_of_week, end_of_week = get_weekly_summary_for_subreddit(name, target_date) - - # Format the date range for the title - date_range_str = f"{start_of_week.strftime('%b %d')} - {end_of_week.strftime('%b %d, %Y')}" - - return render_template( - "weekly_image_view.html", - tickers=tickers, - subreddit_name=name, - date_range=date_range_str - ) - -@app.route("/image/overall") -def overall_image_view(): - """The handler for the overall image-style dashboard.""" - tickers = get_overall_image_view_summary() - current_date = datetime.now(timezone.utc).strftime("%Y-%m-%d") - return render_template( - "overall_image_view.html", - tickers=tickers, - current_date=current_date - ) - def start_dashboard(): """The main function called by the 'rstat-dashboard' command.""" log.info("Starting Flask server...") diff --git a/rstat_tool/database.py b/rstat_tool/database.py index e20fa9e..15aab5c 100644 --- a/rstat_tool/database.py +++ b/rstat_tool/database.py @@ -311,6 +311,49 @@ def get_overall_image_view_summary(): conn.close() return results +def get_overall_daily_summary(): + """ + Gets the top tickers across all subreddits from the LAST 24 HOURS. + (This is a copy of get_overall_summary, renamed for clarity). + """ + conn = get_db_connection() + one_day_ago = datetime.now(timezone.utc) - timedelta(days=1) + one_day_ago_timestamp = int(one_day_ago.timestamp()) + query = """ + SELECT t.symbol, t.market_cap, t.closing_price, COUNT(m.id) as total_mentions, + SUM(CASE WHEN m.mention_sentiment > 0.1 THEN 1 ELSE 0 END) as bullish_mentions, + SUM(CASE WHEN m.mention_sentiment < -0.1 THEN 1 ELSE 0 END) as bearish_mentions + FROM mentions m JOIN tickers t ON m.ticker_id = t.id + WHERE m.mention_timestamp >= ? + GROUP BY t.symbol, t.market_cap, t.closing_price + ORDER BY total_mentions DESC LIMIT 10; + """ + results = conn.execute(query, (one_day_ago_timestamp,)).fetchall() + conn.close() + return results + +def get_overall_weekly_summary(): + """ + Gets the top tickers across all subreddits for the LAST 7 DAYS. + """ + conn = get_db_connection() + today = datetime.now(timezone.utc) + start_of_week, end_of_week = get_week_start_end(today - timedelta(days=7)) # Get last week's boundaries + start_timestamp = int(start_of_week.timestamp()) + end_timestamp = int(end_of_week.timestamp()) + query = """ + SELECT t.symbol, t.market_cap, t.closing_price, COUNT(m.id) as total_mentions, + SUM(CASE WHEN m.mention_sentiment > 0.1 THEN 1 ELSE 0 END) as bullish_mentions, + SUM(CASE WHEN m.mention_sentiment < -0.1 THEN 1 ELSE 0 END) as bearish_mentions + FROM mentions m JOIN tickers t ON m.ticker_id = t.id + WHERE m.mention_timestamp BETWEEN ? AND ? + GROUP BY t.symbol, t.market_cap, t.closing_price + ORDER BY total_mentions DESC LIMIT 10; + """ + results = conn.execute(query, (start_timestamp, end_timestamp)).fetchall() + conn.close() + return results, start_of_week, end_of_week + def get_deep_dive_details(ticker_symbol): """ Gets all analyzed posts that mention a specific ticker. """ conn = get_db_connection() diff --git a/templates/base.html b/templates/base.html deleted file mode 100644 index 8aa2c9f..0000000 --- a/templates/base.html +++ /dev/null @@ -1,109 +0,0 @@ - - - - - - {% block title %}Reddit Stock Dashboard{% endblock %} - - - - -
- {% block content %}{% endblock %} -
- - \ No newline at end of file diff --git a/templates/daily_image_view.html b/templates/daily_image_view.html deleted file mode 100644 index 859c641..0000000 --- a/templates/daily_image_view.html +++ /dev/null @@ -1,95 +0,0 @@ - - - - - - r/{{ subreddit_name }} Ticker Mentions - - - - - - -
-
-
-

Ticker Mentions Daily

-

r/{{ subreddit_name }}

-
-
{{ current_date }}
-
- - - - - - - - - - - - - {% for ticker in tickers %} - - - - - - - - - {% endfor %} - -
RankTickerMentionsMkt CapClose PriceSentiment
{{ loop.index }}{{ ticker.symbol }}{{ ticker.total_mentions }}{{ ticker.market_cap | format_mc }} - {% if ticker.closing_price %} - ${{ "%.2f"|format(ticker.closing_price) }} - {% else %} - N/A - {% endif %} - - {% if ticker.bullish_mentions > ticker.bearish_mentions %} - Bullish - {% elif ticker.bearish_mentions > ticker.bullish_mentions %} - Bearish - {% else %} - Neutral - {% endif %} -
-
-
r/rstat
-
visit us for more
-
-
- - \ No newline at end of file diff --git a/templates/dashboard_base.html b/templates/dashboard_base.html new file mode 100644 index 0000000..de735de --- /dev/null +++ b/templates/dashboard_base.html @@ -0,0 +1,140 @@ + + + + + + {% block title %}RSTAT Dashboard{% endblock %} + + + + + + + {% if not is_image_mode %} + + {% endif %} +
+ {% block content %}{% endblock %} +
+ + \ No newline at end of file diff --git a/templates/dashboard_view.html b/templates/dashboard_view.html new file mode 100644 index 0000000..00ccc85 --- /dev/null +++ b/templates/dashboard_view.html @@ -0,0 +1,69 @@ +{% extends "dashboard_base.html" %} + +{% block title %}{{ title }}{% endblock %} + +{% block content %} +
+
+
+

Reddit Ticker Mentions

+

{{ subtitle }}

+
+
{{ date_string }}
+
+ + + + + + + + + + + + + {% for ticker in tickers %} + + + + + + + + + {% else %} + + + + {% endfor %} + +
RankTickerMentionsSentimentMkt CapClose Price
{{ loop.index }} + + {% if is_image_mode %} + {{ ticker.symbol }} + {% else %} + {{ ticker.symbol }} + {% endif %} + + {{ ticker.total_mentions }} + {% if ticker.bullish_mentions > ticker.bearish_mentions %} + Bullish + {% elif ticker.bearish_mentions > ticker.bullish_mentions %} + Bearish + {% else %} + Neutral + {% endif %} + {{ ticker.market_cap | format_mc }} + {% if ticker.closing_price %} + ${{ "%.2f"|format(ticker.closing_price) }} + {% else %} + N/A + {% endif %} +
No ticker data found for this period.
+
+
RSTAT
+
Reddit Stock Analysis Tool
+
+
+{% endblock %} \ No newline at end of file diff --git a/templates/index.html b/templates/index.html deleted file mode 100644 index 992bf8f..0000000 --- a/templates/index.html +++ /dev/null @@ -1,48 +0,0 @@ -{% extends "base.html" %} - -{% block title %}Overall Dashboard{% endblock %} - -{% block content %} -

- Top 10 Tickers Today (All Subreddits) - - image -

- - - - - - - - - - - - {% for ticker in tickers %} - - - - - - - - - {% endfor %} - -
TickerMentionsMarket CapClosing PriceSentiment
{{ ticker.symbol }}{{ ticker.mention_count }}{{ ticker.market_cap | format_mc }} - {% if ticker.closing_price %} - ${{ "%.2f"|format(ticker.closing_price) }} - {% else %} - N/A - {% endif %} - - {% if ticker.bullish_mentions > ticker.bearish_mentions %} - Bullish - {% elif ticker.bearish_mentions > ticker.bullish_mentions %} - Bearish - {% else %} - Neutral - {% endif %} -
-{% endblock %} \ No newline at end of file diff --git a/templates/overall_image_view.html b/templates/overall_image_view.html deleted file mode 100644 index 05fc880..0000000 --- a/templates/overall_image_view.html +++ /dev/null @@ -1,95 +0,0 @@ - - - - - - r/{{ subreddit_name }} Ticker Mentions - - - - - - -
-
-
-

Ticker Mentions Daily

-

All Subreddits

-
-
{{ current_date }}
-
- - - - - - - - - - - - - {% for ticker in tickers %} - - - - - - - - - {% endfor %} - -
RankTickerMentionsMkt CapClose PriceSentiment
{{ loop.index }}{{ ticker.symbol }}{{ ticker.total_mentions }}{{ ticker.market_cap | format_mc }} - {% if ticker.closing_price %} - ${{ "%.2f"|format(ticker.closing_price) }} - {% else %} - N/A - {% endif %} - - {% if ticker.bullish_mentions > ticker.bearish_mentions %} - Bullish - {% elif ticker.bearish_mentions > ticker.bullish_mentions %} - Bearish - {% else %} - Neutral - {% endif %} -
-
-
r/rstat
-
visit us for more
-
-
- - \ No newline at end of file diff --git a/templates/subreddit.html b/templates/subreddit.html deleted file mode 100644 index e940667..0000000 --- a/templates/subreddit.html +++ /dev/null @@ -1,48 +0,0 @@ -{% extends "base.html" %} - -{% block title %}r/{{ subreddit_name }} Dashboard{% endblock %} - -{% block content %} -

- Top 10 Tickers Today in r/{{ subreddit_name }} - daily image - weekly image -

- - - - - - - - - - - - {% for ticker in tickers %} - - - - - - - - - {% endfor %} - -
TickerMentionsMarket CapClosing PriceSentiment
{{ ticker.symbol }}{{ ticker.mention_count }}{{ ticker.market_cap | format_mc }} - {% if ticker.closing_price %} - ${{ "%.2f"|format(ticker.closing_price) }} - {% else %} - N/A - {% endif %} - - {% if ticker.bullish_mentions > ticker.bearish_mentions %} - Bullish - {% elif ticker.bearish_mentions > ticker.bullish_mentions %} - Bearish - {% else %} - Neutral - {% endif %} -
-{% endblock %} \ No newline at end of file diff --git a/templates/weekly_image_view.html b/templates/weekly_image_view.html deleted file mode 100644 index adc78a1..0000000 --- a/templates/weekly_image_view.html +++ /dev/null @@ -1,95 +0,0 @@ - - - - - - r/{{ subreddit_name }} Ticker Mentions - - - - - - -
-
-
-

Ticker Mentions Weekly

-

r/{{ subreddit_name }}

-
-
{{ date_range }}
-
- - - - - - - - - - - - - {% for ticker in tickers %} - - - - - - - - - {% endfor %} - -
RankTickerMentionsMkt CapClose PriceSentiment
{{ loop.index }}{{ ticker.symbol }}{{ ticker.total_mentions }}{{ ticker.market_cap | format_mc }} - {% if ticker.closing_price %} - ${{ "%.2f"|format(ticker.closing_price) }} - {% else %} - N/A - {% endif %} - - {% if ticker.bullish_mentions > ticker.bearish_mentions %} - Bullish - {% elif ticker.bearish_mentions > ticker.bullish_mentions %} - Bearish - {% else %} - Neutral - {% endif %} -
- -
- - \ No newline at end of file