SYMBOL INDEX (133 symbols across 16 files) FILE: alerts/notifications.py function send_discord_alert (line 8) | def send_discord_alert(webhook_url, title, message, posts=None, color=0x... function send_telegram_alert (line 61) | def send_telegram_alert(bot_token, chat_id, title, message, posts=None): function check_keyword_alerts (line 107) | def check_keyword_alerts(posts, keywords, webhook_url=None, telegram_tok... function send_scrape_summary (line 151) | def send_scrape_summary(subreddit, stats, webhook_url=None, telegram_tok... class AlertMonitor (line 178) | class AlertMonitor: method __init__ (line 181) | def __init__(self, keywords, discord_webhook=None, telegram_token=None... method check_posts (line 188) | def check_posts(self, posts): FILE: analytics/sentiment.py function analyze_sentiment (line 26) | def analyze_sentiment(text): function analyze_posts_sentiment (line 72) | def analyze_posts_sentiment(posts): function analyze_comments_sentiment (line 87) | def analyze_comments_sentiment(comments): function extract_keywords (line 101) | def extract_keywords(texts, top_n=50): function generate_wordcloud_data (line 130) | def generate_wordcloud_data(texts, top_n=100): function calculate_engagement_metrics (line 144) | def calculate_engagement_metrics(posts): function find_best_posting_times (line 189) | def find_best_posting_times(posts): FILE: analytics/subreddit_stats.py function get_subreddit_about (line 10) | def get_subreddit_about(subreddit): function get_subreddit_rules (line 55) | def get_subreddit_rules(subreddit): function get_subreddit_mods (line 90) | def get_subreddit_mods(subreddit): function get_subreddit_flairs (line 123) | def get_subreddit_flairs(subreddit): function get_full_subreddit_stats (line 155) | def get_full_subreddit_stats(subreddit): function save_subreddit_stats (line 199) | def save_subreddit_stats(subreddit, output_dir="data"): FILE: api/server.py function root (line 45) | def root(): function health_check (line 56) | def health_check(): function database_info (line 66) | def database_info(): function list_posts (line 74) | def list_posts( function get_post (line 98) | def get_post(post_id: str): function list_comments (line 114) | def list_comments( function list_subreddits (line 134) | def list_subreddits(): function subreddit_stats (line 140) | def subreddit_stats(subreddit: str): function list_jobs (line 151) | def list_jobs( function job_stats (line 161) | def job_stats(): function raw_query (line 169) | def raw_query( function grafana_search (line 202) | def grafana_search(): function grafana_query (line 209) | def grafana_query(body: dict): FILE: dashboard/app.py function load_subreddit_data (line 61) | def load_subreddit_data(subreddit_path): function get_available_data (line 75) | def get_available_data(): function main (line 98) | def main(): FILE: export/cloud.py class S3Uploader (line 27) | class S3Uploader: method __init__ (line 30) | def __init__(self, bucket_name, aws_access_key=None, aws_secret_key=No... method upload_file (line 54) | def upload_file(self, local_path, s3_key=None): method upload_directory (line 82) | def upload_directory(self, local_dir, s3_prefix=""): method upload_subreddit_data (line 114) | def upload_subreddit_data(self, subreddit, prefix="u"): method list_uploads (line 136) | def list_uploads(self, prefix="reddit/"): class GDriveUploader (line 160) | class GDriveUploader: method __init__ (line 163) | def __init__(self, credentials_file='credentials.json', token_file='to... method _authenticate (line 179) | def _authenticate(self): method create_folder (line 201) | def create_folder(self, name, parent_id=None): method upload_file (line 214) | def upload_file(self, local_path, folder_id=None): method upload_subreddit_data (line 241) | def upload_subreddit_data(self, subreddit, prefix="r"): function upload_to_s3 (line 264) | def upload_to_s3(subreddit, bucket_name, prefix="r"): function upload_to_gdrive (line 280) | def upload_to_gdrive(subreddit, prefix="r"): FILE: export/database.py function get_connection (line 12) | def get_connection(): function init_database (line 19) | def init_database(): function save_post (line 147) | def save_post(post_data, subreddit): function save_posts_batch (line 189) | def save_posts_batch(posts, subreddit): function save_comments_batch (line 234) | def save_comments_batch(comments, post_id): function search_posts (line 268) | def search_posts(query=None, subreddit=None, author=None, min_score=None, function search_comments (line 313) | def search_comments(query=None, post_id=None, author=None, min_score=Non... function get_subreddit_stats (line 345) | def get_subreddit_stats(subreddit): function get_all_subreddits (line 393) | def get_all_subreddits(): function start_job_record (line 411) | def start_job_record(target, mode, is_user=False, dry_run=False): function complete_job_record (line 437) | def complete_job_record(job_id, status, posts=0, comments=0, media=0, er... function get_job_history (line 483) | def get_job_history(limit=50, target=None, status=None): function get_job_stats (line 507) | def get_job_stats(): function print_job_history (line 540) | def print_job_history(limit=20): function enable_auto_vacuum (line 567) | def enable_auto_vacuum(): function vacuum_database (line 578) | def vacuum_database(): function backup_database (line 588) | def backup_database(backup_path=None): function get_database_info (line 615) | def get_database_info(): FILE: export/parquet.py function export_to_parquet (line 9) | def export_to_parquet(subreddit, output_dir=None, prefix="r"): function export_database_to_parquet (line 89) | def export_database_to_parquet(output_dir=None): function list_parquet_files (line 136) | def list_parquet_files(directory="data/parquet"): FILE: main.py function setup_directories (line 37) | def setup_directories(target, prefix): function get_file_path (line 55) | def get_file_path(target, type_prefix): function load_history (line 62) | def load_history(filepath): function save_posts_csv (line 74) | def save_posts_csv(posts, filepath): function save_comments_csv (line 97) | def save_comments_csv(comments, filepath): function get_media_urls (line 111) | def get_media_urls(post_data): function download_media (line 155) | def download_media(url, save_path, media_type="image"): function download_reddit_video_with_audio (line 171) | def download_reddit_video_with_audio(video_url, save_path): function download_post_media (line 262) | def download_post_media(post_data, dirs, post_id): function scrape_comments (line 293) | def scrape_comments(permalink, max_depth=3): function parse_comments (line 321) | def parse_comments(comment_list, post_permalink, depth=0, max_depth=3): function extract_post_data (line 355) | def extract_post_data(post_json): function run_full_history (line 394) | def run_full_history(target, limit, is_user=False, download_media_flag=T... function run_monitor (line 604) | def run_monitor(target, is_user=False): function main (line 655) | def main(): FILE: plugins/__init__.py class Plugin (line 11) | class Plugin(ABC): method process_posts (line 36) | def process_posts(self, posts: list) -> list: method process_comments (line 48) | def process_comments(self, comments: list) -> list: method __repr__ (line 60) | def __repr__(self): function load_plugins (line 64) | def load_plugins(plugin_dir=None): function run_plugins (line 111) | def run_plugins(posts, comments, plugins): function list_plugins (line 134) | def list_plugins(plugin_dir=None): FILE: plugins/deduplicator.py class Deduplicator (line 8) | class Deduplicator(Plugin): method process_posts (line 15) | def process_posts(self, posts): method process_comments (line 34) | def process_comments(self, comments): FILE: plugins/keyword_extractor.py class KeywordExtractor (line 14) | class KeywordExtractor(Plugin): method process_posts (line 22) | def process_posts(self, posts): FILE: plugins/sentiment_tagger.py class SentimentTagger (line 15) | class SentimentTagger(Plugin): method process_posts (line 22) | def process_posts(self, posts): method process_comments (line 38) | def process_comments(self, comments): FILE: scheduler/cron.py class CronScheduler (line 11) | class CronScheduler: method __init__ (line 14) | def __init__(self): method add_job (line 19) | def add_job(self, target, mode='full', limit=100, is_user=False, method remove_job (line 49) | def remove_job(self, job_id): method disable_job (line 54) | def disable_job(self, job_id): method enable_job (line 61) | def enable_job(self, job_id): method list_jobs (line 68) | def list_jobs(self): method _run_job (line 82) | def _run_job(self, job): method _scheduler_loop (line 106) | def _scheduler_loop(self): method start (line 126) | def start(self): method stop (line 137) | def stop(self): method save_jobs (line 144) | def save_jobs(self, filepath='scheduler_jobs.json'): method load_jobs (line 157) | def load_jobs(self, filepath='scheduler_jobs.json'): function run_scheduled (line 177) | def run_scheduled(target, interval_minutes, mode='full', limit=100, is_u... FILE: scraper/async_scraper.py function fetch_json (line 24) | async def fetch_json(session, url, retries=3): function fetch_posts_page (line 38) | async def fetch_posts_page(session, base_url, target, after=None, is_use... function download_media_async (line 51) | async def download_media_async(session, url, save_path): function download_reddit_video_with_audio_async (line 70) | async def download_reddit_video_with_audio_async(session, video_url, sav... function fetch_comments_async (line 171) | async def fetch_comments_async(session, permalink): function parse_comments_sync (line 183) | def parse_comments_sync(comment_list, post_permalink, depth=0, max_depth... function extract_media_urls (line 216) | def extract_media_urls(post_data): function extract_post_data (line 256) | def extract_post_data(p): function scrape_async (line 292) | async def scrape_async(target, limit=100, is_user=False, download_media=... function run_async_scraper (line 467) | def run_async_scraper(target, limit=100, is_user=False, download_media=T... FILE: search/query.py function search_csv (line 9) | def search_csv(filepath, query=None, column=None, min_score=None, max_sc... function search_all_data (line 71) | def search_all_data(data_dir='data', query=None, **kwargs): function print_search_results (line 108) | def print_search_results(results, show_preview=True): function advanced_search (line 130) | def advanced_search(data_dir='data', query=None, regex=False, sort_by='s... function get_top_posts (line 192) | def get_top_posts(data_dir='data', n=10, by='score'): function get_recent_posts (line 197) | def get_recent_posts(data_dir='data', n=10): function find_author_posts (line 202) | def find_author_posts(data_dir='data', author=None): function export_search_results (line 206) | def export_search_results(results, output_path, format='csv'):