#!/usr/bin/env python3
from urllib.error import HTTPError
from urllib.request import urlopen, Request
import logging
# from requests_oauthlib import OAuth1Session
from datetime import datetime
import sys
import json
bearer = None
def _format_date(dt):
"""convert a datetime into an RFC 822 formatted date
Input date must be in GMT.
Stolen from PyRSS2Gen.
"""
# Looks like:
# Sat, 07 Sep 2002 00:00:01 GMT
# Can't use strftime because that's locale dependent
#
# Isn't there a standard way to do this for Python? The
# rfc822 and email.Utils modules assume a timestamp. The
# following is based on the rfc822 module.
return "%s, %02d %s %04d %02d:%02d:%02d GMT" % (
["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"][dt.weekday()],
dt.day,
[
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec",
][dt.month - 1],
dt.year,
dt.hour,
dt.minute,
dt.second,
)
def getBearer():
global bearer
if bearer:
return bearer
headers = {
"Authorization": "Basic Zzl1MXI2SFpYTXg0SXU5UGs5VlNvTzFUdzpmeTIyQjN2QVRRNUI2eGthb1BFdFFRUmtuUGQ1WGZBbnBKVG5hc0ZRa3NyUm5qaVNsaw==",
"Content-Type": "application/x-www-form-urlencoded;charset=UTF-8",
}
data = b"grant_type=client_credentials"
url = "https://api.twitter.com/oauth2/token"
res = urlopen(Request(url, headers=headers, data=data, method="POST"))
response = json.loads(res.read().decode("UTF-8"))
bearer = response["access_token"]
return bearer
def unshorten_urls(title, description, urls):
for url in urls:
shorted_url = url["url"]
long_url = url["expanded_url"]
if "images" in url:
img = url["images"][0]["url"]
long_url_html = ''
else:
long_url_html = '' + long_url + ""
description = description.replace(shorted_url, long_url_html)
title = title.replace(shorted_url, long_url)
return title, description
def twitter(user):
# 500.000 Tweets per month
# API KEY = g9u1r6HZXMx4Iu9Pk9VSoO1Tw
# API SECRET KEY = fy22B3vATQ5B6xkaoPEtQQRknPd5XfAnpJTnasFQksrRnjiSlk
headers = {"authorization": "Bearer " + getBearer()}
# Recent = last 7 days
url = (
"https://api.twitter.com/2/tweets/search/recent?query=from:"
+ user
+ "&tweet.fields=created_at,author_id,lang,source,public_metrics,entities&expansions=referenced_tweets.id,attachments.media_keys&media.fields=url"
)
try:
res = urlopen(Request(url, headers=headers))
response = json.loads(res.read().decode("UTF-8"))
except Exception as exc:
logging.error('Request to twitter failed.', exc_info=exc)
return None
feed = {
'title': 'Twitter: ' + user,
'url': 'https://twitter.com/' + user,
'description': 'The latest entries of the twitter account of ' + user,
'content': []
}
if not response["meta"]["result_count"]:
return feed
feed['content'] = [parse_tweet(
user,
tweet,
response.get("includes", {}).get("tweets", []),
response.get("includes", {}).get("media", []),
) for tweet in response["data"]]
return feed
def parse_tweet(user, tweet, included_tweets, included_media):
title = description = tweet["text"]
link = "https://twitter.com/" + user + "/status/" + str(tweet["id"])
# Check included re-tweets / replace by Retweet
for rt in tweet.get("referenced_tweets", []):
if rt["type"] == "retweeted":
rt_info = title[: title.index(":") + 2]
ref_tweet = next(
t for t in included_tweets if t["id"] == rt["id"]
)
title = rt_info + ref_tweet["text"]
description = rt_info + ref_tweet["text"]
title, description = unshorten_urls(
title, description, ref_tweet.get("entities", {}).get("urls", [])
)
elif rt["type"] == "replied_to":
description += f"
This was a reply to {rt['id']}"
else:
description += f"
Unknown reference type: {rt['type']}"
title, description = unshorten_urls(
title, description, tweet.get("entities", {}).get("urls", [])
)
# Attach media
enclosures = []
included_media_keys = tweet.get('attachments', {}).get('media_keys', [])
for included_media_key in included_media_keys:
ref_media = next(
t for t in included_media if t["media_key"] == included_media_key
)
if 'url' not in ref_media: continue
if ref_media.get('type', '') == 'photo':
description += "
"
else:
enclosures.append(ref_media['url'])
# Append Retweets etc
description += "
"
description += str(tweet["public_metrics"]["retweet_count"]) + " Retweets, "
description += str(tweet["public_metrics"]["like_count"]) + " Likes, "
description += str(tweet["public_metrics"]["reply_count"]) + " Replies, "
description += str(tweet["public_metrics"]["quote_count"]) + " Quotes"
description += "
"
description += "Source: " + tweet["source"]
date = datetime.strptime(tweet["created_at"], "%Y-%m-%dT%H:%M:%S.%fZ")
return {
"title": title,
"url": link,
"content": description,
"date": date,
"enclosures": enclosures,
}
def main(channel):
print(twitter(channel))
if __name__ == "__main__":
if len(sys.argv) != 2:
print("Usage:", sys.argv[0], "")
sys.exit(1)
main(sys.argv[1])
# twitter('rheinbahn_intim')
# twitter('realDonaldTrump')