Luke_Username

respectthread_bot.py

Oct 21st, 2018
638
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.00 KB | None | 0 0
  1. import praw
  2. import config
  3. import time
  4. import os
  5. import unicodedata
  6.  
  7. keyword = '!respect'
  8. subreddit_list = ['whowouldwin', 'respectthread_bot']
  9.  
  10. posts_list = []
  11.  
  12. def bot_login():
  13.     print('Logging in...')
  14.     r = praw.Reddit(username = config.username,
  15.                 password = config.password,
  16.                 client_id = config.client_id,
  17.                 client_secret = config.client_secret,
  18.                 user_agent = 'respectthread responder v0.1')
  19.     print('Logged in')
  20.     with open("saved_posts.txt", "a") as f:
  21.         f.write('\n')
  22.     return r
  23.  
  24. class LineResults:
  25.     def __init__(self, linelist, searchResults):
  26.         self.linelist = linelist
  27.         self.searchResults = searchResults
  28.  
  29. def run_bot(r):
  30.     for sub in subreddit_list:
  31.         # loop through every comment on a certain subreddit. Limits to 30 comments.
  32.         quantity = 20
  33.         print('Obtaining ' + str(quantity) + ' comments from r/' + sub + '...')
  34.         for comment in r.subreddit(sub).comments(limit=quantity):
  35.             resultList = []
  36.             replyTo = False
  37.  
  38.             if comment.author != r.user.me() and comment not in posts_list and keyword in comment.body.lower():
  39.                 bodylist = comment.body.split('\n')
  40.                 for line in bodylist:
  41.                     linelist = line.split()
  42.                     if len(linelist) >= 2 and len(line) < 150 and 'https://www.reddit.com/r/respectthreads' not in line and 'https://redd.it' not in line:
  43.                         if summoning_conditional(linelist):
  44.                             searchResults = generate_search_results(linelist)
  45.                             resultList.append(LineResults(linelist, searchResults))
  46.                             replyTo = True
  47.  
  48.                 if replyTo:
  49.                     generate_reply(comment, resultList)
  50.  
  51.     sleep_time = 20
  52.     print('Sleeping for ' + str(sleep_time) + ' seconds...')
  53.     time.sleep(sleep_time)
  54.    
  55. def summoning_conditional(line_list):
  56.     if line_list[0] == '-' or line_list[0] == '*' or line_list[0] == '+':
  57.         line_list.pop(0)
  58.     if line_list[0].lower() == keyword:
  59.         line_list.pop(0)
  60.         if line_list[0].lower() == 'threads':
  61.             return False
  62.         elif line_list[0].lower() == 'thread':
  63.             line_list.pop(0)
  64.             if line_list[0].lower() == 'for':
  65.                 line_list.pop(0)
  66.         return True
  67.     return False
  68.  
  69. def generate_search_results(linelist):
  70.     query = ''
  71.     for string in linelist:
  72.         query += string + ' '
  73.  
  74.     # Remove extra space at end of string
  75.     query = query[:-1]
  76.  
  77.     search_results = r.subreddit('respectthreads').search(query, sort='relevance', syntax='lucene', time_filter='all')
  78.     filteredResults = []
  79.  
  80.     # Separate between bracketed and unbracketed user text, and remove accents.
  81.     bracketedQuery = strip_accents(substring_in_brackets(query))
  82.     unbracketedQuery = strip_accents(substring_out_brackets(query))
  83.  
  84.     # If the user specified the version or verse in brackets
  85.     if len(bracketedQuery) > 0:
  86.         for post in search_results:
  87.             # Separate between bracketed and unbracketed title text, and remove accents.
  88.             bracketedTitle = strip_accents(substring_in_brackets(post.title))
  89.             unbracketedTitle = strip_accents(substring_out_brackets(post.title))
  90.            
  91.             # Check for matches between user text and post title.
  92.             if unbracketedQuery in unbracketedTitle and bracketedQuery in bracketedTitle:
  93.                 filteredResults.append(post)
  94.     # Else if the user only specified the name
  95.     else:
  96.         for post in search_results:
  97.             unbracketedTitle = strip_accents(substring_out_brackets(post.title))
  98.             if unbracketedQuery in unbracketedTitle:
  99.                 filteredResults.append(post)
  100.  
  101.     # In case the user specifies the character name in brackets and no matches are found.
  102.     if len(filteredResults) <= 0:
  103.         # Have to redo the search results.
  104.         search_results = r.subreddit('respectthreads').search(query, sort='relevance', syntax='lucene', time_filter='all')
  105.         for post in search_results:
  106.             # Separate between bracketed and unbracketed title text, and remove accents.
  107.             bracketedTitle = strip_accents(substring_in_brackets(post.title))
  108.             unbracketedTitle = strip_accents(substring_out_brackets(post.title))
  109.             # Swap queries.
  110.             if unbracketedQuery in bracketedTitle and bracketedQuery in unbracketedTitle:
  111.                 filteredResults.append(post)
  112.  
  113.     return filteredResults
  114.  
  115. def substring_in_brackets(query):
  116.     A = list(query)
  117.     inBrackets = False
  118.     c = 0
  119.     while c < len(A):
  120.         if not inBrackets:
  121.             if A[c] == '(' or A[c] == '[':
  122.                 inBrackets = True
  123.             del A[c]
  124.         else:
  125.             if A[c] == ')' or A[c] == ']':
  126.                 inBrackets = False
  127.                 del A[c]
  128.             else:
  129.                 c += 1
  130.  
  131.     return ''.join(A).lower()
  132.  
  133. def substring_out_brackets(query):
  134.     A = list(query)
  135.     inBrackets = False
  136.  
  137.     c = 0
  138.     while c < len(A):
  139.         if not inBrackets:
  140.             if A[c] == '(' or A[c] == '[':
  141.                 inBrackets = True
  142.             else:
  143.                 c += 1
  144.         else:
  145.             if A[c] == ')' or A[c] == ']':
  146.                 inBrackets = False
  147.             del A[c]
  148.    
  149.     return ''.join(A).lower()
  150.  
  151. def strip_accents(text):
  152.     try:
  153.         text = unicode(text, 'utf-8')
  154.     except NameError: # unicode is a default on python 3
  155.         #print("NameError")
  156.         pass
  157.  
  158.     text = unicodedata.normalize('NFD', text).encode('ascii', 'ignore').decode("utf-8")
  159.     return str(text).replace("-", " ").strip() # Remove dashes
  160.  
  161. def generate_reply(comment, result_list):
  162.     reply_text = ''
  163.     max_reply_length = 8000
  164.     too_long = False
  165.     for result in result_list:
  166.         query = ' '.join(result.linelist)
  167.         if result.searchResults:
  168.             reply_text += 'Here\'s what I found on r/respectthreads for *' + query + '*:\n\n'
  169.             for searchResult in result.searchResults:
  170.                 reply_text += '- [' + searchResult.title + '](' + searchResult.shortlink + ')' + '\n\n'
  171.                 if len(reply_text) > max_reply_length:
  172.                     too_long = True
  173.                     break
  174.         else:
  175.             reply_text += 'Sorry, I couldn\'t find anything on r/respectthreads for *' + query + '*\n\n'
  176.             reply_text += 'If you\'re having issues finding a RT, please see the [user instructions](https://redd.it/bd2iv9).' + '\n'
  177.             reply_text += 'If the RT you\'re looking for does not exist, you can [request it](https://redd.it/b5hr1x) or [make it yourself](https://www.reddit.com/r/respectthreads/wiki/introduction_guide).' + '\n\n'
  178.             if len(reply_text) > max_reply_length:
  179.                 too_long = True
  180.                 break
  181.  
  182.         reply_text += '***\n\n'
  183.         if too_long:
  184.             reply_text += 'Some results may be cut off as this reply has gotten too long.' + '\n\n'
  185.             reply_text += '***\n\n'
  186.             break
  187.  
  188.     reply_text += '^(I am a bot) ^| '
  189.     reply_text += '[^(About)](https://redd.it/bd2mld) ^| '
  190.     reply_text += '[^(How to use)](https://redd.it/cljh3v) ^| '
  191.     reply_text += '[^(How to run)](https://redd.it/be38fh) ^| '
  192.     reply_text += '[^(Code)](https://pastebin.com/gaU5qTmD)'
  193.  
  194.     comment.reply(reply_text)
  195.     print(reply_text)
  196.     with open("saved_posts.txt", "a") as f:
  197.         f.write(comment.id + '\n')
  198.     posts_list.append(comment.id)
  199.     result_list = []
  200.  
  201. def get_saved_posts():
  202.     # Make sure the file exists.
  203.     if not os.path.isfile("saved_posts.txt"):
  204.         posts_list = []
  205.     else:
  206.         # "r" is to read from saved_posts.txt as the variable f
  207.         with open("saved_posts.txt", "r") as f:
  208.             posts_list = f.read()
  209.             posts_list = posts_list.split("\n")
  210.     return posts_list
  211.  
  212. posts_list = get_saved_posts()
  213. r = bot_login()
  214. while True:
  215.     run_bot(r)
Add Comment
Please, Sign In to add comment