0

I wrote a Twitter bot that posts every now and then an image from reddit. I am hosting this script on a raspberry pi 4 and I would like it to run 24/7. However, after a while I get the next error:

tweepy.error.TweepError: Failed to send request:HTTPSConnectionPool(host='api.twitter.com', port=443): Max retries exceeded with url: /1.1/statuses/update_with_medi.json?status=https%3A%2F%2Fredd.it%2kftmohf (Caused by NewConnectionError('<urllib3.connection.VerifiedHTTPSConnection object at 0xb4771550>: Failed to establish a new connection:[Errno -3] Temporary failure in name resolution'))

I think that what is happening is that it can not reach Twitter for whatever reason. What I am looking for is how can I fix this from happening or in case it is not avoidable how can I retry later to run again the program.

Thanks in advance.

Here is the full code in case you need it:

import praw
import json
import urllib.request
import tweepy
import time
import datetime
import os
import fnmatch
from PIL import Image  
import urllib.parse
from glob import glob
import wget

# Place your Twitter API keys here
ACCESS_TOKEN = 'ACCESS_TOKEN '
ACCESS_TOKEN_SECRET = ACCESS_TOKEN_SECRET 
CONSUMER_KEY = 'CONSUMER_KEY' 
CONSUMER_SECRET = 'CONSUMER_SECRET'

#Reddit we want to pick images from
SUBREDDIT = 'learnpython'

#Directory to save the images
PATH = '/home/pi/Desktop/img/'

#TXT file to save the posts you have already posted
POSTED_CACHE = 'posted_posts.txt'

#Max size images can be because twitter has a limit
MAX_SIZE = 3070000

#Reddit shorter url
REDDIT_URL = 'https://redd.it/'

#Time to rest between tweets or we will get banned from twitter
TIME_TO_SLEEP = 1800 #set on 30 minutes but should not be less than 20

reddit = praw.Reddit(
                        user_agent='user agen',
                        client_id='client id',
                        client_secret='client secret')


#See in the sub what posts have pngs or jpgs so you can post the images on twitter
#and get everything ready to be tweeted
def tweet_creator():
    post_ids = []
    post_urls = []

    subreddit = reddit.subreddit(SUBREDDIT)
    
    for submission in subreddit.hot(limit = 55):
        if not already_tweeted(submission.id):
            if '.png' in submission.url or '.jpg' in submission.url:
                get_image(submission.id, submission.url)
                if not too_big(submission.id,submission.url):
                    post_ids.append(submission.id)
                    post_urls.append(submission.url)
    print('[bot] Se han recopilado:'+str(len(post_ids))+' imagenes')
    return post_ids, post_urls
        

#This is the important function that will post the tweets and loop itself 
#for 20 or 30 hours because of the delay we talk about before 
def tweeter(posts_ids, posts_urls):
    auth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)
    auth.set_access_token(ACCESS_TOKEN, ACCESS_TOKEN_SECRET)
    api = tweepy.API(auth)

    for i in range(0, len(posts_ids)):
        api.update_with_media(filename = PATH + posts_ids[i] + posts_urls[i][-4:], status = REDDIT_URL+posts_ids[i] )
        print('[bot:'+str(datetime.datetime.now().hour)+':'+str(datetime.datetime.now().minute)+':'+str(datetime.datetime.now().second)+'] posting link on twitter: redd.it/' + posts_ids[i])
        log_tweet(posts_ids[i])
        time.sleep(TIME_TO_SLEEP)
    print('[bot] Se acabaron los tweets')

#Get the image
def get_image(ids, url):
    opener = urllib.request.build_opener()
    opener.addheaders=[('User-Agent','Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1941.0 Safari/537.36')]
    urllib.request.install_opener(opener)
    #some help in case I forget how this work https://stackoverflow.com/questions/34692009/download-image-from-url-using-python-urllib-but-receiving-http-error-403-forbid

    urllib.request.urlretrieve(url, PATH+ids+url[-4:])

#Check the image is not too big
def too_big(ids,urls):
    found = False

    if os.path.getsize(PATH+ids+urls[-4:]) > MAX_SIZE:
        print('[bot]la imagen:' + ids+urls[-4:]+' es muy grande')
        log_tweet(ids)
        os.remove(PATH+ids+urls[-4:])
        found = True
    return found

#Check if the image has been already tweeted
def already_tweeted(ids):
    found = False
    with open(POSTED_CACHE, 'r') as in_file:
        for line in in_file:
            if ids in line:
                found = True
                break
    return found

#In case it has not been tweeted jet write it's id in the TXT
def log_tweet(ids):
    with open(POSTED_CACHE, 'a') as out_file:
        out_file.write(str(ids) + '\n')

def main():

    posts_ids, posts_urls = tweet_creator()
    tweeter(posts_ids, posts_urls)

#Loop forever
while True:
    main()

1 Answers1

0

This program is developed in China, because for some reason, China is prohibited to visit Twitter. So I use a proxy named shadowsockets, it can set the mode to global.

this may help you

Darkknight
  • 1,716
  • 10
  • 23