@@ -1051,24 +1051,63 @@ def build_wiki_content(actions: List, config: Dict[str, Any]) -> str:
10511051 actions_by_date [date_str ].append (action )
10521052
10531053 # Build content - include ID column for tracking actions across the table
1054+ # Reddit wiki page size limit (512 KB)
1055+ REDDIT_WIKI_LIMIT = 524288
1056+ WARNING_THRESHOLD = int (REDDIT_WIKI_LIMIT * 0.90 ) # Start trimming at 90%
1057+
1058+ sorted_dates = sorted (actions_by_date .keys (), reverse = True )
10541059 content_parts = [timestamp_header ]
1055- for date_str in sorted (actions_by_date .keys (), reverse = True ):
1056- content_parts .append (f"## { date_str } " )
1057- content_parts .append ("| Time | Action | ID | Moderator | Content | Reason | Inquire |" )
1058- content_parts .append ("|------|--------|----|-----------|---------|--------|---------|" )
1059-
1060+ footer_parts = ["---" , "" , "*This modlog is automatically maintained by [RedditModLog](https://github.com/bakerboy448/RedditModLog) bot.*" ]
1061+
1062+ # Build the full content first
1063+ full_content_parts = []
1064+ for date_str in sorted_dates :
1065+ date_parts = [f"## { date_str } " ]
1066+ date_parts .append ("| Time | Action | ID | Moderator | Content | Reason | Inquire |" )
1067+ date_parts .append ("|------|--------|----|-----------|---------|--------|---------|" )
1068+
10601069 for action in sorted (actions_by_date [date_str ], key = lambda x : x .created_utc , reverse = True ):
10611070 entry = format_modlog_entry (action , config )
1062- content_parts .append (f"| { entry ['time' ]} | { entry ['action' ]} | { entry ['id' ]} | { entry ['moderator' ]} | { entry ['content' ]} | { entry ['reason' ]} | { entry ['inquire' ]} |" )
1063-
1064- content_parts .append ("" ) # Empty line between dates
1065-
1066- # Add bot attribution footer after all content
1067- content_parts .append ("---" )
1068- content_parts .append ("" )
1069- content_parts .append ("*This modlog is automatically maintained by [RedditModLog](https://github.com/bakerboy448/RedditModLog) bot.*" )
1070-
1071- return "\n " .join (content_parts )
1071+ date_parts .append (f"| { entry ['time' ]} | { entry ['action' ]} | { entry ['id' ]} | { entry ['moderator' ]} | { entry ['content' ]} | { entry ['reason' ]} | { entry ['inquire' ]} |" )
1072+
1073+ date_parts .append ("" ) # Empty line between dates
1074+ full_content_parts .append ("\n " .join (date_parts ))
1075+
1076+ # Check size and trim if necessary
1077+ included_dates = []
1078+ current_size = len ((timestamp_header + "\n " .join (footer_parts )).encode ('utf-8' ))
1079+ skipped_days = 0
1080+
1081+ for i , date_content in enumerate (full_content_parts ):
1082+ test_size = current_size + len (date_content .encode ('utf-8' ))
1083+
1084+ # If adding this date would exceed the warning threshold, stop adding dates
1085+ if test_size > WARNING_THRESHOLD :
1086+ skipped_days = len (sorted_dates ) - i
1087+ if skipped_days > 0 :
1088+ logger .warning (f"Wiki approaching size limit - trimming { skipped_days } oldest day(s) of entries" )
1089+ logger .warning (f"Excluded dates: { sorted_dates [i :]} " )
1090+
1091+ # Add a notice about trimmed content
1092+ content_parts .append (f"\n **Note:** { skipped_days } older day(s) trimmed due to wiki size limits." )
1093+ content_parts .append (f"Only showing entries from { sorted_dates [i - 1 ] if i > 0 else 'today' } onwards.\n " )
1094+ break
1095+
1096+ content_parts .append (date_content )
1097+ included_dates .append (sorted_dates [i ])
1098+ current_size = test_size
1099+
1100+ # Add footer
1101+ content_parts .extend (footer_parts )
1102+
1103+ final_content = "\n " .join (content_parts )
1104+ final_size = len (final_content .encode ('utf-8' ))
1105+
1106+ if skipped_days > 0 :
1107+ logger .info (f"Wiki content size after trimming: { final_size :,} bytes ({ (final_size / REDDIT_WIKI_LIMIT )* 100 :.1f} % of limit)" )
1108+ logger .info (f"Included { len (included_dates )} days, excluded { skipped_days } days" )
1109+
1110+ return final_content
10721111
10731112def setup_reddit_client (config : Dict [str , Any ]):
10741113 """Initialize Reddit API client"""
@@ -1092,9 +1131,26 @@ def setup_reddit_client(config: Dict[str, Any]):
10921131def update_wiki_page (reddit , subreddit_name : str , wiki_page : str , content : str , force : bool = False ):
10931132 """Update wiki page with content, using hash caching to avoid unnecessary updates"""
10941133 try :
1134+ # Reddit wiki page size limit (512 KB)
1135+ REDDIT_WIKI_LIMIT = 524288
1136+
1137+ # Check content size
1138+ content_size = len (content .encode ('utf-8' ))
1139+ if content_size > REDDIT_WIKI_LIMIT :
1140+ logger .error (f"Wiki content size ({ content_size :,} bytes) exceeds Reddit's limit ({ REDDIT_WIKI_LIMIT :,} bytes)" )
1141+ logger .error (f"Content is { content_size - REDDIT_WIKI_LIMIT :,} bytes over the limit" )
1142+ raise ValueError (f"Wiki content too large: { content_size :,} bytes (limit: { REDDIT_WIKI_LIMIT :,} bytes)" )
1143+
1144+ # Check if we're getting close to the limit (warn at 95%)
1145+ warning_threshold = int (REDDIT_WIKI_LIMIT * 0.95 )
1146+ if content_size > warning_threshold :
1147+ percent_used = (content_size / REDDIT_WIKI_LIMIT ) * 100
1148+ logger .warning (f"Wiki content size ({ content_size :,} bytes) is { percent_used :.1f} % of Reddit's limit" )
1149+ logger .warning (f"Only { REDDIT_WIKI_LIMIT - content_size :,} bytes remaining before hitting limit" )
1150+
10951151 # Calculate content hash
10961152 content_hash = get_content_hash (content )
1097-
1153+
10981154 # Check if content has changed (unless forced)
10991155 cached_hash = get_cached_wiki_hash (subreddit_name , wiki_page )
11001156 if cached_hash == content_hash :
@@ -1103,23 +1159,91 @@ def update_wiki_page(reddit, subreddit_name: str, wiki_page: str, content: str,
11031159 else :
11041160 logger .info (f"Wiki content unchanged for /r/{ subreddit_name } /wiki/{ wiki_page } , skipping update" )
11051161 return False
1106-
1107- # Update the wiki page
1162+
1163+ # Check existing wiki page size if it exists
11081164 subreddit = reddit .subreddit (subreddit_name )
1165+ try :
1166+ existing_wiki = subreddit .wiki [wiki_page ]
1167+ existing_size = len (existing_wiki .content_md .encode ('utf-8' ))
1168+ logger .debug (f"Existing wiki page size: { existing_size :,} bytes" )
1169+
1170+ # If new content would make page exceed limit, we need to handle it
1171+ if existing_size > warning_threshold :
1172+ logger .warning (f"Existing wiki page already at { existing_size :,} bytes ({ (existing_size / REDDIT_WIKI_LIMIT )* 100 :.1f} % of limit)" )
1173+
1174+ # If we're trying to add more content to an already large page
1175+ if content_size >= existing_size :
1176+ logger .error (f"Cannot increase wiki size from { existing_size :,} to { content_size :,} bytes - too close to limit" )
1177+ logger .error ("Consider reducing retention_days or max_wiki_entries_per_page in config" )
1178+ raise ValueError (f"Wiki page too large to update safely" )
1179+ except Exception as e :
1180+ # Wiki page might not exist yet, that's okay
1181+ if "404" not in str (e ) and "not found" not in str (e ).lower ():
1182+ logger .debug (f"Could not check existing wiki size: { e } " )
1183+
1184+ # Update the wiki page
1185+ logger .info (f"Attempting to update wiki page with { content_size :,} bytes of content" )
11091186 subreddit .wiki [wiki_page ].edit (
11101187 content = content ,
11111188 reason = "Automated modlog update"
11121189 )
1113-
1190+
11141191 # Update the cached hash
11151192 update_cached_wiki_hash (subreddit_name , wiki_page , content_hash )
1116-
1193+
11171194 action_type = "force updated" if force else "updated"
11181195 logger .info (f"Successfully { action_type } wiki page: /r/{ subreddit_name } /wiki/{ wiki_page } " )
1196+ logger .info (f"Final wiki size: { content_size :,} bytes ({ (content_size / REDDIT_WIKI_LIMIT )* 100 :.1f} % of Reddit's limit)" )
11191197 return True
1120-
1198+
1199+ except praw .exceptions .RedditAPIException as e :
1200+ # Handle specific Reddit API errors
1201+ error_messages = []
1202+ for item in e .items :
1203+ error_messages .append (f"{ item .error_type } : { item .message } " )
1204+
1205+ logger .error (f"Reddit API error updating wiki page: { ', ' .join (error_messages )} " )
1206+
1207+ # Check if it's a size-related error
1208+ if any ('too long' in msg .lower () or 'size' in msg .lower () for msg in error_messages ):
1209+ logger .error (f"Wiki content size ({ content_size :,} bytes) likely exceeds Reddit's limit" )
1210+ logger .error ("Try reducing retention_days or max_wiki_entries_per_page in config" )
1211+
1212+ raise
1213+
11211214 except Exception as e :
1122- logger .error (f"Failed to update wiki page: { e } " )
1215+ error_str = str (e )
1216+
1217+ # Provide more context for common errors
1218+ if "403" in error_str :
1219+ logger .error (f"403 Forbidden error updating wiki page /r/{ subreddit_name } /wiki/{ wiki_page } " )
1220+ logger .error ("Possible causes:" )
1221+ logger .error (" 1. Wiki page size limit exceeded (current content: {content_size:,} bytes)" )
1222+ logger .error (" 2. Bot lacks wiki edit permissions on this subreddit" )
1223+ logger .error (" 3. Wiki page is locked or restricted" )
1224+ logger .error (" 4. Rate limiting (too many requests)" )
1225+
1226+ # Check if we're near the size limit
1227+ if content_size > REDDIT_WIKI_LIMIT * 0.95 :
1228+ logger .error (f"LIKELY CAUSE: Content size ({ content_size :,} bytes) is very close to Reddit's limit ({ REDDIT_WIKI_LIMIT :,} bytes)" )
1229+
1230+ # Try to check existing page size for context
1231+ try :
1232+ existing_wiki = subreddit .wiki [wiki_page ]
1233+ existing_size = len (existing_wiki .content_md .encode ('utf-8' ))
1234+ logger .error (f"Current wiki page size: { existing_size :,} bytes" )
1235+ if existing_size > REDDIT_WIKI_LIMIT * 0.95 :
1236+ logger .error ("Wiki page is already near Reddit's size limit!" )
1237+ except :
1238+ pass
1239+
1240+ elif "404" in error_str :
1241+ logger .error (f"Wiki page /r/{ subreddit_name } /wiki/{ wiki_page } not found" )
1242+ logger .error ("The wiki page might not exist yet or the name is incorrect" )
1243+
1244+ else :
1245+ logger .error (f"Failed to update wiki page: { e } " )
1246+
11231247 raise
11241248
11251249def process_modlog_actions (reddit , config : Dict [str , Any ]) -> List :
0 commit comments