Advertisement
Guest User

kwikstat.py

a guest
Jan 8th, 2018
354
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.43 KB | None | 0 0
  1. # kwikstat.py ============================================ 2018 January 8
  2. #
  3. # Searches inbox for username mentions and replies to properly formatted
  4. # comments.
  5. #
  6. # Comment syntax:    /u/kwikstat redditor
  7. #
  8. # Replies with comment containing tables of user's most active subreddits
  9. # by total comments and posts.
  10. #
  11. # Tested with Python 2.7.13 =============================================
  12. import time
  13. import operator
  14. import logging
  15. import praw
  16. import antiabuse as aa
  17. from prawcore import exceptions
  18.  
  19. # Script loop delay
  20. delay = 60  # 10 minutes
  21.  
  22. # Blacklisted subreddits
  23. blacklist = ['depression', 'suicidewatch']
  24.  
  25. # Reddit Authentication information:
  26. clientId = "" # String
  27. clientSecret = "" # String
  28. userAgent = "" # String
  29. bot_name = ""
  30. password = ""
  31.  
  32. # Search depth and list length values
  33. list_length = 5
  34. search_depth = 1000
  35.  
  36.  
  37. def aa_scan_ok(reddit, comment, bot_name):
  38.     # Check and address anti-abuse issues
  39.     if aa.is_summon_chain(reddit, comment, bot_name):
  40.         msg = "ANTI-ABUSE: Summon chain - skipped"
  41.         print msg
  42.         logging.info(msg)
  43.         return False
  44.     if aa.comment_limit_reached(comment, 5):
  45.         msg = "ANTI-ABUSE: Comment limit reached - skipped"
  46.         print msg
  47.         logging.info(msg)        
  48.         return False
  49.     if aa.is_already_done(comment, bot_name):
  50.         msg = "ANTI-ABUSE: Already done - skipped"
  51.         print msg
  52.         logging.info(msg)        
  53.         return False
  54.     return True
  55.  
  56.        
  57. def search_and_post(comment, redditor, list_length, search_depth):
  58.     # Create and post reply; append blacklist if necessary; handle errors
  59.     global blacklist
  60.     if not aa_scan_ok(reddit, comment, bot_name):
  61.         comment.mark_read()
  62.         return
  63.     try:
  64.         post_list = list(redditor.submissions.new(limit=search_depth))
  65.         comment_list = list(redditor.comments.new(limit=search_depth))
  66.         posts_dict = get_subreddit_tallies(post_list)
  67.         comments_dict = get_subreddit_tallies(comment_list)        
  68.         reply_msg = "RECENT USER ACTIVITY: %s\n\n" % target_user
  69.         reply_msg += "TOP SUBREDDITS BY POST:\n\n"                    
  70.         reply_msg += build_table(posts_dict, list_length)
  71.         reply_msg += "\n\nTOP SUBREDDITS BY COMMENT:\n\n"
  72.         reply_msg += build_table(comments_dict, list_length)        
  73.         sent,status = aa.post_reply(reply_msg, comment, bot_name)
  74.         if sent:
  75.             msg = "REPLY SUCCESS @ %s" % comment.subreddit                                          
  76.             print msg
  77.             logging.info(msg)
  78.             logging.info(reply_msg)
  79.             comment.mark_read()
  80.         else:
  81.             if status == "403 Client Error: Forbidden":
  82.                 msg = "BANNED: %s" % comment.subreddit
  83.                 print msg
  84.                 logging.info(msg)
  85.                 sub = str(comment.subreddit.display_name)
  86.                 append_blacklist(sub)
  87.                 comment.mark_read()                
  88.             else:
  89.                 msg = "REPLY FAILURE @ %s: %s" % (comment.subreddit, status)
  90.                 print msg
  91.                 logging.info(msg)                
  92.     except Exception as e:
  93.         msg = "UNEXPECTED ERROR: %s" % str(e)
  94.         print msg
  95.         logging.error(msg)
  96.  
  97.  
  98. def build_table(tally_dict, list_length):
  99.     # Create sorted list from tally dict in descending order by tally
  100.     sorted_list = sorted(tally_dict.items(),
  101.                   key=operator.itemgetter(1),
  102.                   reverse=True)
  103.     # Shrink post list size if necessary to avoid index error
  104.     list_len = list_length
  105.     if list_len > len(sorted_list):
  106.         list_len = len(sorted_list)
  107.     if list_len == 0:
  108.         return None
  109.     else:
  110.         message = "total | subreddit\n-:|:-"
  111.         for item in sorted_list[:list_len]:
  112.             message += "\n%d | %s" % (item[1], item[0])
  113.         return message
  114.  
  115.  
  116. def get_subreddit_tallies(contrib_list):    
  117.     # Tally number of contributions by subreddit; return dict  
  118.     contrib_dict = {}
  119.     for contrib in contrib_list:
  120.         subreddit = contrib.subreddit
  121.         if subreddit not in contrib_dict.keys():
  122.             contrib_dict[subreddit] = 1
  123.         else:
  124.             contrib_dict[subreddit] += 1
  125.     return contrib_dict
  126.  
  127.  
  128. def append_blacklist(sub):
  129.     # Append blacklist and modify script for future execution
  130.     global blacklist
  131.     bl_old = "blacklist = [%s]" % str(blacklist)[1:-1]
  132.     blacklist.append(sub)
  133.     bl_new = "blacklist = [%s]" % str(blacklist)[1:-1]
  134.     with open("redditbot.py", "r") as f:
  135.         old_text = f.read()
  136.     new_text = old_text.replace(bl_old, bl_new)
  137.     with open("redditbot.py", "w") as f:
  138.         f.write(new_text)
  139.     msg = "BLACKLIST Appended: %s" % sub
  140.     print msg
  141.     logging.info(msg)
  142.  
  143.  
  144. # Log file setup
  145. log_name = raw_input("Log file: ")
  146. if not log_name.endswith(".log"):
  147.     log_name += ".log"
  148. log_format = "%(asctime)s\t%(levelname)s    \t%(message)s"  # DEBUG
  149. logging.basicConfig(level=logging.DEBUG,                    # INFO
  150.                     datefmt="%Y-%m-%d %H:%M:%S",            # WARNING
  151.                     format=log_format,                      # ERROR
  152.                     filename=log_name)                      # CRITICAL
  153. logging.info("Logging started")
  154.  
  155. # Create Reddit instance        
  156. reddit = praw.Reddit(client_id=clientId,
  157.                      client_secret=clientSecret,
  158.                      user_agent=userAgent,
  159.                      username=bot_name,
  160.                      password=password)
  161.  
  162.  
  163. # MAIN LOOP -------------------------------------------------------------
  164.  
  165. while True:
  166.     # Try to reply to new inbox messages if they are username mentions
  167.     for item in reddit.inbox.unread(limit=None):    
  168.         target_user = item.body.split(" ")[1]
  169.         msg = "REQUESTER: %s | TARGET: %s | SUBREDDIT: %s" % \
  170.               (item.author, target_user, item.subreddit)
  171.         print msg
  172.         logging.info(msg)
  173.         target = reddit.redditor(target_user)
  174.         if isinstance(item, praw.models.Comment):
  175.             if item.subreddit in blacklist:
  176.                 msg = "BLACKLIST - request from %s" % item.subreddit
  177.                 print msg
  178.                 logging.info(msg)
  179.                 item.mark_read()            
  180.             else:                        
  181.                 search_and_post(item, target, list_length,
  182.                                 search_depth)
  183.     for i in range(delay):
  184.         time.sleep(1)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement