refactor, and remove nowrap

This commit is contained in:
wassname
2025-01-01 15:39:39 +08:00
parent 9beb1fcc45
commit c70ea8add3
8 changed files with 2714 additions and 2019 deletions
+1 -1
View File
@@ -58,7 +58,7 @@
<a href="https://github.com/wassname/scrape_r_rational">source code</a>
<div class="tabl">
<table id="myTable" class="table table-sm table-striped table-bordered nowrap" style="width:100%"></table>
<table id="myTable" class="table table-sm table-striped table-bordered" style="width:100%"></table>
</div>
</body>
+8 -117
View File
@@ -5237,15 +5237,6 @@
"print(f\"{len(df_links3)} -> {len(df3)} after title dedup\")"
]
},
{
"cell_type": "code",
"execution_count": 69,
"metadata": {},
"outputs": [],
"source": [
"# df3.iloc[3]['url']"
]
},
{
"cell_type": "markdown",
"metadata": {},
@@ -5255,41 +5246,11 @@
},
{
"cell_type": "code",
"execution_count": 70,
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def format_flair(author_flair_text):\n",
" if author_flair_text:\n",
" return f\" <em>{author_flair_text}</em>\"\n",
" return \"\"\n",
"\n",
"import markdown\n",
"def commentmd2html(x: dict) -> str:\n",
" body = markdown.markdown(x['body'])\n",
" ts = pd.to_datetime(x['created_utc'], unit='s').strftime('%Y-%m-%d')\n",
" flair = format_flair(x['author_flair_text'])\n",
" url = prefix + x['permalink']\n",
" s = f\"\"\"<h3><a href=\"{url}\">{x.get('author', 'anon')} [{x['score']:+}] {flair} <sup>{ts}</sup></a></h3>\n",
"{body}\n",
"\"\"\"\n",
" # print(s)\n",
" return s\n",
"\n",
"def collapsibe(title, body):\n",
" return f\"\"\"<details><summary>{title}</summary>\n",
"{body}\n",
"</details>\n",
"\"\"\"\n",
"\n",
"prefix = \"https://reddit.com\"\n",
"def c2md(x):\n",
" return collapsibe(x['id'], commentmd2html(x))\n",
"\n",
"# # QC test\n",
"# x = df3.iloc[0].comments[0]\n",
"# from IPython.display import display, HTML\n",
"# display(HTML(c2md(x)))"
"from rrational.transform import join_uniq, chain_lists, format_flair, c2md, collapsibe, urls2a,url2a, unique_elements "
]
},
{
@@ -5317,33 +5278,6 @@
"d = df3.reset_index().sort_values(\"score\", ascending=False)\n",
"\n",
"\n",
"def url2a(url):\n",
" text = url\n",
" if \"reddit.com/r/rational\" in url:\n",
" text = url.split(\"/\")[-2]\n",
" # text = url.replace('https://reddit.com/r/rational/comments/', '')\n",
"\n",
" return f'<a href=\"{url}\">{text}</a>'\n",
"\n",
"\n",
"from collections import OrderedDict\n",
"def unique_elements(lst):\n",
" return list(OrderedDict.fromkeys(lst))\n",
"\n",
"def urls2a(urls, sep=None):\n",
" if isinstance(urls, str):\n",
" urls = urls.split(\"\\n\")\n",
"\n",
" # get uniques from list, keep in same order\n",
" urls = unique_elements(urls)\n",
"\n",
" a_els = [url2a(u) for u in urls]\n",
"\n",
" # now make into a html list\n",
" if sep is None:\n",
" return \"<ul>\" + \"\".join([f\"<li>{x}</li>\" for x in a_els]) + \"</ul>\"\n",
" else:\n",
" return sep.join(a_els)\n",
"\n",
"# make title have a link to first url\n",
"d['title'] = d.progress_apply(lambda x: f'<a href=\"{x[\"url\"][0]}\">{x[\"title\"]}</a>', axis=1)\n",
@@ -5361,13 +5295,6 @@
"d['last_link_utc'] = d['last_link_utc'].dt.strftime('%Y-%m-%d')\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": 72,
@@ -5636,51 +5563,15 @@
},
{
"cell_type": "code",
"execution_count": 85,
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'[{\"title\": \"title\", \"visible\": true, \"searchable\": true, \"footer\": \"title\"}, {\"title\": \"score\", \"visible\": true, \"searchable\": true, \"footer\": \"score\"}, {\"title\": \"#link\", \"visible\": true, \"searchable\": true, \"footer\": \"#link\"}, {\"title\": \"#comment\", \"visible\": true, \"searchable\": true, \"footer\": \"#comment\"}, {\"title\": \"first_link\", \"visible\": false, \"searchable\": false, \"footer\": \"first_link\"}, {\"title\": \"last_link\", \"visible\": false, \"searchable\": false, \"footer\": \"last_link\"}, {\"title\": \"urls\", \"visible\": true, \"searchable\": true, \"footer\": \"urls\"}, {\"title\": \"threads\", \"visible\": true, \"searchable\": true, \"footer\": \"threads\"}, {\"title\": \"comments\", \"visible\": false, \"searchable\": false, \"footer\": \"comments\"}]'"
]
},
"execution_count": 85,
"metadata": {},
"output_type": "execute_result"
}
],
"outputs": [],
"source": [
"# put into the html template\n",
"import jinja2\n",
"\n",
"environment = jinja2.Environment()\n",
"template = open(\"../index.jinja2.html\").read()\n",
"template = environment.from_string(template)\n",
"\n",
"\n",
"data = d.to_json(orient=\"values\")\n",
"\n",
"hidden = [\"comments\", \"first_link\", \"last_link\"]\n",
"columns = [\n",
" {\n",
" \"title\": c,\n",
" \"visible\": c not in hidden,\n",
" \"searchable\": c not in hidden,\n",
" \"footer\": c,\n",
" }\n",
" for c in d.columns\n",
"]\n",
"columns = json.dumps(columns)\n",
"\n",
"\n",
"html = template.render(\n",
" data=data,\n",
" columns=columns,\n",
")\n",
"from rrational.export import export_df_2_html\n",
"html_out = Path(\"../index2.html\").resolve()\n",
"open(html_out, \"w\").write(html)\n",
"columns"
"export_df_2_html(df=d, output=html_out,\n",
" hidden_columns=[\"comments\", \"first_link\", \"last_link\"],\n",
")"
]
},
{
+147 -1206
View File
File diff suppressed because it is too large Load Diff
+1703
View File
File diff suppressed because it is too large Load Diff
Generated
+679 -695
View File
File diff suppressed because it is too large Load Diff
View File
+52
View File
@@ -0,0 +1,52 @@
from io import BytesIO
import base64
import gzip
import jinja2
import pandas as pd
from pathlib import Path
import json
from IPython.display import HTML, display
def base64_gzip_encode(data: str) -> str:
"""because there is a lot of uncompressed text data, we can compress it to gzip and store as base64. This isn't perfect but it's simple and works with a single static page"""
buf = BytesIO()
compressGzip = gzip.GzipFile(fileobj=buf, mode="wb")
compressGzip.write(data.encode())
compressGzip.close()
buf.seek(0)
b64str = base64.b64encode(buf.getvalue()).decode()
return b64str
def export_df_2_html(df: pd.DataFrame = None, template: Path=Path( "../index.jinja2.html"), output: Path = Path("../index.html"), columns:list = None, hidden_columns: list = []):
"""
"""
environment = jinja2.Environment()
template_o = open("../index.jinja2.html").read()
template_o = environment.from_string(template_o)
columns = [
{
"title": c,
"visible": c not in hidden_columns,
"searchable": c not in hidden_columns,
"footer": c,
"name": c+"2",
}
for c in df.columns
]
columns = json.dumps(columns)
b64str = base64_gzip_encode(df.to_json(orient="values"))
html = template_o.render(
data=b64str,
columns=columns,
)
html_out = Path(output).resolve()
open(html_out, "w").write(html)
htmla = f'<a href="{html_out}">View the page {html_out}</a>'
display(HTML(htmla))
+124
View File
@@ -0,0 +1,124 @@
import markdown
import pandas as pd
import json
import collections, itertools
from collections import OrderedDict
def join_uniq(x: list[str]):
return "\n".join(set(x))
def chain_lists(x: list[list[str]]):
return [item for sublist in x for item in sublist]
def format_flair(author_flair_text):
if author_flair_text:
return f" <em>{author_flair_text}</em>"
return ""
def commentmd2html(x: dict) -> str:
"""convert a comment to html"""
body = markdown.markdown(x['body'])
ts = pd.to_datetime(x['created_utc'], unit='s').strftime('%Y-%m-%d')
flair = format_flair(x['author_flair_text'])
url = prefix + x['permalink']
s = f"""<h3><a href="{url}">{x.get('author', 'anon')} [{x['score']:+}] {flair} <sup>{ts}</sup></a></h3>
{body}
"""
# print(s)
return s
def collapsibe(title, body):
"""make a collapsible html element"""
return f"""<details><summary>{title}</summary>
{body}
</details>
"""
prefix = "https://reddit.com"
def c2md(x):
"""md comment to html"""
return collapsibe(x['id'], commentmd2html(x))
def url2a(url):
"""url to a tag"""
text = url
if "reddit.com/r/rational" in url:
text = url.split("/")[-2]
# text = url.replace('https://reddit.com/r/rational/comments/', '')
return f'<a href="{url}">{text}</a>'
def unique_elements(lst):
"""get unique elements but unlike a set, keep them ordered."""
return list(OrderedDict.fromkeys(lst))
def urls2a(urls, sep=None):
"""urls to a tags"""
if isinstance(urls, str):
urls = urls.split("\n")
# get uniques from list, keep in same order
urls = unique_elements(urls)
a_els = [url2a(u) for u in urls]
# now make into a html list
if sep is None:
return "<ul>" + "".join([f"<li>{x}</li>" for x in a_els]) + "</ul>"
else:
return sep.join(a_els)
import numpy as np
def auto_transform_to_html(d):
for c in d.columns:
# if the cols is a lists of strings
is_list = d[c].apply(lambda x: isinstance(x, (list, tuple, np.ndarray))).all()
is_list_str = is_list and d[c].apply(lambda x: (x is None) or (len(x)==0) or isinstance(x[0], str)).all()
is_str = d[c].apply(lambda x: isinstance(x, str)).all()
is_list_of_urls = is_list_str and d[c].apply(lambda x: (len(x)==0) or x[0].startswith("http")).all()
is_urls = is_str and d[c].apply(lambda x: x.startswith("http")).all()
is_url = d[c].apply(lambda x: isinstance(x, str)).all() and d[c].apply(lambda x: x.startswith("http")).all()
is_list_obj = is_list and d[c].apply(lambda x: isinstance(x, dict)).all()
print(f"{c}, is_list={is_list}, is_list_str={is_list_str}, is_list_url={is_list_of_urls}, is_url={is_url}, is_urls={is_urls}, is_list_obj={is_list_obj}\n")
# if columns contains str: urls
if is_urls:
d[c] = d[c].apply(lambda x: url2a(x))
# elif c.endswith("urls"):
# d[c] = d[c].apply(lambda x: collapsibe('...', urls2a(x)))
# elif c.endswith("url"):
# d[c] = d[c].apply(lambda x: url2a(x))
elif is_list_of_urls:
d[c] = d[c].apply(lambda x: collapsibe('...', urls2a(x)))
elif is_list_str:
d[c] = d[c].apply(lambda x: join_uniq(x))
# if float, round to 2 decimal places
elif d[c].dtype == float:
d[c] = d[c].apply(lambda x: round(x, 2))
# if column name ends with utc
elif c.endswith("utc"):
d[c] = pd.to_datetime(d[c], unit='s').dt.strftime('%Y-%m-%d')
elif is_list:
# TODO object to json using pandas.io.json.dumps
# from pandas.io.json._json import to_json
from pandas._libs.json import ujson_dumps
d[c] = d[c].apply(lambda x: collapsibe('...', ujson_dumps(x, indent=2)))
# make title have a link to first url
d['title'] = d.apply(lambda x: f'<a href="{x["url"][0]}">{x["title"]}</a>', axis=1)
return d