added a notebook for peertube data gathering
This commit is contained in:
1 parent
ff2a92194b
commit
37fd38f1b0
4 files changed
+266
No files matched your search
@@ -0,0 +1,17 @@
|
||||
## Statistiche per nerd da Peer Tube
|
||||
|
||||
spero funzioni
|
||||
|
||||
per installarlo baste creare un nuovo ambiente e installare le dipendenze con:
|
||||
|
||||
```
|
||||
python -m venv env
|
||||
source .\env\bin\activate
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
per eseguire il tutto basta lanciare:
|
||||
|
||||
```
|
||||
jupyter-lab
|
||||
```
|
||||
@@ -0,0 +1,3 @@
|
||||
jupyterlab==4.1.2
|
||||
selenium==4.18.1
|
||||
schedule
|
||||
@@ -0,0 +1,238 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "27784c31-2579-4c9f-802a-de9b9e1471d1",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Statistiche per Nerd homebrew"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"id": "5d3f30ae-baa7-4703-870f-921829fd8c34",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import schedule\n",
|
||||
"import signal\n",
|
||||
"import json\n",
|
||||
"import time\n",
|
||||
"from bs4 import BeautifulSoup as bs\n",
|
||||
"from selenium import webdriver\n",
|
||||
"from selenium.webdriver.chrome.options import Options\n",
|
||||
"from selenium.webdriver.common.by import By\n",
|
||||
"from selenium.webdriver import ActionChains\n",
|
||||
"from selenium.webdriver.support.wait import WebDriverWait\n",
|
||||
"from selenium.webdriver.support import expected_conditions as ec\n",
|
||||
"from IPython.display import display, display_html, DisplayHandle, Image"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"id": "aa49216c",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def interrupt_handler(signum, driver: webdriver.Chrome):\n",
|
||||
" print(f'Handling signal {signum} ({signal.Signals(signum).name}).')\n",
|
||||
"\n",
|
||||
" schedule.clear()\n",
|
||||
" driver.quit()\n",
|
||||
" %reset_selective -f driver\n",
|
||||
" raise SystemExit"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"id": "db04c5f7",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def setupChromeDriver():\n",
|
||||
" chrome_options = Options()\n",
|
||||
" #chrome_options.add_argument(\"--headless\")\n",
|
||||
" chrome_options.add_argument(\"--window-size=1280,720\")\n",
|
||||
" chrome_options.add_argument(\"--mute-audio\")\n",
|
||||
" driver = webdriver.Chrome(options=chrome_options)\n",
|
||||
" return driver"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"id": "9c6ed068",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def saveStats(stats):\n",
|
||||
"\n",
|
||||
" with open('stats.json', 'r+') as jsonFile:\n",
|
||||
" try:\n",
|
||||
" data = json.load(jsonFile)\n",
|
||||
" except json.JSONDecodeError:\n",
|
||||
" data = []\n",
|
||||
" data.append(stats)\n",
|
||||
" jsonFile.seek(0)\n",
|
||||
" json.dump(data, jsonFile, indent=4)\n",
|
||||
"\n",
|
||||
"def downloadStats(driver: webdriver.Chrome, display_handle: DisplayHandle):\n",
|
||||
" html = driver.find_element(By.CLASS_NAME ,'vjs-stats-list')\n",
|
||||
" htmlBS = bs(html.get_attribute('innerHTML'), 'html.parser')\n",
|
||||
"\n",
|
||||
" timestampDiv = htmlBS.new_tag('div', attrs={'style': 'display: block;'})\n",
|
||||
" timestampTitleDiv = htmlBS.new_tag('div')\n",
|
||||
" timestampTitleDiv.string = 'Timestamp'\n",
|
||||
" timestampDiv.append(timestampTitleDiv)\n",
|
||||
" timestampSpan = htmlBS.new_tag('span')\n",
|
||||
" timestampSpan.string = time.strftime('%Y-%m-%dT%H:%M:%S%z')\n",
|
||||
" timestampDiv.append(timestampSpan)\n",
|
||||
" htmlBS.div.insert_before(timestampDiv)\n",
|
||||
" \n",
|
||||
" stats = htmlBS.find_all('div', attrs={'style': 'display: block;'})\n",
|
||||
" statsList = dict(\n",
|
||||
" map(\n",
|
||||
" lambda stat: (\n",
|
||||
" stat.div.text, \n",
|
||||
" stat.span.text.replace('\\u21d3', 'down').replace('down/', 'down /').replace('\\u21d1 ', 'up').replace('\\u21d1', 'up').replace('\\u00b7', '-').strip()\n",
|
||||
" ), stats\n",
|
||||
" )\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
" display_handle.update(statsList)\n",
|
||||
"\n",
|
||||
" saveStats(statsList)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"id": "a812fea1-55f9-4c5d-87d6-d884df5ed1ba",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def setupStats(driver: webdriver.Chrome, url: str):\n",
|
||||
" actions = ActionChains(driver)\n",
|
||||
" wait = WebDriverWait(driver, 30, poll_frequency=0.2)\n",
|
||||
"\n",
|
||||
" driver.get(url)\n",
|
||||
"\n",
|
||||
" wait.until(ec.presence_of_element_located((By.CLASS_NAME, 'vjs-big-play-button')))\n",
|
||||
" actions.click(driver.find_element(By.CLASS_NAME ,'video-js')).perform()\n",
|
||||
" actions.context_click(driver.find_element(By.CLASS_NAME ,'video-js')).perform()\n",
|
||||
" statsForNerds = driver.find_elements(By.CLASS_NAME ,'vjs-menu-item')\n",
|
||||
" actions.pause(1)\n",
|
||||
" actions.click(statsForNerds[-1]).perform()\n",
|
||||
" wait.until(ec.text_to_be_present_in_element((By.CLASS_NAME, 'vjs-stats-list'), 'Player'))\n",
|
||||
"\n",
|
||||
" display(Image(driver.get_screenshot_as_png()))\n",
|
||||
"\n",
|
||||
" return driver"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"id": "221fa21b-aaf4-493f-b344-2d1a86c85c64",
|
||||
"metadata": {
|
||||
"scrolled": true
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"image/png": "iVBORw0KGgoAAAANSUhEUgAABPAAAAJGCAYAAADVgHtRAAAAAXNSR0IArs4c6QAAIABJREFUeJzsvXm8HUWZ//+uqu4+273ZE0IChCxkYUkiawKE4DKgCIgIQgD56RdFURYXFkFGZRBwHLcZFxRERpCRmbAjoCxCCDuCgQRJANmTICEhdz1Ld1f9/ug+55673+yQPO/X6ybnnK6urq2ruz711FPKOecQBEEQBAGA/h6LfR0fyCNVHruCIAibHqXUBoXp7/yBxC8IgiAIVZqbmzc4Dm+jpEQQBEEQtgLWR5xb198FQRCETU9vfXC98FYfpqsgVz3Wm1DnnBMRTxAEQdisiIAnCIIgCOsh3g30t4EcEwRBEDYNvQlzXY/1Jtj1JdSJiCcIgiBsTkTAEwRBELZ5NlS8EzFPEAThvUNvVna9Hev6m4h4giAIwnsREfAEQRAEoRf6E+o2VMjbkLCCIAjbOn2Jar2F7ckCr6uQN1BhTxAEQRA2JyLgCYIgCNs0A/VhV/99Ywh765oeQRAEoQOl1ID7y65hByrcdRXtehPxRNwTBEEQNgci4AmCIAhCFwYq3m2IqLch6REEQdiW6E00G+i5XcW73r73JNwNVMQTBEEQhE2N3tIJEARBEIQtxbr6t+vps3Ou2+ee/vo73t+5giAI2yob0ncO9DgbMEHT22+CIAiCMFBuu+22fsMoJ08bQRAEYRtkIEtnexPsBvJbT9eQR64gCMLmo6ulXP336ueefluX4/1dUxAEQRAAmpubez1WL94deeSRvYYTAU8QBEHYJlkX67uBiHebUsSTR7UgCNsy6yOKDUS8owehbqDHekuXCHiCIAhCT/Qm4PVkedebiCcCniAIgrDNsS7Wd3395nkeWos3CkEQhPc71lqiKIIBinldP9cjIp4gCPWUrv8G0RN/wJVat3RShDpUtgFv33lkj//RZrleTwJeX8tmexLxRMATBEEQtjk2xPpOxDtBEIStk75EPLHCEwRhfShd/w3CB6/c0skQ+sA/6AubRcTrawntQJGRhyAIgiB0oT/xzjkn4p0gCMJWhtZ6QP2/IAjCQIme+MOWToLQD++nOpLRRz/cPoCdQARBEIT3Dxs6+JLBmyAIwtaNPCcEQdhYyLLZ9z7vpzoSAa8fzjrzLC695NItnQxBEARhEzKQzSn62phCEARB2DqQ54EgCILwXkUEvAHwmyuv5ITj5/HKK69s6aQIgiAIW4D6QZsM1gRBELZu6vt66fMFQXgvYSbPQQ/faUsnQ9hCeFs6Ae8XHnvsMY48/AguvexSjuhlS19BEATh/c1AfR3JgE4QBGHrxDnX4yYU1d+7/i8IgrCp8WediJl8IP6sE2u/2dWv41a/RvnO7xO/sHCLpk/YfIiAtw60tbVx1plnsXjxEi741gVbOjlbBcViifMv/Da33f5HZs6YzlVXXM7QoUO3dLIEQdiGGKgYJ9Z3giAI7w0eXPgQS5e9QKlUYvvRo9lvv33YaccdN+o1qv39QEQ6EfMEQdhU5L96B2byHADCx64DQA/bCTV8HGbyHPKT51C+4zKix67Drn59C6dWGAiLFi1a53NmzpwJIuCtH7+58kqWLF7MJZddyvjx4zdavD/44Y/51RW/6fb7jjvswOEfP4zPnHg8o0eP3mjXWxfm33AT511wYb/hvnTq5zn37K9vljQJgiCsK+sjwHU9R0Q8QRCELcP8G27iZ7+4nDeXL+927BNHHs43zz2b7UaN2uDrdBXk1kegE1FPEIQNQQ/fiexnLsdMnkP8wkJK157WTaAzk+eQ/czlZD5+Pt4uB/YYRti6EB9460l1Se0jV3x7k1/rjTff5PJfX8GJJ/8/XnzxpU1+PUEQBKFvJ+XrK+K1tLSwZPFi3nj9deI43uA0DpRyqcSvL7+cJYsXb1AcN8yfz7KlS3s83tzUxH/+5Ce88fp768VxY6SraxyPPvwwd//pT5u1DutZsngxv778csql0ha5fk+8F9MkbF384Ic/5rwLLmSnnXbkV7/8Gc889TgvLV3C3Xf9kTNP/zK33vZHjj3uxA1+V+6rv5cJHEEQNhdV8a58x2W0//TjPQpz8QsLafvX3Qkfuw4zeQ5e3RLbzc855C58ksKp5/Qawj/xXgoX3kt2v+S79+nbKZz3e4KR/UR92O8pXPgkucM2borfj2xSC7xJU3fHWrtBcWiteWnpko2Wpo3FjjvuyDnnncteajHF33yOzFHfRY8Yt9Hiv/JXv2Da1Km88uqr3HHnn7j+/+bzyquvcvXvruWi71yI7/u1sNZamltayAQZcrlsn/EWiyXKlTKDGhvRun/9tq2tDa0Ns2bty7X/fRWkA9D/+NFPeeXVVxm/886c842v0tjYCMDIESM2OO/V/BTy+U757EoYhrS1t9PQ0IBnzAZfVxAEgU3k9845x4L772fBggXstNNOrFmzhnKpxLyTTtqoltybmnKxSBRFWzoZW5wojin1I1Q1NzXxh//5H+adcAKDBg/ebGkThK2R+TfcxK+u+A2nfO6zfOv8czsdmzRxAl8983Q+ePBcTjn1NL5x3vncdtP8jXLd/vzhCYIgbAr08J1qlneVOy7rN3zpmtMwu8zBn3Xiei6l/SGFn5zcybrLFV/DPnclpeuuYGCKzjj0mClo3bsmokZOQY8BVwA4En/mXPQQ8A+BynV9RD18CnrMFHht4DnaWtmkFnhfOe2LmzL6LcYpn/889/7lPg4//HAAwqdupPWivajc+/ONdo2GhgbGjNmeA/afzbnnfJ3ZsxKZeumyZbS2tgJQqVS44aabmfPBj7DnPrPZbcaenHjy53qceXz9jTf48hlfZcZe+7LnPrPZa9/9+e3Vv6NSqdTC/OCHP2bC5F254MLvsHLlW5x+1tfY4wP78NVvnM2woUM5YP/ZHLD/bPafPZuxY8cAMHjwIPbbd5/ascmTd2H+DTcxYfKuTJi8K/NvuKkWf/3vjz/xZLc0RnHMzbfeXsvP9D335cc//a9ug6R33lnNxZdcxvQ9k7zsMXNvLrnsB7VyEQRBWB8GItCtr4i3Zs0ann7qKU46+WQ+d8opfOOcc/jsKaew/RZyi7A+ZLJZTjz5ZHbbffctnZQtzpyDDuLIo47CyOSRIGwWfvaLy9l/9qxu4l09M6bvwaXfu4glS57jmt/3NRIcGJvymSAIgtAXVUu68LH/GfA54WPXoYfvROHiJRQuXtLJd17/ZCGTBb+MXf0advVrkJuCOeCH5M84Yz1z0R+3Uf7vbxE+cDbFDe+ytxk2qQXe1846g6+dtakqfPOz9z57c+6557L3Pvt0PxhVKN14AeEzt5P9xHcxk2ZvtOsGQcDwYcM6Xy6O+eWvruC/fv7LTr8/+tjjfOkrZ3LFr37OxAkTAHjxxZf40lfO5JVXX62Fa2pu5nuX/TutbW18+bQvdrJgW75iBd++6GLu+8v9AEyZPJlCoVA77vs+w7qkZ2OwZMlzLFnyXO17uVzm57/8FZ7n1dL49qpVnPW1szsJgOVymauu/m+ampq46Dv/2q8VoiAIQpX+Bl89HV+fAVsYhgBkM5nab2PGjKl9bm5u5rZbbuGFZcvI5/Mc+clPsuuuuxKGIY89+iiPPvIIzU1NjBo1ik/Pm8fo0aOpVCrcevPNTNt1V+6/7z5y+Twnf/aztLa0cOstt/CPl14in8/z8SOOYOrUqQCsXr2aKy6/nDfeeIOdx4/nuHnzaGhoqKVj+Ztvcs/dd/OpY4+tWVY/+8wzLH3+eQ4/8khuvuEG9tlvPyZPmYJzjkV/+xt33XEHpVKJqdOmdbLOi+OYhQsW8NDChYRhyH6zZnHoxz6GMabTsUqlwvQZMzjs8MPJ5/PEccyf7rqLxx99FON57LPPPvzLoYf2apHd0tLCLTfdxG677cYD99/P2rVrmbbrrnzy6KPJ5nLdwr+1ciV33Xknr77yCgBz5s7lgx/6EEuff57Fzz7Lp449tnathQ8+SLFYZNasWZ3ieOShh3jnnXc48qijekzv7tOnM//661m7di2//PnP2XHHHTnmuOP465NPcu899xBHEXtMn87HPv7xTuXfFWstjz/2GPffdx/t7e1MnTaNo44+unZs4cKFPPbII8TWcvgRR7DX3nv3mUdjDI889BCVMKS1tZUnHnuMfD7Psccfz8SJE2lpaeG2m29m5p578ue77mLNmjXMmDmTo44+Gt/3a3X+57vuor29vddyds7xyMMPr1NeBaE3Hlz4EG8uX86F3/pmv2EP+ciHmTljOnfc+SdOPmn9l5L1ZGHXn9WdWOUJgrCx8GediF39em3TioFQueMy9PCdetzgYiBWfACUFxF+7wgqACMvoXDBGegJnyDDz7CfuAoz5F3sE2dTeR6YdgbZfWfC2gWUbr2mUzT64B+S2WsuqrSA8I9nE/ZiOafGjYMceNNI4mQG/ifOxJ86HVofJ376SsqPPlN3xjj8wy/BnzkOXrl2HawDtx5kE4sB4Ps+5553Lqd8/vP9ho1fepS2Hx1K8OHTyR71XfCCDb7+okXPsPChhwHYbrvtCDIZHn74UX75qysA+MIpn+OLXziF1avXcN4FF7LomWf589338uUvnUpbezs//s+f1Za7fv/Si5m8yy7cePMtfO/S7/PHO+7kk0cdyY477FC73sKHHsbzPE6Ydxwf/uDBm3XjjOM/fSxfOOVzLF22jAsu/A5Nzc3cetsf+cSRRzB27Biu/M3VPP7EkwweNIhLv3cRB805kPsXPMj53/o2d/35bk6YdxwzZ0zfbOkVBGHbZF1FvJEjRzJ+wgSuvuoq9j/wQPY/4ACy2WSyoVwq8X/XX8/48eM54aSTWP3OO9x4ww0MHz6cIYMHEwQBXznjDHK5HHfdeSf33XMPx59wAs5amtau5YG//IVPHXss240eTUtLC7+7+mr2mD6dkz/7WVqam4nq/LQtfuYZjps3j0JDA7+7+mqefeYZ9j/ggNrx4cOLine truncated
|
||||
"text/plain": [
|
||||
"<IPython.core.display.Image object>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"{'Timestamp': '2024-03-07T03:08:51+0100',\n",
|
||||
" 'Player mode': 'p2p-media-loader',\n",
|
||||
" 'P2P': 'enabled',\n",
|
||||
" 'Video UUID': '7f063c76-14a5-400a-9dad-0f450bb7467e',\n",
|
||||
" 'Viewport / Frames': '1264x582*1.00 / 3 dropped of 5465',\n",
|
||||
" 'Resolution': '720p',\n",
|
||||
" 'Volume': '100',\n",
|
||||
" 'Codecs': 'avc1.640020 / mp4a.40.2',\n",
|
||||
" 'Connection Speed': '6 MB/s',\n",
|
||||
" 'Network Activity': '2 MB down / 0 B up',\n",
|
||||
" 'Total Transfered': '49 MB down / 0 B up',\n",
|
||||
" 'Download Breakdown': '49 MB from servers - 0 B from peers',\n",
|
||||
" 'Buffer State': '[40s, 2m23s]',\n",
|
||||
" 'Live Latency': '20s (from edge: 0s)'}"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Handling signal 2 (SIGINT).\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"ename": "SystemExit",
|
||||
"evalue": "",
|
||||
"output_type": "error",
|
||||
"traceback": [
|
||||
"An exception has occurred, use %tb to see the full traceback.\n",
|
||||
"\u001b[1;31mSystemExit\u001b[0m\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"c:\\Users\\mirko\\statnerd\\.venv\\Lib\\site-packages\\IPython\\core\\interactiveshell.py:3585: UserWarning: To exit: use 'exit', 'quit', or Ctrl-D.\n",
|
||||
" warn(\"To exit: use 'exit', 'quit', or Ctrl-D.\", stacklevel=1)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"if __name__ == '__main__':\n",
|
||||
" driver = setupChromeDriver()\n",
|
||||
"\n",
|
||||
" signal.signal(signal.SIGINT, lambda signum, frame: interrupt_handler(signum, driver))\n",
|
||||
" \n",
|
||||
" setupStats(driver, \"https://tube.kobim.cloud/w/gFL48Fz3doCEnYwK46BwYN\")\n",
|
||||
"\n",
|
||||
" display_handle = display(\"Loading...\", display_id=True)\n",
|
||||
" \n",
|
||||
" schedule.every(0.3).seconds.do(downloadStats, driver, display_handle)\n",
|
||||
" while True:\n",
|
||||
" schedule.run_pending()"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"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.11.3"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
Reference in new issue
Block a user