abx-plugins 0.9.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- abx_plugins-0.9.0/.gitignore +6 -0
- abx_plugins-0.9.0/LICENSE +21 -0
- abx_plugins-0.9.0/PKG-INFO +118 -0
- abx_plugins-0.9.0/README.md +86 -0
- abx_plugins-0.9.0/abx_plugins/__init__.py +14 -0
- abx_plugins-0.9.0/abx_plugins/plugins/.coverage +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/__init__.py +1 -0
- abx_plugins-0.9.0/abx_plugins/plugins/accessibility/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/accessibility/config.json +21 -0
- abx_plugins-0.9.0/abx_plugins/plugins/accessibility/on_Snapshot__39_accessibility.js +294 -0
- abx_plugins-0.9.0/abx_plugins/plugins/accessibility/templates/icon.html +1 -0
- abx_plugins-0.9.0/abx_plugins/plugins/accessibility/tests/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/accessibility/tests/test_accessibility.py +195 -0
- abx_plugins-0.9.0/abx_plugins/plugins/apt/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/apt/on_Binary__13_apt_install.py +89 -0
- abx_plugins-0.9.0/abx_plugins/plugins/apt/templates/icon.html +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/apt/tests/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/apt/tests/test_apt_provider.py +153 -0
- abx_plugins-0.9.0/abx_plugins/plugins/archivedotorg/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/archivedotorg/config.json +26 -0
- abx_plugins-0.9.0/abx_plugins/plugins/archivedotorg/on_Snapshot__08_archivedotorg.bg.py +154 -0
- abx_plugins-0.9.0/abx_plugins/plugins/archivedotorg/templates/card.html +12 -0
- abx_plugins-0.9.0/abx_plugins/plugins/archivedotorg/templates/icon.html +1 -0
- abx_plugins-0.9.0/abx_plugins/plugins/archivedotorg/tests/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/archivedotorg/tests/test_archivedotorg.py +93 -0
- abx_plugins-0.9.0/abx_plugins/plugins/brew/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/brew/on_Binary__12_brew_install.py +91 -0
- abx_plugins-0.9.0/abx_plugins/plugins/brew/templates/icon.html +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/chrome/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/chrome/chrome_utils.js +2038 -0
- abx_plugins-0.9.0/abx_plugins/plugins/chrome/config.json +157 -0
- abx_plugins-0.9.0/abx_plugins/plugins/chrome/extract_cookies.js +254 -0
- abx_plugins-0.9.0/abx_plugins/plugins/chrome/on_Crawl__70_chrome_install.py +46 -0
- abx_plugins-0.9.0/abx_plugins/plugins/chrome/on_Crawl__90_chrome_launch.bg.js +433 -0
- abx_plugins-0.9.0/abx_plugins/plugins/chrome/on_Snapshot__10_chrome_tab.bg.js +265 -0
- abx_plugins-0.9.0/abx_plugins/plugins/chrome/on_Snapshot__11_chrome_wait.js +85 -0
- abx_plugins-0.9.0/abx_plugins/plugins/chrome/on_Snapshot__30_chrome_navigate.js +231 -0
- abx_plugins-0.9.0/abx_plugins/plugins/chrome/templates/icon.html +1 -0
- abx_plugins-0.9.0/abx_plugins/plugins/chrome/tests/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/chrome/tests/chrome_test_helpers.py +997 -0
- abx_plugins-0.9.0/abx_plugins/plugins/chrome/tests/test_chrome.py +725 -0
- abx_plugins-0.9.0/abx_plugins/plugins/chrome/tests/test_chrome_test_helpers.py +257 -0
- abx_plugins-0.9.0/abx_plugins/plugins/consolelog/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/consolelog/config.json +21 -0
- abx_plugins-0.9.0/abx_plugins/plugins/consolelog/on_Snapshot__21_consolelog.bg.js +207 -0
- abx_plugins-0.9.0/abx_plugins/plugins/consolelog/templates/icon.html +1 -0
- abx_plugins-0.9.0/abx_plugins/plugins/consolelog/tests/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/consolelog/tests/test_consolelog.py +126 -0
- abx_plugins-0.9.0/abx_plugins/plugins/custom/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/custom/on_Binary__14_custom_install.py +99 -0
- abx_plugins-0.9.0/abx_plugins/plugins/custom/templates/icon.html +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/custom/tests/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/custom/tests/test_custom_provider.py +148 -0
- abx_plugins-0.9.0/abx_plugins/plugins/dns/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/dns/config.json +21 -0
- abx_plugins-0.9.0/abx_plugins/plugins/dns/on_Snapshot__22_dns.bg.js +271 -0
- abx_plugins-0.9.0/abx_plugins/plugins/dns/templates/icon.html +1 -0
- abx_plugins-0.9.0/abx_plugins/plugins/dns/tests/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/dns/tests/test_dns.py +125 -0
- abx_plugins-0.9.0/abx_plugins/plugins/dom/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/dom/config.json +21 -0
- abx_plugins-0.9.0/abx_plugins/plugins/dom/on_Snapshot__53_dom.js +190 -0
- abx_plugins-0.9.0/abx_plugins/plugins/dom/templates/card.html +8 -0
- abx_plugins-0.9.0/abx_plugins/plugins/dom/templates/icon.html +1 -0
- abx_plugins-0.9.0/abx_plugins/plugins/dom/tests/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/dom/tests/test_dom.py +187 -0
- abx_plugins-0.9.0/abx_plugins/plugins/env/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/env/on_Binary__15_env_install.py +73 -0
- abx_plugins-0.9.0/abx_plugins/plugins/env/templates/icon.html +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/env/tests/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/env/tests/test_env_provider.py +158 -0
- abx_plugins-0.9.0/abx_plugins/plugins/favicon/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/favicon/config.json +26 -0
- abx_plugins-0.9.0/abx_plugins/plugins/favicon/on_Snapshot__11_favicon.bg.py +154 -0
- abx_plugins-0.9.0/abx_plugins/plugins/favicon/templates/card.html +9 -0
- abx_plugins-0.9.0/abx_plugins/plugins/favicon/templates/icon.html +1 -0
- abx_plugins-0.9.0/abx_plugins/plugins/favicon/tests/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/favicon/tests/test_favicon.py +308 -0
- abx_plugins-0.9.0/abx_plugins/plugins/forumdl/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/forumdl/config.json +51 -0
- abx_plugins-0.9.0/abx_plugins/plugins/forumdl/forum-dl-wrapper.py +38 -0
- abx_plugins-0.9.0/abx_plugins/plugins/forumdl/on_Crawl__25_forumdl_install.py +94 -0
- abx_plugins-0.9.0/abx_plugins/plugins/forumdl/on_Snapshot__04_forumdl.bg.py +267 -0
- abx_plugins-0.9.0/abx_plugins/plugins/forumdl/templates/card.html +7 -0
- abx_plugins-0.9.0/abx_plugins/plugins/forumdl/templates/full.html +147 -0
- abx_plugins-0.9.0/abx_plugins/plugins/forumdl/templates/icon.html +1 -0
- abx_plugins-0.9.0/abx_plugins/plugins/forumdl/tests/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/forumdl/tests/test_forumdl.py +316 -0
- abx_plugins-0.9.0/abx_plugins/plugins/gallerydl/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/gallerydl/config.json +54 -0
- abx_plugins-0.9.0/abx_plugins/plugins/gallerydl/on_Crawl__20_gallerydl_install.py +61 -0
- abx_plugins-0.9.0/abx_plugins/plugins/gallerydl/on_Snapshot__03_gallerydl.bg.py +260 -0
- abx_plugins-0.9.0/abx_plugins/plugins/gallerydl/templates/card.html +11 -0
- abx_plugins-0.9.0/abx_plugins/plugins/gallerydl/templates/full.html +28 -0
- abx_plugins-0.9.0/abx_plugins/plugins/gallerydl/templates/icon.html +1 -0
- abx_plugins-0.9.0/abx_plugins/plugins/gallerydl/tests/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/gallerydl/tests/test_gallerydl.py +190 -0
- abx_plugins-0.9.0/abx_plugins/plugins/git/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/git/config.json +44 -0
- abx_plugins-0.9.0/abx_plugins/plugins/git/on_Crawl__05_git_install.py +61 -0
- abx_plugins-0.9.0/abx_plugins/plugins/git/on_Snapshot__05_git.bg.py +144 -0
- abx_plugins-0.9.0/abx_plugins/plugins/git/templates/card.html +5 -0
- abx_plugins-0.9.0/abx_plugins/plugins/git/templates/icon.html +1 -0
- abx_plugins-0.9.0/abx_plugins/plugins/git/tests/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/git/tests/test_git.py +130 -0
- abx_plugins-0.9.0/abx_plugins/plugins/hashes/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/hashes/config.json +20 -0
- abx_plugins-0.9.0/abx_plugins/plugins/hashes/on_Snapshot__93_hashes.py +188 -0
- abx_plugins-0.9.0/abx_plugins/plugins/hashes/templates/icon.html +1 -0
- abx_plugins-0.9.0/abx_plugins/plugins/hashes/tests/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/hashes/tests/test_hashes.py +159 -0
- abx_plugins-0.9.0/abx_plugins/plugins/headers/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/headers/config.json +21 -0
- abx_plugins-0.9.0/abx_plugins/plugins/headers/on_Snapshot__27_headers.bg.js +253 -0
- abx_plugins-0.9.0/abx_plugins/plugins/headers/templates/icon.html +1 -0
- abx_plugins-0.9.0/abx_plugins/plugins/headers/tests/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/headers/tests/test_headers.py +409 -0
- abx_plugins-0.9.0/abx_plugins/plugins/htmltotext/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/htmltotext/config.json +20 -0
- abx_plugins-0.9.0/abx_plugins/plugins/htmltotext/on_Snapshot__58_htmltotext.py +162 -0
- abx_plugins-0.9.0/abx_plugins/plugins/htmltotext/templates/icon.html +1 -0
- abx_plugins-0.9.0/abx_plugins/plugins/htmltotext/tests/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/htmltotext/tests/test_htmltotext.py +93 -0
- abx_plugins-0.9.0/abx_plugins/plugins/infiniscroll/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/infiniscroll/config.json +51 -0
- abx_plugins-0.9.0/abx_plugins/plugins/infiniscroll/on_Snapshot__45_infiniscroll.js +435 -0
- abx_plugins-0.9.0/abx_plugins/plugins/infiniscroll/templates/icon.html +1 -0
- abx_plugins-0.9.0/abx_plugins/plugins/infiniscroll/tests/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/infiniscroll/tests/test_infiniscroll.py +248 -0
- abx_plugins-0.9.0/abx_plugins/plugins/istilldontcareaboutcookies/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/istilldontcareaboutcookies/config.json +14 -0
- abx_plugins-0.9.0/abx_plugins/plugins/istilldontcareaboutcookies/on_Crawl__81_install_istilldontcareaboutcookies_extension.js +126 -0
- abx_plugins-0.9.0/abx_plugins/plugins/istilldontcareaboutcookies/templates/icon.html +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/istilldontcareaboutcookies/tests/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/istilldontcareaboutcookies/tests/test_istilldontcareaboutcookies.py +641 -0
- abx_plugins-0.9.0/abx_plugins/plugins/media/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/media/tests/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/mercury/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/mercury/config.json +40 -0
- abx_plugins-0.9.0/abx_plugins/plugins/mercury/on_Crawl__40_mercury_install.py +67 -0
- abx_plugins-0.9.0/abx_plugins/plugins/mercury/on_Snapshot__57_mercury.py +199 -0
- abx_plugins-0.9.0/abx_plugins/plugins/mercury/templates/card.html +8 -0
- abx_plugins-0.9.0/abx_plugins/plugins/mercury/templates/icon.html +1 -0
- abx_plugins-0.9.0/abx_plugins/plugins/mercury/tests/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/mercury/tests/test_mercury.py +169 -0
- abx_plugins-0.9.0/abx_plugins/plugins/modalcloser/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/modalcloser/config.json +26 -0
- abx_plugins-0.9.0/abx_plugins/plugins/modalcloser/on_Snapshot__15_modalcloser.bg.js +341 -0
- abx_plugins-0.9.0/abx_plugins/plugins/modalcloser/templates/icon.html +1 -0
- abx_plugins-0.9.0/abx_plugins/plugins/modalcloser/tests/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/modalcloser/tests/test_modalcloser.py +459 -0
- abx_plugins-0.9.0/abx_plugins/plugins/npm/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/npm/on_Binary__10_npm_install.py +130 -0
- abx_plugins-0.9.0/abx_plugins/plugins/npm/on_Crawl__00_npm_install.py +62 -0
- abx_plugins-0.9.0/abx_plugins/plugins/npm/templates/icon.html +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/npm/tests/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/npm/tests/test_npm_provider.py +145 -0
- abx_plugins-0.9.0/abx_plugins/plugins/papersdl/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/papersdl/config.json +39 -0
- abx_plugins-0.9.0/abx_plugins/plugins/papersdl/on_Crawl__30_papersdl_install.py +61 -0
- abx_plugins-0.9.0/abx_plugins/plugins/papersdl/on_Snapshot__66_papersdl.bg.py +228 -0
- abx_plugins-0.9.0/abx_plugins/plugins/papersdl/templates/card.html +7 -0
- abx_plugins-0.9.0/abx_plugins/plugins/papersdl/templates/full.html +71 -0
- abx_plugins-0.9.0/abx_plugins/plugins/papersdl/templates/icon.html +1 -0
- abx_plugins-0.9.0/abx_plugins/plugins/papersdl/tests/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/papersdl/tests/test_papersdl.py +190 -0
- abx_plugins-0.9.0/abx_plugins/plugins/parse_dom_outlinks/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/parse_dom_outlinks/config.json +21 -0
- abx_plugins-0.9.0/abx_plugins/plugins/parse_dom_outlinks/on_Snapshot__75_parse_dom_outlinks.js +298 -0
- abx_plugins-0.9.0/abx_plugins/plugins/parse_dom_outlinks/templates/icon.html +1 -0
- abx_plugins-0.9.0/abx_plugins/plugins/parse_dom_outlinks/tests/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/parse_dom_outlinks/tests/test_parse_dom_outlinks.py +121 -0
- abx_plugins-0.9.0/abx_plugins/plugins/parse_html_urls/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/parse_html_urls/config.json +13 -0
- abx_plugins-0.9.0/abx_plugins/plugins/parse_html_urls/on_Snapshot__70_parse_html_urls.py +301 -0
- abx_plugins-0.9.0/abx_plugins/plugins/parse_html_urls/templates/icon.html +1 -0
- abx_plugins-0.9.0/abx_plugins/plugins/parse_html_urls/tests/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/parse_html_urls/tests/test_parse_html_urls.py +267 -0
- abx_plugins-0.9.0/abx_plugins/plugins/parse_jsonl_urls/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/parse_jsonl_urls/config.json +13 -0
- abx_plugins-0.9.0/abx_plugins/plugins/parse_jsonl_urls/on_Snapshot__74_parse_jsonl_urls.py +222 -0
- abx_plugins-0.9.0/abx_plugins/plugins/parse_jsonl_urls/templates/icon.html +1 -0
- abx_plugins-0.9.0/abx_plugins/plugins/parse_jsonl_urls/tests/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/parse_jsonl_urls/tests/test_parse_jsonl_urls.py +276 -0
- abx_plugins-0.9.0/abx_plugins/plugins/parse_netscape_urls/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/parse_netscape_urls/config.json +13 -0
- abx_plugins-0.9.0/abx_plugins/plugins/parse_netscape_urls/on_Snapshot__73_parse_netscape_urls.py +266 -0
- abx_plugins-0.9.0/abx_plugins/plugins/parse_netscape_urls/templates/icon.html +1 -0
- abx_plugins-0.9.0/abx_plugins/plugins/parse_netscape_urls/tests/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/parse_netscape_urls/tests/test_parse_netscape_urls.py +208 -0
- abx_plugins-0.9.0/abx_plugins/plugins/parse_netscape_urls/tests/test_parse_netscape_urls_comprehensive.py +953 -0
- abx_plugins-0.9.0/abx_plugins/plugins/parse_rss_urls/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/parse_rss_urls/config.json +13 -0
- abx_plugins-0.9.0/abx_plugins/plugins/parse_rss_urls/on_Snapshot__72_parse_rss_urls.py +175 -0
- abx_plugins-0.9.0/abx_plugins/plugins/parse_rss_urls/templates/icon.html +1 -0
- abx_plugins-0.9.0/abx_plugins/plugins/parse_rss_urls/tests/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/parse_rss_urls/tests/test_parse_rss_urls.py +212 -0
- abx_plugins-0.9.0/abx_plugins/plugins/parse_rss_urls/tests/test_parse_rss_urls_comprehensive.py +1002 -0
- abx_plugins-0.9.0/abx_plugins/plugins/parse_txt_urls/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/parse_txt_urls/config.json +13 -0
- abx_plugins-0.9.0/abx_plugins/plugins/parse_txt_urls/on_Snapshot__71_parse_txt_urls.py +173 -0
- abx_plugins-0.9.0/abx_plugins/plugins/parse_txt_urls/templates/icon.html +1 -0
- abx_plugins-0.9.0/abx_plugins/plugins/parse_txt_urls/tests/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/parse_txt_urls/tests/test_parse_txt_urls.py +193 -0
- abx_plugins-0.9.0/abx_plugins/plugins/path_utils.py +30 -0
- abx_plugins-0.9.0/abx_plugins/plugins/pdf/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/pdf/config.json +28 -0
- abx_plugins-0.9.0/abx_plugins/plugins/pdf/on_Snapshot__52_pdf.js +199 -0
- abx_plugins-0.9.0/abx_plugins/plugins/pdf/templates/card.html +6 -0
- abx_plugins-0.9.0/abx_plugins/plugins/pdf/templates/full.html +5 -0
- abx_plugins-0.9.0/abx_plugins/plugins/pdf/templates/icon.html +1 -0
- abx_plugins-0.9.0/abx_plugins/plugins/pdf/tests/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/pdf/tests/test_pdf.py +197 -0
- abx_plugins-0.9.0/abx_plugins/plugins/pip/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/pip/on_Binary__11_pip_install.py +138 -0
- abx_plugins-0.9.0/abx_plugins/plugins/pip/templates/icon.html +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/pip/tests/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/pip/tests/test_pip_provider.py +190 -0
- abx_plugins-0.9.0/abx_plugins/plugins/puppeteer/__init__.py +1 -0
- abx_plugins-0.9.0/abx_plugins/plugins/puppeteer/on_Binary__12_puppeteer_install.py +176 -0
- abx_plugins-0.9.0/abx_plugins/plugins/puppeteer/on_Crawl__60_puppeteer_install.py +43 -0
- abx_plugins-0.9.0/abx_plugins/plugins/puppeteer/tests/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/puppeteer/tests/test_puppeteer.py +123 -0
- abx_plugins-0.9.0/abx_plugins/plugins/readability/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/readability/config.json +39 -0
- abx_plugins-0.9.0/abx_plugins/plugins/readability/on_Crawl__35_readability_install.py +63 -0
- abx_plugins-0.9.0/abx_plugins/plugins/readability/on_Snapshot__56_readability.py +209 -0
- abx_plugins-0.9.0/abx_plugins/plugins/readability/templates/card.html +8 -0
- abx_plugins-0.9.0/abx_plugins/plugins/readability/templates/full.html +6 -0
- abx_plugins-0.9.0/abx_plugins/plugins/readability/templates/icon.html +1 -0
- abx_plugins-0.9.0/abx_plugins/plugins/readability/tests/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/readability/tests/test_readability.py +235 -0
- abx_plugins-0.9.0/abx_plugins/plugins/redirects/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/redirects/config.json +21 -0
- abx_plugins-0.9.0/abx_plugins/plugins/redirects/on_Snapshot__25_redirects.bg.js +244 -0
- abx_plugins-0.9.0/abx_plugins/plugins/redirects/templates/icon.html +1 -0
- abx_plugins-0.9.0/abx_plugins/plugins/redirects/tests/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/redirects/tests/test_redirects.py +149 -0
- abx_plugins-0.9.0/abx_plugins/plugins/responses/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/responses/config.json +21 -0
- abx_plugins-0.9.0/abx_plugins/plugins/responses/on_Snapshot__24_responses.bg.js +308 -0
- abx_plugins-0.9.0/abx_plugins/plugins/responses/templates/icon.html +1 -0
- abx_plugins-0.9.0/abx_plugins/plugins/responses/tests/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/responses/tests/test_responses.py +127 -0
- abx_plugins-0.9.0/abx_plugins/plugins/screenshot/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/screenshot/config.json +28 -0
- abx_plugins-0.9.0/abx_plugins/plugins/screenshot/on_Snapshot__51_screenshot.js +185 -0
- abx_plugins-0.9.0/abx_plugins/plugins/screenshot/templates/card.html +8 -0
- abx_plugins-0.9.0/abx_plugins/plugins/screenshot/templates/full.html +7 -0
- abx_plugins-0.9.0/abx_plugins/plugins/screenshot/templates/icon.html +1 -0
- abx_plugins-0.9.0/abx_plugins/plugins/screenshot/tests/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/screenshot/tests/test_screenshot.py +477 -0
- abx_plugins-0.9.0/abx_plugins/plugins/search_backend_ripgrep/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/search_backend_ripgrep/config.json +34 -0
- abx_plugins-0.9.0/abx_plugins/plugins/search_backend_ripgrep/on_Crawl__50_ripgrep_install.py +43 -0
- abx_plugins-0.9.0/abx_plugins/plugins/search_backend_ripgrep/search.py +109 -0
- abx_plugins-0.9.0/abx_plugins/plugins/search_backend_ripgrep/templates/icon.html +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/search_backend_ripgrep/tests/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/search_backend_ripgrep/tests/test_ripgrep_detection.py +144 -0
- abx_plugins-0.9.0/abx_plugins/plugins/search_backend_ripgrep/tests/test_ripgrep_search.py +295 -0
- abx_plugins-0.9.0/abx_plugins/plugins/search_backend_sonic/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/search_backend_sonic/config.json +39 -0
- abx_plugins-0.9.0/abx_plugins/plugins/search_backend_sonic/on_Snapshot__91_index_sonic.py +201 -0
- abx_plugins-0.9.0/abx_plugins/plugins/search_backend_sonic/search.py +56 -0
- abx_plugins-0.9.0/abx_plugins/plugins/search_backend_sonic/templates/icon.html +1 -0
- abx_plugins-0.9.0/abx_plugins/plugins/search_backend_sqlite/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/search_backend_sqlite/config.json +25 -0
- abx_plugins-0.9.0/abx_plugins/plugins/search_backend_sqlite/on_Snapshot__90_index_sqlite.py +192 -0
- abx_plugins-0.9.0/abx_plugins/plugins/search_backend_sqlite/search.py +75 -0
- abx_plugins-0.9.0/abx_plugins/plugins/search_backend_sqlite/templates/icon.html +1 -0
- abx_plugins-0.9.0/abx_plugins/plugins/search_backend_sqlite/tests/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/search_backend_sqlite/tests/test_sqlite_search.py +348 -0
- abx_plugins-0.9.0/abx_plugins/plugins/seo/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/seo/config.json +21 -0
- abx_plugins-0.9.0/abx_plugins/plugins/seo/on_Snapshot__38_seo.js +175 -0
- abx_plugins-0.9.0/abx_plugins/plugins/seo/templates/icon.html +1 -0
- abx_plugins-0.9.0/abx_plugins/plugins/seo/tests/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/seo/tests/test_seo.py +129 -0
- abx_plugins-0.9.0/abx_plugins/plugins/singlefile/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/singlefile/config.json +77 -0
- abx_plugins-0.9.0/abx_plugins/plugins/singlefile/on_Crawl__45_singlefile_install.py +66 -0
- abx_plugins-0.9.0/abx_plugins/plugins/singlefile/on_Crawl__82_singlefile_install.js +352 -0
- abx_plugins-0.9.0/abx_plugins/plugins/singlefile/on_Snapshot__50_singlefile.py +407 -0
- abx_plugins-0.9.0/abx_plugins/plugins/singlefile/singlefile_extension_save.js +210 -0
- abx_plugins-0.9.0/abx_plugins/plugins/singlefile/templates/card.html +8 -0
- abx_plugins-0.9.0/abx_plugins/plugins/singlefile/templates/icon.html +1 -0
- abx_plugins-0.9.0/abx_plugins/plugins/singlefile/tests/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/singlefile/tests/test_singlefile.py +304 -0
- abx_plugins-0.9.0/abx_plugins/plugins/ssl/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/ssl/config.json +21 -0
- abx_plugins-0.9.0/abx_plugins/plugins/ssl/on_Snapshot__23_ssl.bg.js +203 -0
- abx_plugins-0.9.0/abx_plugins/plugins/ssl/templates/icon.html +1 -0
- abx_plugins-0.9.0/abx_plugins/plugins/ssl/tests/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/ssl/tests/test_ssl.py +147 -0
- abx_plugins-0.9.0/abx_plugins/plugins/staticfile/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/staticfile/config.json +21 -0
- abx_plugins-0.9.0/abx_plugins/plugins/staticfile/on_Snapshot__26_staticfile.bg.js +372 -0
- abx_plugins-0.9.0/abx_plugins/plugins/staticfile/templates/card.html +24 -0
- abx_plugins-0.9.0/abx_plugins/plugins/staticfile/templates/icon.html +1 -0
- abx_plugins-0.9.0/abx_plugins/plugins/staticfile/tests/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/staticfile/tests/test_staticfile.py +122 -0
- abx_plugins-0.9.0/abx_plugins/plugins/title/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/title/config.json +21 -0
- abx_plugins-0.9.0/abx_plugins/plugins/title/on_Snapshot__54_title.js +145 -0
- abx_plugins-0.9.0/abx_plugins/plugins/title/templates/icon.html +1 -0
- abx_plugins-0.9.0/abx_plugins/plugins/title/tests/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/title/tests/test_title.py +279 -0
- abx_plugins-0.9.0/abx_plugins/plugins/twocaptcha/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/twocaptcha/config.json +50 -0
- abx_plugins-0.9.0/abx_plugins/plugins/twocaptcha/on_Crawl__83_twocaptcha_install.js +77 -0
- abx_plugins-0.9.0/abx_plugins/plugins/twocaptcha/on_Crawl__95_twocaptcha_config.js +393 -0
- abx_plugins-0.9.0/abx_plugins/plugins/twocaptcha/templates/icon.html +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/twocaptcha/tests/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/twocaptcha/tests/test_twocaptcha.py +338 -0
- abx_plugins-0.9.0/abx_plugins/plugins/ublock/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/ublock/config.json +14 -0
- abx_plugins-0.9.0/abx_plugins/plugins/ublock/on_Crawl__80_install_ublock_extension.js +71 -0
- abx_plugins-0.9.0/abx_plugins/plugins/ublock/templates/icon.html +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/ublock/tests/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/ublock/tests/test_ublock.py +725 -0
- abx_plugins-0.9.0/abx_plugins/plugins/wget/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/wget/config.json +75 -0
- abx_plugins-0.9.0/abx_plugins/plugins/wget/on_Crawl__10_wget_install.py +108 -0
- abx_plugins-0.9.0/abx_plugins/plugins/wget/on_Snapshot__06_wget.bg.py +241 -0
- abx_plugins-0.9.0/abx_plugins/plugins/wget/templates/card.html +8 -0
- abx_plugins-0.9.0/abx_plugins/plugins/wget/templates/icon.html +1 -0
- abx_plugins-0.9.0/abx_plugins/plugins/wget/tests/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/wget/tests/test_wget.py +437 -0
- abx_plugins-0.9.0/abx_plugins/plugins/ytdlp/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/ytdlp/config.json +92 -0
- abx_plugins-0.9.0/abx_plugins/plugins/ytdlp/on_Crawl__15_ytdlp_install.py +77 -0
- abx_plugins-0.9.0/abx_plugins/plugins/ytdlp/on_Snapshot__02_ytdlp.bg.py +269 -0
- abx_plugins-0.9.0/abx_plugins/plugins/ytdlp/templates/card.html +17 -0
- abx_plugins-0.9.0/abx_plugins/plugins/ytdlp/templates/full.html +10 -0
- abx_plugins-0.9.0/abx_plugins/plugins/ytdlp/templates/icon.html +1 -0
- abx_plugins-0.9.0/abx_plugins/plugins/ytdlp/tests/__init__.py +0 -0
- abx_plugins-0.9.0/abx_plugins/plugins/ytdlp/tests/test_ytdlp.py +202 -0
- abx_plugins-0.9.0/conftest.py +22 -0
- abx_plugins-0.9.0/pyproject.toml +52 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Nick Sweeting
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: abx-plugins
|
|
3
|
+
Version: 0.9.0
|
|
4
|
+
Summary: ArchiveBox-compatible plugin suite (hooks, configs, binaries manifests)
|
|
5
|
+
Project-URL: Homepage, https://github.com/ArchiveBox/abx-plugins
|
|
6
|
+
Project-URL: Source, https://github.com/ArchiveBox/abx-plugins
|
|
7
|
+
Project-URL: Documentation, https://github.com/ArchiveBox/ArchiveBox
|
|
8
|
+
Project-URL: Bug Tracker, https://github.com/ArchiveBox/abx-plugins/issues
|
|
9
|
+
Author-email: Nick Sweeting <pyproject.toml+abx-plugins@archivebox.io>
|
|
10
|
+
License: MIT
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: archivebox,hooks,plugins,scraping,web-archiving
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Programming Language :: Python
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Requires-Python: >=3.10
|
|
23
|
+
Requires-Dist: abx-pkg>=0.6.0
|
|
24
|
+
Requires-Dist: rich-click>=1.9.7
|
|
25
|
+
Provides-Extra: dev
|
|
26
|
+
Requires-Dist: abx-pkg>=0.6.0; extra == 'dev'
|
|
27
|
+
Requires-Dist: feedparser>=6.0.0; extra == 'dev'
|
|
28
|
+
Requires-Dist: pytest>=8.0.0; extra == 'dev'
|
|
29
|
+
Requires-Dist: requests>=2.28.0; extra == 'dev'
|
|
30
|
+
Requires-Dist: rich-click>=1.8.0; extra == 'dev'
|
|
31
|
+
Description-Content-Type: text/markdown
|
|
32
|
+
|
|
33
|
+
# abx-plugins
|
|
34
|
+
|
|
35
|
+
ArchiveBox-compatible plugin suite (hooks, config schemas, binaries manifests).
|
|
36
|
+
|
|
37
|
+
This package contains only plugin assets and a tiny helper to locate them.
|
|
38
|
+
It does **not** depend on Django or ArchiveBox.
|
|
39
|
+
|
|
40
|
+
## Usage
|
|
41
|
+
|
|
42
|
+
```python
|
|
43
|
+
from abx_plugins import get_plugins_dir
|
|
44
|
+
|
|
45
|
+
plugins_dir = get_plugins_dir()
|
|
46
|
+
# scan plugins_dir for plugins/*/config.json, binaries.jsonl, on_* hooks
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Tools like `abx-dl` and ArchiveBox can discover plugins from this package
|
|
50
|
+
without symlinks or environment-variable tricks.
|
|
51
|
+
|
|
52
|
+
## Plugin Contract
|
|
53
|
+
|
|
54
|
+
### Directory layout
|
|
55
|
+
|
|
56
|
+
Each plugin lives under `plugins/<name>/` and may include:
|
|
57
|
+
|
|
58
|
+
- `config.json` (optional) - config schema
|
|
59
|
+
- `binaries.jsonl` (optional) - binary manifests
|
|
60
|
+
- `on_*` hook scripts (required to do work)
|
|
61
|
+
|
|
62
|
+
Hooks run with:
|
|
63
|
+
|
|
64
|
+
- **SNAP_DIR** = base snapshot directory (default: `.`)
|
|
65
|
+
- **CRAWL_DIR** = base crawl directory (default: `.`)
|
|
66
|
+
- **Snapshot hook output** = `SNAP_DIR/<plugin>/...`
|
|
67
|
+
- **Crawl hook output** = `CRAWL_DIR/<plugin>/...`
|
|
68
|
+
- **Other plugin outputs** can be read via `../<other-plugin>/...` from your own output dir
|
|
69
|
+
|
|
70
|
+
### Key environment variables
|
|
71
|
+
|
|
72
|
+
- `SNAP_DIR` - base snapshot directory (default: `.`)
|
|
73
|
+
- `CRAWL_DIR` - base crawl directory (default: `.`)
|
|
74
|
+
- `LIB_DIR` - binaries/tools root (default: `~/.config/abx/lib`)
|
|
75
|
+
- `PERSONAS_DIR` - persona profiles root (default: `~/.config/abx/personas`)
|
|
76
|
+
- `ACTIVE_PERSONA` - persona name (default: `Default`)
|
|
77
|
+
|
|
78
|
+
### Event JSONL interface (bbus-style, no dependency)
|
|
79
|
+
|
|
80
|
+
Hooks emit JSONL events to stdout. They do **not** need to import `bbus`.
|
|
81
|
+
The event envelope matches the bbus style so higher layers can stream/replay.
|
|
82
|
+
|
|
83
|
+
Minimal envelope:
|
|
84
|
+
|
|
85
|
+
```json
|
|
86
|
+
{
|
|
87
|
+
"event_id": "uuidv7",
|
|
88
|
+
"event_type": "SnapshotCreated",
|
|
89
|
+
"event_created_at": "2026-02-01T20:10:22Z",
|
|
90
|
+
"event_parent_id": "uuidv7-or-null",
|
|
91
|
+
"event_schema": "abx.events.v1",
|
|
92
|
+
"event_path": "abx-plugins",
|
|
93
|
+
"data": { "...": "event-specific fields" }
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Conventions:
|
|
98
|
+
|
|
99
|
+
- Active verb names are **requests** (e.g. `BinaryInstall`, `ProcessLaunch`).
|
|
100
|
+
- Past tense names are **facts** (e.g. `BinaryInstalled`, `ProcessExited`).
|
|
101
|
+
- Plugins can emit additional fields inside `data` without coordination.
|
|
102
|
+
|
|
103
|
+
Common event types emitted by hooks:
|
|
104
|
+
|
|
105
|
+
- `ArchiveResultCreated` (status + output files)
|
|
106
|
+
- `Binary` records (dependency detection/install)
|
|
107
|
+
- `ProcessStarted` / `ProcessExited`
|
|
108
|
+
|
|
109
|
+
Higher-level tools (abx-dl / ArchiveBox) can:
|
|
110
|
+
|
|
111
|
+
- Parse these events from stdout
|
|
112
|
+
- Persist or project them (SQLite/JSONL/Django) without plugins knowing
|
|
113
|
+
|
|
114
|
+
Legacy note:
|
|
115
|
+
|
|
116
|
+
Some hooks still emit a lightweight JSONL record with a top-level `type` field
|
|
117
|
+
(e.g., `{"type": "ArchiveResult", ...}`). Runtimes should accept those and
|
|
118
|
+
optionally translate them into the event envelope above.
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# abx-plugins
|
|
2
|
+
|
|
3
|
+
ArchiveBox-compatible plugin suite (hooks, config schemas, binaries manifests).
|
|
4
|
+
|
|
5
|
+
This package contains only plugin assets and a tiny helper to locate them.
|
|
6
|
+
It does **not** depend on Django or ArchiveBox.
|
|
7
|
+
|
|
8
|
+
## Usage
|
|
9
|
+
|
|
10
|
+
```python
|
|
11
|
+
from abx_plugins import get_plugins_dir
|
|
12
|
+
|
|
13
|
+
plugins_dir = get_plugins_dir()
|
|
14
|
+
# scan plugins_dir for plugins/*/config.json, binaries.jsonl, on_* hooks
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Tools like `abx-dl` and ArchiveBox can discover plugins from this package
|
|
18
|
+
without symlinks or environment-variable tricks.
|
|
19
|
+
|
|
20
|
+
## Plugin Contract
|
|
21
|
+
|
|
22
|
+
### Directory layout
|
|
23
|
+
|
|
24
|
+
Each plugin lives under `plugins/<name>/` and may include:
|
|
25
|
+
|
|
26
|
+
- `config.json` (optional) - config schema
|
|
27
|
+
- `binaries.jsonl` (optional) - binary manifests
|
|
28
|
+
- `on_*` hook scripts (required to do work)
|
|
29
|
+
|
|
30
|
+
Hooks run with:
|
|
31
|
+
|
|
32
|
+
- **SNAP_DIR** = base snapshot directory (default: `.`)
|
|
33
|
+
- **CRAWL_DIR** = base crawl directory (default: `.`)
|
|
34
|
+
- **Snapshot hook output** = `SNAP_DIR/<plugin>/...`
|
|
35
|
+
- **Crawl hook output** = `CRAWL_DIR/<plugin>/...`
|
|
36
|
+
- **Other plugin outputs** can be read via `../<other-plugin>/...` from your own output dir
|
|
37
|
+
|
|
38
|
+
### Key environment variables
|
|
39
|
+
|
|
40
|
+
- `SNAP_DIR` - base snapshot directory (default: `.`)
|
|
41
|
+
- `CRAWL_DIR` - base crawl directory (default: `.`)
|
|
42
|
+
- `LIB_DIR` - binaries/tools root (default: `~/.config/abx/lib`)
|
|
43
|
+
- `PERSONAS_DIR` - persona profiles root (default: `~/.config/abx/personas`)
|
|
44
|
+
- `ACTIVE_PERSONA` - persona name (default: `Default`)
|
|
45
|
+
|
|
46
|
+
### Event JSONL interface (bbus-style, no dependency)
|
|
47
|
+
|
|
48
|
+
Hooks emit JSONL events to stdout. They do **not** need to import `bbus`.
|
|
49
|
+
The event envelope matches the bbus style so higher layers can stream/replay.
|
|
50
|
+
|
|
51
|
+
Minimal envelope:
|
|
52
|
+
|
|
53
|
+
```json
|
|
54
|
+
{
|
|
55
|
+
"event_id": "uuidv7",
|
|
56
|
+
"event_type": "SnapshotCreated",
|
|
57
|
+
"event_created_at": "2026-02-01T20:10:22Z",
|
|
58
|
+
"event_parent_id": "uuidv7-or-null",
|
|
59
|
+
"event_schema": "abx.events.v1",
|
|
60
|
+
"event_path": "abx-plugins",
|
|
61
|
+
"data": { "...": "event-specific fields" }
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Conventions:
|
|
66
|
+
|
|
67
|
+
- Active verb names are **requests** (e.g. `BinaryInstall`, `ProcessLaunch`).
|
|
68
|
+
- Past tense names are **facts** (e.g. `BinaryInstalled`, `ProcessExited`).
|
|
69
|
+
- Plugins can emit additional fields inside `data` without coordination.
|
|
70
|
+
|
|
71
|
+
Common event types emitted by hooks:
|
|
72
|
+
|
|
73
|
+
- `ArchiveResultCreated` (status + output files)
|
|
74
|
+
- `Binary` records (dependency detection/install)
|
|
75
|
+
- `ProcessStarted` / `ProcessExited`
|
|
76
|
+
|
|
77
|
+
Higher-level tools (abx-dl / ArchiveBox) can:
|
|
78
|
+
|
|
79
|
+
- Parse these events from stdout
|
|
80
|
+
- Persist or project them (SQLite/JSONL/Django) without plugins knowing
|
|
81
|
+
|
|
82
|
+
Legacy note:
|
|
83
|
+
|
|
84
|
+
Some hooks still emit a lightweight JSONL record with a top-level `type` field
|
|
85
|
+
(e.g., `{"type": "ArchiveResult", ...}`). Runtimes should accept those and
|
|
86
|
+
optionally translate them into the event envelope above.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"""Plugin suite package for ArchiveBox-compatible tools."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from importlib import resources
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def get_plugins_dir() -> Path:
|
|
10
|
+
"""Return the filesystem path to the bundled plugins directory."""
|
|
11
|
+
return Path(resources.files(__name__) / "plugins")
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
__all__ = ["get_plugins_dir"]
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Plugin suite root package for abx-plugins."""
|
|
File without changes
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"type": "object",
|
|
4
|
+
"additionalProperties": false,
|
|
5
|
+
"required_plugins": ["chrome"],
|
|
6
|
+
"properties": {
|
|
7
|
+
"ACCESSIBILITY_ENABLED": {
|
|
8
|
+
"type": "boolean",
|
|
9
|
+
"default": true,
|
|
10
|
+
"x-aliases": ["SAVE_ACCESSIBILITY", "USE_ACCESSIBILITY"],
|
|
11
|
+
"description": "Enable accessibility tree capture"
|
|
12
|
+
},
|
|
13
|
+
"ACCESSIBILITY_TIMEOUT": {
|
|
14
|
+
"type": "integer",
|
|
15
|
+
"default": 30,
|
|
16
|
+
"minimum": 5,
|
|
17
|
+
"x-fallback": "TIMEOUT",
|
|
18
|
+
"description": "Timeout for accessibility capture in seconds"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Extract accessibility tree and page outline from a URL.
|
|
4
|
+
*
|
|
5
|
+
* Extracts:
|
|
6
|
+
* - Page outline (headings h1-h6, sections, articles)
|
|
7
|
+
* - Iframe tree
|
|
8
|
+
* - Accessibility snapshot
|
|
9
|
+
* - ARIA labels and roles
|
|
10
|
+
*
|
|
11
|
+
* Usage: on_Snapshot__39_accessibility.js --url=<url> --snapshot-id=<uuid>
|
|
12
|
+
* Output: Writes accessibility/accessibility.json
|
|
13
|
+
*
|
|
14
|
+
* Environment variables:
|
|
15
|
+
* SAVE_ACCESSIBILITY: Enable accessibility extraction (default: true)
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
const fs = require('fs');
|
|
19
|
+
const path = require('path');
|
|
20
|
+
// Add NODE_MODULES_DIR to module resolution paths if set
|
|
21
|
+
if (process.env.NODE_MODULES_DIR) module.paths.unshift(process.env.NODE_MODULES_DIR);
|
|
22
|
+
const puppeteer = require('puppeteer-core');
|
|
23
|
+
|
|
24
|
+
// Extractor metadata
|
|
25
|
+
const PLUGIN_NAME = 'accessibility';
|
|
26
|
+
const PLUGIN_DIR = path.basename(__dirname);
|
|
27
|
+
const SNAP_DIR = path.resolve((process.env.SNAP_DIR || '.').trim());
|
|
28
|
+
const OUTPUT_DIR = path.join(SNAP_DIR, PLUGIN_DIR);
|
|
29
|
+
if (!fs.existsSync(OUTPUT_DIR)) {
|
|
30
|
+
fs.mkdirSync(OUTPUT_DIR, { recursive: true });
|
|
31
|
+
}
|
|
32
|
+
process.chdir(OUTPUT_DIR);
|
|
33
|
+
const OUTPUT_FILE = 'accessibility.json';
|
|
34
|
+
const CHROME_SESSION_DIR = '../chrome';
|
|
35
|
+
const CHROME_SESSION_REQUIRED_ERROR = 'No Chrome session found (chrome plugin must run first)';
|
|
36
|
+
|
|
37
|
+
// Parse command line arguments
|
|
38
|
+
function parseArgs() {
|
|
39
|
+
const args = {};
|
|
40
|
+
process.argv.slice(2).forEach(arg => {
|
|
41
|
+
if (arg.startsWith('--')) {
|
|
42
|
+
const [key, ...valueParts] = arg.slice(2).split('=');
|
|
43
|
+
args[key.replace(/-/g, '_')] = valueParts.join('=') || true;
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
return args;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Get environment variable with default
|
|
50
|
+
function getEnv(name, defaultValue = '') {
|
|
51
|
+
return (process.env[name] || defaultValue).trim();
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function getEnvBool(name, defaultValue = false) {
|
|
55
|
+
const val = getEnv(name, '').toLowerCase();
|
|
56
|
+
if (['true', '1', 'yes', 'on'].includes(val)) return true;
|
|
57
|
+
if (['false', '0', 'no', 'off'].includes(val)) return false;
|
|
58
|
+
return defaultValue;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Wait for chrome tab to be fully loaded
|
|
62
|
+
async function waitForChromeTabLoaded(timeoutMs = 60000) {
|
|
63
|
+
const navigationFile = path.join(CHROME_SESSION_DIR, 'navigation.json');
|
|
64
|
+
const startTime = Date.now();
|
|
65
|
+
|
|
66
|
+
while (Date.now() - startTime < timeoutMs) {
|
|
67
|
+
if (fs.existsSync(navigationFile)) {
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
// Wait 100ms before checking again
|
|
71
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Get CDP URL from chrome plugin
|
|
78
|
+
function getCdpUrl() {
|
|
79
|
+
const cdpFile = path.join(CHROME_SESSION_DIR, 'cdp_url.txt');
|
|
80
|
+
if (fs.existsSync(cdpFile)) {
|
|
81
|
+
return fs.readFileSync(cdpFile, 'utf8').trim();
|
|
82
|
+
}
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function assertChromeSession() {
|
|
87
|
+
const cdpFile = path.join(CHROME_SESSION_DIR, 'cdp_url.txt');
|
|
88
|
+
const targetIdFile = path.join(CHROME_SESSION_DIR, 'target_id.txt');
|
|
89
|
+
const pidFile = path.join(CHROME_SESSION_DIR, 'chrome.pid');
|
|
90
|
+
if (!fs.existsSync(cdpFile) || !fs.existsSync(targetIdFile) || !fs.existsSync(pidFile)) {
|
|
91
|
+
throw new Error(CHROME_SESSION_REQUIRED_ERROR);
|
|
92
|
+
}
|
|
93
|
+
try {
|
|
94
|
+
const pid = parseInt(fs.readFileSync(pidFile, 'utf8').trim(), 10);
|
|
95
|
+
if (!pid || Number.isNaN(pid)) throw new Error('Invalid pid');
|
|
96
|
+
process.kill(pid, 0);
|
|
97
|
+
} catch (e) {
|
|
98
|
+
throw new Error(CHROME_SESSION_REQUIRED_ERROR);
|
|
99
|
+
}
|
|
100
|
+
const cdpUrl = getCdpUrl();
|
|
101
|
+
if (!cdpUrl) {
|
|
102
|
+
throw new Error(CHROME_SESSION_REQUIRED_ERROR);
|
|
103
|
+
}
|
|
104
|
+
return cdpUrl;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Extract accessibility info
|
|
108
|
+
async function extractAccessibility(url) {
|
|
109
|
+
// Output directory is current directory (hook already runs in output dir)
|
|
110
|
+
const outputPath = path.join(OUTPUT_DIR, OUTPUT_FILE);
|
|
111
|
+
|
|
112
|
+
let browser = null;
|
|
113
|
+
|
|
114
|
+
try {
|
|
115
|
+
// Connect to existing Chrome session
|
|
116
|
+
const cdpUrl = assertChromeSession();
|
|
117
|
+
|
|
118
|
+
browser = await puppeteer.connect({
|
|
119
|
+
browserWSEndpoint: cdpUrl,
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
// Get the page
|
|
123
|
+
const pages = await browser.pages();
|
|
124
|
+
const page = pages.find(p => p.url().startsWith('http')) || pages[0];
|
|
125
|
+
|
|
126
|
+
if (!page) {
|
|
127
|
+
return { success: false, error: 'No page found in Chrome session' };
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Get accessibility snapshot
|
|
131
|
+
const accessibilityTree = await page.accessibility.snapshot({ interestingOnly: true });
|
|
132
|
+
|
|
133
|
+
// Extract page outline (headings, sections, etc.)
|
|
134
|
+
const outline = await page.evaluate(() => {
|
|
135
|
+
const headings = [];
|
|
136
|
+
const elements = document.querySelectorAll(
|
|
137
|
+
'h1, h2, h3, h4, h5, h6, a[name], header, footer, article, main, aside, nav, section, figure, summary, table, form, iframe'
|
|
138
|
+
);
|
|
139
|
+
|
|
140
|
+
elements.forEach(elem => {
|
|
141
|
+
// Skip unnamed anchors
|
|
142
|
+
if (elem.tagName.toLowerCase() === 'a' && !elem.name) return;
|
|
143
|
+
|
|
144
|
+
const tagName = elem.tagName.toLowerCase();
|
|
145
|
+
const elemId = elem.id || elem.name || elem.getAttribute('aria-label') || elem.role || '';
|
|
146
|
+
const elemClasses = (elem.className || '').toString().trim().split(/\s+/).slice(0, 3).join(' .');
|
|
147
|
+
const action = elem.action?.split('/').pop() || '';
|
|
148
|
+
|
|
149
|
+
let summary = (elem.innerText || '').slice(0, 128);
|
|
150
|
+
if (summary.length >= 128) summary += '...';
|
|
151
|
+
|
|
152
|
+
let prefix = '';
|
|
153
|
+
let title = '';
|
|
154
|
+
|
|
155
|
+
// Format headings with # prefix
|
|
156
|
+
const level = parseInt(tagName.replace('h', ''));
|
|
157
|
+
if (!isNaN(level)) {
|
|
158
|
+
prefix = '#'.repeat(level);
|
|
159
|
+
title = elem.innerText || elemId || elemClasses;
|
|
160
|
+
} else {
|
|
161
|
+
// For other elements, create breadcrumb path
|
|
162
|
+
const parents = [tagName];
|
|
163
|
+
let node = elem.parentNode;
|
|
164
|
+
while (node && parents.length < 5) {
|
|
165
|
+
if (node.tagName) {
|
|
166
|
+
const tag = node.tagName.toLowerCase();
|
|
167
|
+
if (!['div', 'span', 'p', 'body', 'html'].includes(tag)) {
|
|
168
|
+
parents.unshift(tag);
|
|
169
|
+
} else {
|
|
170
|
+
parents.unshift('');
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
node = node.parentNode;
|
|
174
|
+
}
|
|
175
|
+
prefix = parents.join('>');
|
|
176
|
+
|
|
177
|
+
title = elemId ? `#${elemId}` : '';
|
|
178
|
+
if (!title && elemClasses) title = `.${elemClasses}`;
|
|
179
|
+
if (action) title += ` /${action}`;
|
|
180
|
+
if (summary && !title.includes(summary)) title += `: ${summary}`;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Clean up title
|
|
184
|
+
title = title.replace(/\s+/g, ' ').trim();
|
|
185
|
+
|
|
186
|
+
if (prefix) {
|
|
187
|
+
headings.push(`${prefix} ${title}`);
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
return headings;
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
// Get iframe tree
|
|
195
|
+
const iframes = [];
|
|
196
|
+
function dumpFrameTree(frame, indent = '>') {
|
|
197
|
+
iframes.push(indent + frame.url());
|
|
198
|
+
for (const child of frame.childFrames()) {
|
|
199
|
+
dumpFrameTree(child, indent + '>');
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
dumpFrameTree(page.mainFrame(), '');
|
|
203
|
+
|
|
204
|
+
const accessibilityData = {
|
|
205
|
+
url,
|
|
206
|
+
headings: outline,
|
|
207
|
+
iframes,
|
|
208
|
+
tree: accessibilityTree,
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
// Write output
|
|
212
|
+
fs.writeFileSync(outputPath, JSON.stringify(accessibilityData, null, 2));
|
|
213
|
+
|
|
214
|
+
return { success: true, output: outputPath, accessibilityData };
|
|
215
|
+
|
|
216
|
+
} catch (e) {
|
|
217
|
+
return { success: false, error: `${e.name}: ${e.message}` };
|
|
218
|
+
} finally {
|
|
219
|
+
if (browser) {
|
|
220
|
+
browser.disconnect();
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
async function main() {
|
|
226
|
+
const args = parseArgs();
|
|
227
|
+
const url = args.url;
|
|
228
|
+
const snapshotId = args.snapshot_id;
|
|
229
|
+
|
|
230
|
+
if (!url || !snapshotId) {
|
|
231
|
+
console.error('Usage: on_Snapshot__39_accessibility.js --url=<url> --snapshot-id=<uuid>');
|
|
232
|
+
process.exit(1);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
const startTs = new Date();
|
|
236
|
+
let status = 'failed';
|
|
237
|
+
let output = null;
|
|
238
|
+
let error = '';
|
|
239
|
+
|
|
240
|
+
try {
|
|
241
|
+
// Check if enabled
|
|
242
|
+
if (!getEnvBool('ACCESSIBILITY_ENABLED', true)) {
|
|
243
|
+
console.log('Skipping accessibility (ACCESSIBILITY_ENABLED=False)');
|
|
244
|
+
// Output clean JSONL (no RESULT_JSON= prefix)
|
|
245
|
+
console.log(JSON.stringify({
|
|
246
|
+
type: 'ArchiveResult',
|
|
247
|
+
status: 'skipped',
|
|
248
|
+
output_str: 'ACCESSIBILITY_ENABLED=False',
|
|
249
|
+
}));
|
|
250
|
+
process.exit(0);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// Check if Chrome session exists, then wait for page load
|
|
254
|
+
assertChromeSession();
|
|
255
|
+
const pageLoaded = await waitForChromeTabLoaded(60000);
|
|
256
|
+
if (!pageLoaded) {
|
|
257
|
+
throw new Error('Page not loaded after 60s (chrome_navigate must complete first)');
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
const result = await extractAccessibility(url);
|
|
261
|
+
|
|
262
|
+
if (result.success) {
|
|
263
|
+
status = 'succeeded';
|
|
264
|
+
output = result.output;
|
|
265
|
+
const headingCount = result.accessibilityData.headings.length;
|
|
266
|
+
const iframeCount = result.accessibilityData.iframes.length;
|
|
267
|
+
console.log(`Accessibility extracted: ${headingCount} headings, ${iframeCount} iframes`);
|
|
268
|
+
} else {
|
|
269
|
+
status = 'failed';
|
|
270
|
+
error = result.error;
|
|
271
|
+
}
|
|
272
|
+
} catch (e) {
|
|
273
|
+
error = `${e.name}: ${e.message}`;
|
|
274
|
+
status = 'failed';
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
const endTs = new Date();
|
|
278
|
+
|
|
279
|
+
if (error) console.error(`ERROR: ${error}`);
|
|
280
|
+
|
|
281
|
+
// Output clean JSONL (no RESULT_JSON= prefix)
|
|
282
|
+
console.log(JSON.stringify({
|
|
283
|
+
type: 'ArchiveResult',
|
|
284
|
+
status,
|
|
285
|
+
output_str: output || error || '',
|
|
286
|
+
}));
|
|
287
|
+
|
|
288
|
+
process.exit(status === 'succeeded' ? 0 : 1);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
main().catch(e => {
|
|
292
|
+
console.error(`Fatal error: ${e.message}`);
|
|
293
|
+
process.exit(1);
|
|
294
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<span class="abx-output-icon abx-output-icon--accessibility" title="Accessibility"><svg width="16" height="16" viewBox="0 0 24 24" aria-hidden="true" focusable="false" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="4.5" r="2" fill="currentColor" stroke="none"/><path d="M4 7.5h16"/><path d="M12 7.5v12"/><path d="M7 20l5-6 5 6"/></svg></span>
|
|
File without changes
|