Created
April 22, 2021 14:20
-
-
Save j6k4m8/23fed7b448e5810c32aed0dcdc90f82a to your computer and use it in GitHub Desktop.
Download an archive of a user's tweets and render a simple HTML page (no JS required)
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
{ | |
"cells": [ | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"username = \"j6m8\"" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"!twint -u {username} --images -o {username}_images.csv --csv" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"import pandas as pd\n", | |
"from tqdm.auto import tqdm" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"df = pd.read_csv(f\"{username}_images.csv\", sep=\"\\t\")" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"!mkdir -p images\n", | |
"for photorow in tqdm(df.photos):\n", | |
" for photo_url in eval(photorow):\n", | |
" fname = photo_url.split(\"/\")[-1]\n", | |
" !wget {photo_url} -O images/{fname}" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"df.columns" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"def images_from_tweet(tweet):\n", | |
" t = \"\"\n", | |
" for im in eval(tweet.photos):\n", | |
" t += f\"<img src='images/{im.split('/')[-1]}' />\"\n", | |
" return t\n", | |
"\n", | |
"tweets_html = \"\\n\".join(\n", | |
"\n", | |
" f\"\"\"\n", | |
" <article>\n", | |
" <h3><a href=\"https://twitter.com/{username}/status/{tweet.id}\">@{tweet.username} on {tweet.date}</a></h3>\n", | |
" <p>{tweet.tweet}</p>\n", | |
" <div class=\"img-container\">{images_from_tweet(tweet)}</div>\n", | |
" </article>\n", | |
" \"\"\"\n", | |
" for i, tweet in df.iterrows()\n", | |
" \n", | |
")" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"styles = \"\"\"\n", | |
"\n", | |
"* {\n", | |
" box-sizing: border-box;\n", | |
"}\n", | |
"\n", | |
"body {\n", | |
" font-family: sans-serif;\n", | |
" background: linear-gradient(rgb(224, 231, 255), rgb(237, 233, 254));\n", | |
"}\n", | |
"\n", | |
".tweets {\n", | |
" width: 50vw;\n", | |
" min-width: 30em;\n", | |
" max-width: 100vw;\n", | |
" margin: auto;\n", | |
"}\n", | |
"\n", | |
"article {\n", | |
" padding: 2em;\n", | |
" box-shadow: rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(0, 0, 0, 0.1) 0px 4px 6px -1px, rgba(0, 0, 0, 0.06) 0px 2px 4px -1px;\n", | |
" margin: 1em;\n", | |
" border-radius: 5px;\n", | |
" background: white;\n", | |
"}\n", | |
"\n", | |
"article .img-container {\n", | |
" display: grid;\n", | |
" flex-wrap: wrap;\n", | |
" justify-content: space-around;\n", | |
" grid-template-columns: auto auto auto;\n", | |
"}\n", | |
"\n", | |
"article img {\n", | |
" width: 95%;\n", | |
" margin: auto;\n", | |
"}\n", | |
"\n", | |
"\"\"\"\n", | |
"\n", | |
"html = f\"\"\"\n", | |
"\n", | |
"<html>\n", | |
"\n", | |
"<head>\n", | |
"<title>Archive: @{username}</title>\n", | |
"<style>{styles}</style>\n", | |
"</head>\n", | |
"\n", | |
"<body>\n", | |
"\n", | |
"<div class=\"tweets\">{tweets_html}</div>\n", | |
"\n", | |
"</body>\n", | |
"<script>\n", | |
"const data = {df.T.to_json()}\n", | |
"</script>\n", | |
"</html>\n", | |
"\n", | |
"\"\"\"\n", | |
"\n", | |
"with open(\"index.html\", \"w\") as fh:\n", | |
" fh.write(html)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [] | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"display_name": "Python 3", | |
"language": "python", | |
"name": "python3" | |
}, | |
"language_info": { | |
"codemirror_mode": { | |
"name": "ipython", | |
"version": 3 | |
}, | |
"file_extension": ".py", | |
"mimetype": "text/x-python", | |
"name": "python", | |
"nbconvert_exporter": "python", | |
"pygments_lexer": "ipython3", | |
"version": "3.7.7" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 4 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment