102 lines
3 KiB
Python
102 lines
3 KiB
Python
from wiki_postbot.creds import Creds
|
|
import tweepy
|
|
import typing
|
|
import re
|
|
from pathlib import Path
|
|
from dataclasses import dataclass
|
|
|
|
@dataclass
|
|
class Author:
|
|
username: str
|
|
name: str
|
|
|
|
|
|
class Thread:
|
|
def __init__(self,
|
|
tweets: typing.List[tweepy.tweet.Tweet],
|
|
responses: typing.List[tweepy.Response]
|
|
):
|
|
self.tweets = tweets
|
|
self.responses = responses
|
|
self.pdf = None
|
|
self.sort()
|
|
|
|
@property
|
|
def text(self) -> str:
|
|
"""
|
|
Text from all the tweets in a thread, double new lines between each
|
|
|
|
also replacing any @'s with markdown links to profiles i guess
|
|
"""
|
|
text = "\n\n".join([t.text for t in self.tweets])
|
|
# make @'s links
|
|
text = re.sub(r"@([\w\d_]{1,})", r"[@\1](https://twitter.com/\1)", text)
|
|
return text
|
|
|
|
@property
|
|
def author(self) -> Author:
|
|
return Author(
|
|
"@" + self.responses[0].includes['users'][0].username,
|
|
self.responses[0].includes['users'][0].name,
|
|
|
|
)
|
|
|
|
@property
|
|
def title(self) -> str:
|
|
return f"{self.author.name}'s thread - {self.tweets[0].created_at.strftime('%y-%m-%d %H:%M')}"
|
|
|
|
def sort(self):
|
|
"""
|
|
sort order of tweets
|
|
"""
|
|
self.tweets = sorted(self.tweets, key=lambda x: x.created_at)
|
|
self.responses = sorted(self.responses, key=lambda x: x.data.created_at)
|
|
|
|
|
|
def to_pdf(self, output_file:typing.Optional[Path]=None,
|
|
) -> Path:
|
|
if output_file is None:
|
|
output_file = Path('.') / f"{self.tweets[0].author_id}_{self.tweets[0].created_at.isoformat()}.pdf"
|
|
|
|
pypandoc.convert_text(
|
|
self.text, to="html", format="md",
|
|
outputfile=str(output_file),
|
|
extra_args = [
|
|
'--pdf-engine=weasyprint',
|
|
f'--data-dir={Path(__file__).parent}',
|
|
'--template=./template.html',
|
|
])
|
|
self.pdf = output_file
|
|
return output_file
|
|
|
|
|
|
@classmethod
|
|
def from_tweet(cls,
|
|
creds:Creds,
|
|
response:tweepy.Response,
|
|
limit:int=100) -> 'Thread':
|
|
"""
|
|
Starting with the mentioned tweet, get all of the tweets in a thread in order
|
|
"""
|
|
tweet = response.data
|
|
client = tweepy.Client(creds.bearer_token)
|
|
tweets = [tweet]
|
|
responses = [response]
|
|
while tweet.referenced_tweets is not None and len(tweet.referenced_tweets)>0 and len(tweets)<=limit:
|
|
replied = [t.id for t in tweet.referenced_tweets if t.type=="replied_to"]
|
|
if len(replied)==0:
|
|
# top tweet was qt
|
|
break
|
|
replied = replied[0]
|
|
response = client.get_tweet(id=replied, tweet_fields=[
|
|
"referenced_tweets",
|
|
"author_id",
|
|
"created_at"
|
|
], expansions=[
|
|
'author_id'
|
|
])
|
|
tweet = response.data
|
|
tweets.append(tweet)
|
|
responses.append(response)
|
|
|
|
return Thread(tweets, responses)
|