-
Notifications
You must be signed in to change notification settings - Fork 27
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
587 additions
and
89 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
import logging | ||
import tweepy | ||
|
||
from datetime import datetime | ||
|
||
from exceptions.twitter import ( | ||
AlreadyTweetedError, | ||
ConfigNotFoundError, | ||
TokenNotFoundError, | ||
AchiveUrlNotFoundError, | ||
UpdateStatusError, | ||
) | ||
|
||
|
||
class TwitterHandler: | ||
consumer_key = None | ||
consumer_secret = None | ||
|
||
def __init__(self, consumer_key, consumer_secret): | ||
if not consumer_key or not consumer_secret: | ||
raise ConfigNotFoundError() | ||
|
||
self.consumer_key = consumer_key | ||
self.consumer_secret = consumer_secret | ||
|
||
auth = tweepy.OAuthHandler(self.consumer_key, self.consumer_secret) | ||
auth.secure = True | ||
self.auth = auth | ||
|
||
def api(self, token): | ||
self.auth.set_access_token(token["access_token"], token["access_token_secret"]) | ||
return tweepy.API(self.auth) | ||
|
||
def build_text(self, diff): | ||
text = diff.new.title | ||
if len(text) >= 225: | ||
text = text[0:225] + "…" | ||
text += " " + diff.url | ||
return text | ||
|
||
def create_thread(self, entry, first_version, token): | ||
try: | ||
twitter = self.api(token) | ||
status = twitter.update_status(entry.url) | ||
entry.tweet_status_id_str = status.id_str | ||
entry.save() | ||
|
||
# Save the entry status_id inside the first entryVersion | ||
first_version.tweet_status_id_str = status.id_str | ||
first_version.save() | ||
return status.id_str | ||
except Exception as e: | ||
raise UpdateStatusError(entry) | ||
|
||
def tweet_diff(self, diff, token=None): | ||
if not token: | ||
raise TokenNotFoundError() | ||
elif diff.tweeted: | ||
raise AlreadyTweetedError(diff.id) | ||
elif not (diff.old.archive_url and diff.new.archive_url): | ||
raise AchiveUrlNotFoundError() | ||
|
||
twitter = self.api(token) | ||
text = self.build_text(diff) | ||
|
||
# Check if the thread exists | ||
thread_status_id_str = None | ||
if diff.old.entry.tweet_status_id_str is None: | ||
try: | ||
thread_status_id_str = self.create_thread( | ||
diff.old.entry, diff.old, token | ||
) | ||
logging.info( | ||
"created thread https://twitter.com/%s/status/%s" | ||
% (self.auth.get_username(), thread_status_id_str) | ||
) | ||
except UpdateStatusError as e: | ||
logging.error(str(e)) | ||
else: | ||
thread_status_id_str = diff.old.tweet_status_id_str | ||
|
||
try: | ||
status = twitter.update_with_media( | ||
diff.thumbnail_path, | ||
status=text, | ||
in_reply_to_status_id=thread_status_id_str, | ||
) | ||
logging.info( | ||
"tweeted diff https://twitter.com/%s/status/%s" | ||
% (self.auth.get_username(), status.id_str) | ||
) | ||
# Save the tweet status id inside the new version | ||
diff.new.tweet_status_id_str = status.id_str | ||
diff.new.save() | ||
# And save that the diff has been tweeted | ||
diff.tweeted = datetime.utcnow() | ||
diff.save() | ||
except Exception as e: | ||
logging.error("unable to tweet: %s", e) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
class TwitterError(RuntimeError): | ||
pass | ||
|
||
|
||
class ConfigNotFoundError(TwitterError): | ||
"""Exception raised if the Twitter instance has not the required key and secret""" | ||
|
||
def __init__(self): | ||
self.message = "consumer key/secret not set up for feed." | ||
|
||
|
||
class TokenNotFoundError(TwitterError): | ||
"""Exception raised if no token is preset""" | ||
|
||
def __init__(self): | ||
self.message = "access token/secret not set up for feed" | ||
|
||
|
||
class AlreadyTweetedError(TwitterError): | ||
def __init__(self, diff_id): | ||
self.message = "diff %s has already been tweeted" % diff_id | ||
|
||
|
||
class AchiveUrlNotFoundError(TwitterError): | ||
def __init__(self): | ||
self.message = "not tweeting without archive urls" | ||
|
||
|
||
class UpdateStatusError(TwitterError): | ||
def __init__(self, entry): | ||
self.message = "could not create thread on entry id %s, url %s" % ( | ||
entry.id, | ||
entry.url, | ||
) |
File renamed without changes.
Oops, something went wrong.