def test_tweet(self): consumer_key = settings.TWITTER_CONSUMER_KEY consumer_secret = settings.TWITTER_CONSUMER_SECRET access_key = settings.TWITTER_ACCESS_TOKEN_KEY access_secret = settings.TWITTER_ACCESS_TOKEN_SECRET if any(not i for i in [ consumer_key, consumer_secret, access_key, access_secret, ]): LOG.warning("Twitter API credentials not set!") return api = ThreadedApi( consumer_key=consumer_key, consumer_secret=consumer_secret, access_token_key=access_key, access_token_secret=access_secret, ) message = "This is a test long tweet\r\n{}".format("\r\n".join( f"This is line {line}" for line in range(2, 30))) try: if calc_expected_status_length(message) > CHARACTER_LIMIT: api.PostUpdates(message, continuation="…", threaded=True) else: api.PostUpdate(message) except TwitterError as exc: LOG.warning("Hit twitter error: %s", exc) if str(exc) in RETRYABLE_ERRORS: raise self.retry(exc=exc) delay = get_twitter_rate_limit_delay(api) if delay is None: LOG.error("No idea what to do with twitter error %s", exc) raise raise self.retry(countdown=delay, exc=exc)
def tweet_about_beers(self, beer_pks): if not beer_pks: LOG.warning("nothing to do") return LOG.debug("Tweeting about beer PKs: %s", beer_pks) consumer_key = settings.TWITTER_CONSUMER_KEY consumer_secret = settings.TWITTER_CONSUMER_SECRET access_key = settings.TWITTER_ACCESS_TOKEN_KEY access_secret = settings.TWITTER_ACCESS_TOKEN_SECRET if any(not i for i in [ consumer_key, consumer_secret, access_key, access_secret, ]): LOG.warning("Twitter API credentials not set!") return api = ThreadedApi( consumer_key=consumer_key, consumer_secret=consumer_secret, access_token_key=access_key, access_token_secret=access_secret, ) # Mark beers which have been removed from the tap list as tweeted about Beer.objects.filter( tweeted_about=False, taps__isnull=True, ).update(tweeted_about=True) beers = list( Beer.objects.filter( id__in=beer_pks, tweeted_about=False, ).select_related( "manufacturer", "style", ).prefetch_related( Prefetch( "taps", queryset=Tap.objects.select_related("venue"), ), ).order_by("id")) already_tweeted_about = set(i.id for i in Beer.objects.filter( tweeted_about=True, id__in=beer_pks, )) unknown_pks = set(beer_pks).difference(already_tweeted_about) LOG.debug("Got %s beers", len(beers)) if not beers: if unknown_pks: LOG.warning("No beers found! Trying again shortly") raise self.retry(countdown=300) LOG.info("everything was already tweeted about. No big deal") return if len(beers) > 10: LOG.info("Too many beers to tweet about at once: %s", len(beers)) beers = beers[:10] if len(beers) == 1: beer = beers[0] if beer.tweeted_about: LOG.info("%s has already been tweeted about; skipping.", beer) return message = format_beer(beer, SINGLE_BEER_TEMPLATE).strip() messages = [message] else: extra_beers = len(beer_pks) - len(beers) - len(already_tweeted_about) messages = [ MULTI_BEER_OUTER.format( len(beers), "({} still to come!)".format(extra_beers) if extra_beers > 0 else "", ).strip() ] + format_beers(beers) if len(messages) == 1: LOG.info("All beers already tweeted about") return message = "\r\n".join(messages) LOG.info("Going to tweet: %s", message) try: if calc_expected_status_length(message) > CHARACTER_LIMIT: api.PostUpdates(message, continuation="…", threaded=True) else: api.PostUpdate(message) except TwitterError as exc: LOG.warning("Hit twitter error: %s", exc) if str(exc) in RETRYABLE_ERRORS: raise self.retry(exc=exc) LOG.error("Tweet(s) that caused error was %s", message) delay = get_twitter_rate_limit_delay(api) if delay is None: LOG.error("No idea what to do with twitter error %s", exc) raise raise self.retry(countdown=delay, exc=exc) Beer.objects.filter(id__in=[i.id for i in beers]).update(tweeted_about=True) LOG.debug("Done tweeting")
def tweet_about_beers(self, beer_pks): if not beer_pks: LOG.warning('nothing to do') return LOG.debug('Tweeting about beer PKs: %s', beer_pks) consumer_key = settings.TWITTER_CONSUMER_KEY consumer_secret = settings.TWITTER_CONSUMER_SECRET access_key = settings.TWITTER_ACCESS_TOKEN_KEY access_secret = settings.TWITTER_ACCESS_TOKEN_SECRET if any(not i for i in [ consumer_key, consumer_secret, access_key, access_secret, ]): LOG.warning('Twitter API credentials not set!') return api = ThreadedApi( consumer_key=consumer_key, consumer_secret=consumer_secret, access_token_key=access_key, access_token_secret=access_secret, ) beers = list( Beer.objects.filter( id__in=beer_pks, tweeted_about=False, ).select_related( 'manufacturer', 'style', ).prefetch_related( Prefetch( 'taps', queryset=Tap.objects.select_related('venue'), ), ).order_by('id')) already_tweeted_about = set(i.id for i in Beer.objects.filter( tweeted_about=True, id__in=beer_pks, )) unknown_pks = set(beer_pks).difference(already_tweeted_about) LOG.debug('Got %s beers', len(beers)) if not beers: if unknown_pks: LOG.warning('No beers found! Trying again shortly') raise self.retry(countdown=300) LOG.info('everything was already tweeted about. No big deal') return if len(beers) > 10: LOG.info('Too many beers to tweet about at once: %s', len(beers)) beers = beers[:10] if len(beers) == 1: beer = beers[0] if beer.tweeted_about: LOG.info('%s has already been tweeted about; skipping.', beer) return message = format_beer(beer, SINGLE_BEER_TEMPLATE).strip() messages = [message] else: extra_beers = len(beer_pks) - len(beers) - len(already_tweeted_about) messages = [ MULTI_BEER_OUTER.format( len(beers), '({} still to come!)'.format(extra_beers) if extra_beers > 0 else '').strip() ] + format_beers(beers) if len(messages) == 1: LOG.info('All beers already tweeted about') return message = '\r\n'.join(messages) LOG.info('Going to tweet: %s', message) try: if calc_expected_status_length(message) > CHARACTER_LIMIT: api.PostUpdates(message, continuation='…', threaded=True) else: api.PostUpdate(message) except TwitterError as exc: LOG.warning('Hit twitter error: %s', exc) if str(exc) in RETRYABLE_ERRORS: raise self.retry(exc=exc) delay = get_twitter_rate_limit_delay(api) if delay is None: LOG.error('No idea what to do with twitter error %s', exc) raise raise self.retry(countdown=delay, exc=exc) Beer.objects.filter(id__in=[i.id for i in beers]).update(tweeted_about=True) LOG.debug('Done tweeting')