Guest User

vreddit_bot

a guest
Nov 1st, 2018
1,336
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 11.91 KB | None | 0 0
  1.  
  2. #!/usr/bin/env python3
  3. ######################################################################
  4. ## Reddit Bot that provides downloadable links for v.redd.it videos ##
  5. ######################################################################
  6.  
  7. import praw
  8. import time
  9. import re
  10. import sys
  11. import random
  12. import urllib.request
  13. import os.path
  14. import os
  15. from pystreamable import StreamableApi
  16. import youtube_dl
  17. import smtplib
  18.  
  19.  
  20. donate = 'https://www.reddit.com/r/vreddit_bot/wiki/index'
  21. botPath = '/home/pi/bots/vreddit/'
  22. commentedPath = botPath + 'commented.txt'
  23. footer = ("  \n ***  \n ^^I\'m a Bot *bleep* *bloop* | [**Info**](https://np.reddit.com/r/vreddit_bot/comments/9h41sx/info) | [**Donate**](https://www.reddit.com/r/vreddit_bot/wiki/index)")
  24. format = '.mp4' #Change to .webm for longer processing and lower quality but drastically reduced upload size
  25. uploadText = ''
  26.  
  27. ## Email Variables
  28. sent_from = 'EMAIL'
  29. to = ['EMAIL']
  30. subject = 'Uploading failed'
  31. body = "There was something wrong with the upload"
  32.  
  33. email_text = """\
  34. From: %s
  35. To: %s
  36. Subject: %s
  37.  
  38. %s
  39. """ % (sent_from, ", ".join(to), subject, body)
  40.  
  41. gmail_user = 'USERNAME'
  42. gmail_password = 'PASSWORD'
  43.  
  44. ################
  45. ## SEND EMAIL ##
  46. ################
  47. def sendGmail(gmail_user, gmail_password, sent_from, to, email_text):
  48.     try:
  49.         server = smtplib.SMTP_SSL('smtp.gmail.com', 465)
  50.         server.ehlo()
  51.         server.login(gmail_user, gmail_password)
  52.         server.sendmail(sent_from, to, email_text)
  53.         server.close()
  54.  
  55.         print('E-mail sent!')
  56.     except:
  57.         print('Something went wrong when sending E-Mail...')
  58. ######################
  59.  
  60.  
  61. api = StreamableApi('USERNAME', 'PASSWORD')
  62.  
  63.  
  64.  
  65. def replying(mention, reply):
  66.     #Replying to comment
  67.     file_obj_r = open(commentedPath,'r')
  68.     if mention.id not in file_obj_r.read().splitlines():
  69.         print('Replying... \n')
  70.         try:
  71.             mention.reply(reply + footer)
  72.             file_obj_r.close()
  73.  
  74.             file_obj_w = open(commentedPath,'a+')
  75.             file_obj_w.write(mention.id + '\n')
  76.             file_obj_w.close()
  77.  
  78.         #Send PM if replying went wrong (Should only happen if the bot is banned)
  79.         except:
  80.             sub = str(mention.subreddit)
  81.             pm = reply + footer
  82.             subject = 'I\'m probably banned in r/' + sub + ', so you get a PM instead ;)'
  83.             print('Error when replying, probably banned. Replying per PM.')
  84.             reddit.redditor(author).message(subject, pm)
  85.             file_obj_r.close()
  86.  
  87.             file_obj_w = open(commentedPath,'a+')
  88.             file_obj_w.write(mention.id + '\n')
  89.             file_obj_w.close()
  90.  
  91. #Authenticate via praw.ini file, look at praw documentation for more info
  92. def authenticate():
  93.  
  94.     print('Authenticating...\n')
  95.     reddit = praw.Reddit('vreddit', user_agent = 'vreddit')
  96.     print('Authenticated as {}\n'.format(reddit.user.me()))
  97.     return reddit
  98.  
  99.  
  100. #############
  101. ## RUN BOT ##
  102. #############
  103.  
  104. def run_bot(reddit):
  105.     #Search mentions in inbox
  106.     for mention in reddit.inbox.mentions(limit=10):
  107.  
  108.         parent = mention.parent()
  109.         submissionURL = mention.submission.url
  110.         submissionID = mention.submission.id
  111.         submissionTitle = mention.submission.title
  112.         author = str(mention.author)
  113.         shouldUpload = False
  114.         downloadTime = 0
  115.         uploadTime = 0
  116.  
  117.  
  118.         downloadedPath= botPath + 'downloaded/' + str(submissionID) + format
  119.         uploadedPath = botPath + 'uploaded/' + str(submissionID) + '.txt'
  120.  
  121.         #Reply condition
  122.         matchVreddit = 'v.redd.it' in submissionURL
  123.  
  124.         if matchVreddit:
  125.             mention.upvote()
  126.  
  127.             #Generate downloadable v.redd.it URL, saves uploading bandwidth
  128.             try:
  129.                 media_url = mention.submission.media['reddit_video']['fallback_url']
  130.                 media_url = str(media_url)
  131.                 audio_url = media_url.rpartition('/')[0] + '/audio'
  132.                 shouldUpload = False
  133.             #Upload if something doesn't work out (Usually a x-posted link which doesn't get recognized for some reason, fix in the future)
  134.             except Exception as e:
  135.                 #print(e) #Uncomment to see error
  136.                 media_url = submissionURL
  137.                 shouldUpload = True
  138.  
  139.  
  140.             #Workaround to check if v.redd.it link has audio, raises exception if it doesn't.
  141.             try:
  142.                 req = urllib.request.Request(audio_url)
  143.                 resp = urllib.request.urlopen(req)
  144.                 respData = resp.read()
  145.                 shouldUpload = True
  146.             except:
  147.                 audio = False #Needs something here
  148.  
  149.  
  150.             #shouldUpload = True #Uncomment for always upload
  151.  
  152.             #Check if the file was downloaded or uploaded before
  153.             downloaded = os.path.exists(downloadedPath)
  154.             uploaded = os.path.exists(uploadedPath)
  155.  
  156.  
  157.             #Check if file has already been uploaded (if the .txt file with the link was generated before, to avoid uploading the same video multiple times)
  158.             if uploaded:
  159.                 try:
  160.                     with open(uploadedPath, 'r') as content_file:
  161.                         uploadedURL = content_file.read()
  162.                         txt = True
  163.  
  164.                 except Exception as e:
  165.                     print(e)
  166.                     print("Couldn't get URL, continuing..")
  167.             else:
  168.                 txt = False
  169.  
  170.             #DOWNLOAD
  171.             if shouldUpload and not uploaded:
  172.                 if not downloaded and not uploaded:
  173.                     try:
  174.                         print('Downloading "' + submissionTitle + '"')
  175.                         ydl_opts = {
  176.                         'outtmpl': downloadedPath,
  177.                         #'format': 'bestvideo',        #uncomment for video without audio only, see youtube-dl documentation
  178.                         'max_filesize': int('200000000'),
  179.                         'ratelimit': 2000000,
  180.                         }
  181.                         with youtube_dl.YoutubeDL(ydl_opts) as ydl:
  182.                             startTimeDownload = time.time()
  183.                             ydl.download([submissionURL])
  184.  
  185.                         downloaded = True
  186.                         downloadTime = time.time() - startTimeDownload
  187.                     except Exception as e:
  188.                         print('ERROR: Downloading failed.')
  189.                         print(e)
  190.  
  191.                         downloaded = False
  192.                 elif downloaded and not uploaded:
  193.                     print('Already downloaded "' + submissionTitle + '"')
  194.  
  195.             elif not shouldUpload:
  196.                 uploadedURL = media_url
  197.  
  198.             #Check again if downloaded file exists now
  199.             downloaded = os.path.exists(downloadedPath)
  200.  
  201.  
  202. ###########################
  203.             ## UPLOADING ##
  204.             ###############
  205.  
  206.             if downloaded and not uploaded and shouldUpload:
  207.  
  208.                 try:
  209.                     print('Uploading file.')
  210.                     startTime = time.time()
  211.  
  212.                     stream = api.upload_video(downloadedPath, submissionID)
  213.                     shortcode = stream['shortcode']
  214.                     uploadedURL = 'https://streamable.com/' + shortcode
  215.                     print("Successfully uploaded: " + uploadedURL)
  216.                     uploadTime = time.time() - startTime
  217.                     uploaded = True
  218.                     #Delete downloaded file
  219.                     try:
  220.                         print('Deleting downloaded file.')
  221.                         os.remove(downloadedPath)
  222.                     except Exception as e:
  223.                         print(e)
  224.                         print("ERROR: Can't remove file.")
  225.  
  226.                 except Exception as e:
  227.                     print(e)
  228.                     print("ERROR: Can't upload file. Sending email and terminating..")
  229.                     sendGmail(gmail_user, gmail_password, sent_from, to, email_text)
  230.                     uploaded = False
  231.                     sys.exit()
  232.  
  233.  
  234.  
  235. #########################
  236.             ## REPLYING #
  237.             #############
  238.  
  239.             #Generate normal comment reply string
  240.             if uploaded or not shouldUpload:
  241.                 if uploaded and not txt:
  242.                     timeText = "\n\nIt took " + "%.f" % downloadTime + " seconds to download " \
  243.                         + "and " + "%.f" % uploadTime + " seconds to upload.\n"
  244.                 else:
  245.                     timeText = ""
  246.                 try:
  247.                     reply = "Downloadable link: " + uploadedURL + timeText
  248.                 except Exception as e:
  249.                     print(e)
  250.  
  251.             #Generate reply string if something went wrong
  252.             elif (not downloaded or not uploaded) and shouldUpload:
  253.                 try:
  254.                     media_url = mention.submission.media['reddit_video']['fallback_url']
  255.                     reply = 'Sorry, there was a problem. [Here](' + media_url + ') is a downloadable v.redd.it link without audio.'
  256.                 except:
  257.                     reply = 'Sorry, something went wrong :( If the submission is a x-post, try mentioning my name on the original post.'
  258.  
  259.    
  260.             #Replying to comment
  261.             file_obj_r = open(commentedPath,'r')
  262.             if mention.id not in file_obj_r.read().splitlines():
  263.                 print('Replying... \n')
  264.                 try:
  265.                     mention.reply(reply + footer)
  266.                     file_obj_r.close()
  267.  
  268.                     file_obj_w = open(commentedPath,'a+')
  269.                     file_obj_w.write(mention.id + '\n')
  270.                     file_obj_w.close()
  271.  
  272.                 #Send PM if replying went wrong (Should only happen if the bot is banned)
  273.                 except:
  274.                     message = "\n\nIf you wanna help, you could edit your original post to include my link :)"
  275.                     sub = str(mention.subreddit)
  276.                     pm = reply + message + footer
  277.                     subject = 'I\'m probably banned in r/' + sub + ', so you get a PM instead ;)'
  278.                     print('Error when replying, probably banned. Replying per PM.')
  279.                     reddit.redditor(author).message(subject, pm)
  280.                     file_obj_r.close()
  281.  
  282.                     file_obj_w = open(commentedPath,'a+')
  283.                     file_obj_w.write(mention.id + '\n')
  284.                     file_obj_w.close()
  285.  
  286.  
  287. #########################
  288.             ## FINISH  ##
  289.             #############
  290.             #Create .txt file with streamable link, named after the submission ID
  291.             if uploaded and not txt:
  292.                 try:
  293.                     print('Creating txt file.')
  294.                     f = open(uploadedPath,"w+")
  295.                     f.write(uploadedURL)
  296.                     f.close()
  297.                 except Exception as e:
  298.                     print(e)
  299.                     print("ERROR: Can't create txt file.")
  300.  
  301.         else:
  302.             reply = 'Sorry, I only work with v.redd.it links.'
  303.             #Replying to comment
  304.             file_obj_r = open(commentedPath,'r')
  305.             if mention.id not in file_obj_r.read().splitlines():
  306.                 print('Replying... \n')
  307.                 try:
  308.                     mention.reply(reply + footer)
  309.                     file_obj_r.close()
  310.  
  311.                     file_obj_w = open(commentedPath,'a+')
  312.                     file_obj_w.write(mention.id + '\n')
  313.                     file_obj_w.close()
  314.  
  315.                 #Send PM if replying went wrong (Should only happen if the bot is banned)
  316.                 except:
  317.                     print('Error when replying and no valid link.')
  318.                     file_obj_r.close()
  319.  
  320. #########################
  321.  
  322.     #print('Waiting 5 seconds...\n')
  323.     time.sleep(5)
  324.  
  325.  
  326. def main():
  327.     reddit = authenticate()
  328.     while True:
  329.         run_bot(reddit)
  330.  
  331.  
  332.  
  333. if __name__ == '__main__':
  334.         main()
Add Comment
Please, Sign In to add comment