Last active
August 28, 2019 08:50
-
-
Save meatyite/300f40a04301975672418807b631ec74 to your computer and use it in GitHub Desktop.
Make twitter DMs from requested twitter data into an actual readable HTML file
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
""" | |
Turns your twitter DMs from the "request your data" feature into readable HTML files | |
You'll need to remove the "window.YTD.direct_message.part0 = " thing from the JS file before running this script | |
You'll also need to extract the archive inside of the "direct_message_media" folder if you want images to show up | |
Please execuse me for this horrible piece of code | |
LICENSED UNDER THE WTFPL, NO COPYRIGHT WHATSOEVER | |
""" | |
import tweeterid | |
import json | |
import sys | |
from urllib.parse import urlparse | |
from os.path import basename | |
def isMediaUrlsNone(mediaUrls, message_id): | |
if '<br/>'.join(mediaUrls) == '': | |
return '[None]<br/>' | |
else: | |
urls_html = "" | |
for media_url in mediaUrls: | |
if media_url.endswith('.mp4') or media_url.endswith('.mp4?tag=1'): | |
urls_html += "<video src={} controls/><br/>".format(media_url) | |
else: | |
urls_html += "<img src={}/><br/>".format("direct_message_media/" + message_id + '-' + basename(urlparse(media_url).path).replace('/', '')) | |
return urls_html | |
import sys | |
def query_yes_no(question, default="no"): | |
""" | |
(yes i stole this from stackoverflow) | |
Ask a yes/no question via input() and return their answer. | |
"question" is a string that is presented to the user. | |
"default" is the presumed answer if the user just hits <Enter>. | |
It must be "yes" (the default), "no" or None (meaning | |
an answer is required of the user). | |
The "answer" return value is True for "yes" or False for "no". | |
""" | |
valid = {"yes": True, "y": True, "ye": True, | |
"no": False, "n": False} | |
if default is None: | |
prompt = " [y/n] " | |
elif default == "yes": | |
prompt = " [Y/n] " | |
elif default == "no": | |
prompt = " [y/N] " | |
else: | |
raise ValueError("invalid default answer: '%s'" % default) | |
while True: | |
sys.stdout.write(question + prompt) | |
choice = input().lower() | |
if default is not None and choice == '': | |
return valid[default] | |
elif choice in valid: | |
return valid[choice] | |
else: | |
sys.stdout.write("Please respond with 'yes' or 'no' " | |
"(or 'y' or 'n').\n") | |
def main(): | |
non_bmp_map = dict.fromkeys(range(0x10000, sys.maxunicode + 1), 0xfffd) | |
original_raw_json = open('direct-message.js', 'r', encoding='utf-8').read() | |
original_json = json.loads(original_raw_json) | |
for dm_conversations_json in original_json: | |
dm_convo_html = "<body>" | |
dm_conversations_json = dm_conversations_json['dmConversation']['messages'][::-1] | |
twitter_ids = {} | |
for _message in dm_conversations_json: | |
message = _message['messageCreate'] | |
sender_id = message['senderId'] | |
recipient_id = message['recipientId'] | |
if not(sender_id in twitter_ids.keys()): | |
twitter_ids[sender_id] = tweeterid.id_to_handle(sender_id) | |
if not(recipient_id in twitter_ids.keys()): | |
twitter_ids[recipient_id] = tweeterid.id_to_handle(recipient_id) | |
sender = twitter_ids[sender_id] | |
dm_convo_html += "<p>({}) [{}]: {}<br/>{}</p>".format(message['createdAt'], sender, message["text"], isMediaUrlsNone(message['mediaUrls'], str(message['id']))) | |
rtl = query_yes_no("Would you like to make this conversation with {} RTL (right to left)?".format(' - '.join(twitter_ids.values()))) | |
if rtl: | |
dm_convo_html += """\ | |
<style> | |
p { | |
direction:RTL | |
} | |
</style> | |
""" | |
else: | |
dm_convo_html += """\ | |
<style> | |
p { | |
direction:LTR | |
} | |
</style> | |
""" | |
dm_convo_html += "</body>" | |
open(' - '.join(twitter_ids.values()) + '.html', 'wb').write(dm_convo_html.encode()) | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment