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.
Files changed (339) hide show
  1. abx_plugins-0.9.0/.gitignore +6 -0
  2. abx_plugins-0.9.0/LICENSE +21 -0
  3. abx_plugins-0.9.0/PKG-INFO +118 -0
  4. abx_plugins-0.9.0/README.md +86 -0
  5. abx_plugins-0.9.0/abx_plugins/__init__.py +14 -0
  6. abx_plugins-0.9.0/abx_plugins/plugins/.coverage +0 -0
  7. abx_plugins-0.9.0/abx_plugins/plugins/__init__.py +1 -0
  8. abx_plugins-0.9.0/abx_plugins/plugins/accessibility/__init__.py +0 -0
  9. abx_plugins-0.9.0/abx_plugins/plugins/accessibility/config.json +21 -0
  10. abx_plugins-0.9.0/abx_plugins/plugins/accessibility/on_Snapshot__39_accessibility.js +294 -0
  11. abx_plugins-0.9.0/abx_plugins/plugins/accessibility/templates/icon.html +1 -0
  12. abx_plugins-0.9.0/abx_plugins/plugins/accessibility/tests/__init__.py +0 -0
  13. abx_plugins-0.9.0/abx_plugins/plugins/accessibility/tests/test_accessibility.py +195 -0
  14. abx_plugins-0.9.0/abx_plugins/plugins/apt/__init__.py +0 -0
  15. abx_plugins-0.9.0/abx_plugins/plugins/apt/on_Binary__13_apt_install.py +89 -0
  16. abx_plugins-0.9.0/abx_plugins/plugins/apt/templates/icon.html +0 -0
  17. abx_plugins-0.9.0/abx_plugins/plugins/apt/tests/__init__.py +0 -0
  18. abx_plugins-0.9.0/abx_plugins/plugins/apt/tests/test_apt_provider.py +153 -0
  19. abx_plugins-0.9.0/abx_plugins/plugins/archivedotorg/__init__.py +0 -0
  20. abx_plugins-0.9.0/abx_plugins/plugins/archivedotorg/config.json +26 -0
  21. abx_plugins-0.9.0/abx_plugins/plugins/archivedotorg/on_Snapshot__08_archivedotorg.bg.py +154 -0
  22. abx_plugins-0.9.0/abx_plugins/plugins/archivedotorg/templates/card.html +12 -0
  23. abx_plugins-0.9.0/abx_plugins/plugins/archivedotorg/templates/icon.html +1 -0
  24. abx_plugins-0.9.0/abx_plugins/plugins/archivedotorg/tests/__init__.py +0 -0
  25. abx_plugins-0.9.0/abx_plugins/plugins/archivedotorg/tests/test_archivedotorg.py +93 -0
  26. abx_plugins-0.9.0/abx_plugins/plugins/brew/__init__.py +0 -0
  27. abx_plugins-0.9.0/abx_plugins/plugins/brew/on_Binary__12_brew_install.py +91 -0
  28. abx_plugins-0.9.0/abx_plugins/plugins/brew/templates/icon.html +0 -0
  29. abx_plugins-0.9.0/abx_plugins/plugins/chrome/__init__.py +0 -0
  30. abx_plugins-0.9.0/abx_plugins/plugins/chrome/chrome_utils.js +2038 -0
  31. abx_plugins-0.9.0/abx_plugins/plugins/chrome/config.json +157 -0
  32. abx_plugins-0.9.0/abx_plugins/plugins/chrome/extract_cookies.js +254 -0
  33. abx_plugins-0.9.0/abx_plugins/plugins/chrome/on_Crawl__70_chrome_install.py +46 -0
  34. abx_plugins-0.9.0/abx_plugins/plugins/chrome/on_Crawl__90_chrome_launch.bg.js +433 -0
  35. abx_plugins-0.9.0/abx_plugins/plugins/chrome/on_Snapshot__10_chrome_tab.bg.js +265 -0
  36. abx_plugins-0.9.0/abx_plugins/plugins/chrome/on_Snapshot__11_chrome_wait.js +85 -0
  37. abx_plugins-0.9.0/abx_plugins/plugins/chrome/on_Snapshot__30_chrome_navigate.js +231 -0
  38. abx_plugins-0.9.0/abx_plugins/plugins/chrome/templates/icon.html +1 -0
  39. abx_plugins-0.9.0/abx_plugins/plugins/chrome/tests/__init__.py +0 -0
  40. abx_plugins-0.9.0/abx_plugins/plugins/chrome/tests/chrome_test_helpers.py +997 -0
  41. abx_plugins-0.9.0/abx_plugins/plugins/chrome/tests/test_chrome.py +725 -0
  42. abx_plugins-0.9.0/abx_plugins/plugins/chrome/tests/test_chrome_test_helpers.py +257 -0
  43. abx_plugins-0.9.0/abx_plugins/plugins/consolelog/__init__.py +0 -0
  44. abx_plugins-0.9.0/abx_plugins/plugins/consolelog/config.json +21 -0
  45. abx_plugins-0.9.0/abx_plugins/plugins/consolelog/on_Snapshot__21_consolelog.bg.js +207 -0
  46. abx_plugins-0.9.0/abx_plugins/plugins/consolelog/templates/icon.html +1 -0
  47. abx_plugins-0.9.0/abx_plugins/plugins/consolelog/tests/__init__.py +0 -0
  48. abx_plugins-0.9.0/abx_plugins/plugins/consolelog/tests/test_consolelog.py +126 -0
  49. abx_plugins-0.9.0/abx_plugins/plugins/custom/__init__.py +0 -0
  50. abx_plugins-0.9.0/abx_plugins/plugins/custom/on_Binary__14_custom_install.py +99 -0
  51. abx_plugins-0.9.0/abx_plugins/plugins/custom/templates/icon.html +0 -0
  52. abx_plugins-0.9.0/abx_plugins/plugins/custom/tests/__init__.py +0 -0
  53. abx_plugins-0.9.0/abx_plugins/plugins/custom/tests/test_custom_provider.py +148 -0
  54. abx_plugins-0.9.0/abx_plugins/plugins/dns/__init__.py +0 -0
  55. abx_plugins-0.9.0/abx_plugins/plugins/dns/config.json +21 -0
  56. abx_plugins-0.9.0/abx_plugins/plugins/dns/on_Snapshot__22_dns.bg.js +271 -0
  57. abx_plugins-0.9.0/abx_plugins/plugins/dns/templates/icon.html +1 -0
  58. abx_plugins-0.9.0/abx_plugins/plugins/dns/tests/__init__.py +0 -0
  59. abx_plugins-0.9.0/abx_plugins/plugins/dns/tests/test_dns.py +125 -0
  60. abx_plugins-0.9.0/abx_plugins/plugins/dom/__init__.py +0 -0
  61. abx_plugins-0.9.0/abx_plugins/plugins/dom/config.json +21 -0
  62. abx_plugins-0.9.0/abx_plugins/plugins/dom/on_Snapshot__53_dom.js +190 -0
  63. abx_plugins-0.9.0/abx_plugins/plugins/dom/templates/card.html +8 -0
  64. abx_plugins-0.9.0/abx_plugins/plugins/dom/templates/icon.html +1 -0
  65. abx_plugins-0.9.0/abx_plugins/plugins/dom/tests/__init__.py +0 -0
  66. abx_plugins-0.9.0/abx_plugins/plugins/dom/tests/test_dom.py +187 -0
  67. abx_plugins-0.9.0/abx_plugins/plugins/env/__init__.py +0 -0
  68. abx_plugins-0.9.0/abx_plugins/plugins/env/on_Binary__15_env_install.py +73 -0
  69. abx_plugins-0.9.0/abx_plugins/plugins/env/templates/icon.html +0 -0
  70. abx_plugins-0.9.0/abx_plugins/plugins/env/tests/__init__.py +0 -0
  71. abx_plugins-0.9.0/abx_plugins/plugins/env/tests/test_env_provider.py +158 -0
  72. abx_plugins-0.9.0/abx_plugins/plugins/favicon/__init__.py +0 -0
  73. abx_plugins-0.9.0/abx_plugins/plugins/favicon/config.json +26 -0
  74. abx_plugins-0.9.0/abx_plugins/plugins/favicon/on_Snapshot__11_favicon.bg.py +154 -0
  75. abx_plugins-0.9.0/abx_plugins/plugins/favicon/templates/card.html +9 -0
  76. abx_plugins-0.9.0/abx_plugins/plugins/favicon/templates/icon.html +1 -0
  77. abx_plugins-0.9.0/abx_plugins/plugins/favicon/tests/__init__.py +0 -0
  78. abx_plugins-0.9.0/abx_plugins/plugins/favicon/tests/test_favicon.py +308 -0
  79. abx_plugins-0.9.0/abx_plugins/plugins/forumdl/__init__.py +0 -0
  80. abx_plugins-0.9.0/abx_plugins/plugins/forumdl/config.json +51 -0
  81. abx_plugins-0.9.0/abx_plugins/plugins/forumdl/forum-dl-wrapper.py +38 -0
  82. abx_plugins-0.9.0/abx_plugins/plugins/forumdl/on_Crawl__25_forumdl_install.py +94 -0
  83. abx_plugins-0.9.0/abx_plugins/plugins/forumdl/on_Snapshot__04_forumdl.bg.py +267 -0
  84. abx_plugins-0.9.0/abx_plugins/plugins/forumdl/templates/card.html +7 -0
  85. abx_plugins-0.9.0/abx_plugins/plugins/forumdl/templates/full.html +147 -0
  86. abx_plugins-0.9.0/abx_plugins/plugins/forumdl/templates/icon.html +1 -0
  87. abx_plugins-0.9.0/abx_plugins/plugins/forumdl/tests/__init__.py +0 -0
  88. abx_plugins-0.9.0/abx_plugins/plugins/forumdl/tests/test_forumdl.py +316 -0
  89. abx_plugins-0.9.0/abx_plugins/plugins/gallerydl/__init__.py +0 -0
  90. abx_plugins-0.9.0/abx_plugins/plugins/gallerydl/config.json +54 -0
  91. abx_plugins-0.9.0/abx_plugins/plugins/gallerydl/on_Crawl__20_gallerydl_install.py +61 -0
  92. abx_plugins-0.9.0/abx_plugins/plugins/gallerydl/on_Snapshot__03_gallerydl.bg.py +260 -0
  93. abx_plugins-0.9.0/abx_plugins/plugins/gallerydl/templates/card.html +11 -0
  94. abx_plugins-0.9.0/abx_plugins/plugins/gallerydl/templates/full.html +28 -0
  95. abx_plugins-0.9.0/abx_plugins/plugins/gallerydl/templates/icon.html +1 -0
  96. abx_plugins-0.9.0/abx_plugins/plugins/gallerydl/tests/__init__.py +0 -0
  97. abx_plugins-0.9.0/abx_plugins/plugins/gallerydl/tests/test_gallerydl.py +190 -0
  98. abx_plugins-0.9.0/abx_plugins/plugins/git/__init__.py +0 -0
  99. abx_plugins-0.9.0/abx_plugins/plugins/git/config.json +44 -0
  100. abx_plugins-0.9.0/abx_plugins/plugins/git/on_Crawl__05_git_install.py +61 -0
  101. abx_plugins-0.9.0/abx_plugins/plugins/git/on_Snapshot__05_git.bg.py +144 -0
  102. abx_plugins-0.9.0/abx_plugins/plugins/git/templates/card.html +5 -0
  103. abx_plugins-0.9.0/abx_plugins/plugins/git/templates/icon.html +1 -0
  104. abx_plugins-0.9.0/abx_plugins/plugins/git/tests/__init__.py +0 -0
  105. abx_plugins-0.9.0/abx_plugins/plugins/git/tests/test_git.py +130 -0
  106. abx_plugins-0.9.0/abx_plugins/plugins/hashes/__init__.py +0 -0
  107. abx_plugins-0.9.0/abx_plugins/plugins/hashes/config.json +20 -0
  108. abx_plugins-0.9.0/abx_plugins/plugins/hashes/on_Snapshot__93_hashes.py +188 -0
  109. abx_plugins-0.9.0/abx_plugins/plugins/hashes/templates/icon.html +1 -0
  110. abx_plugins-0.9.0/abx_plugins/plugins/hashes/tests/__init__.py +0 -0
  111. abx_plugins-0.9.0/abx_plugins/plugins/hashes/tests/test_hashes.py +159 -0
  112. abx_plugins-0.9.0/abx_plugins/plugins/headers/__init__.py +0 -0
  113. abx_plugins-0.9.0/abx_plugins/plugins/headers/config.json +21 -0
  114. abx_plugins-0.9.0/abx_plugins/plugins/headers/on_Snapshot__27_headers.bg.js +253 -0
  115. abx_plugins-0.9.0/abx_plugins/plugins/headers/templates/icon.html +1 -0
  116. abx_plugins-0.9.0/abx_plugins/plugins/headers/tests/__init__.py +0 -0
  117. abx_plugins-0.9.0/abx_plugins/plugins/headers/tests/test_headers.py +409 -0
  118. abx_plugins-0.9.0/abx_plugins/plugins/htmltotext/__init__.py +0 -0
  119. abx_plugins-0.9.0/abx_plugins/plugins/htmltotext/config.json +20 -0
  120. abx_plugins-0.9.0/abx_plugins/plugins/htmltotext/on_Snapshot__58_htmltotext.py +162 -0
  121. abx_plugins-0.9.0/abx_plugins/plugins/htmltotext/templates/icon.html +1 -0
  122. abx_plugins-0.9.0/abx_plugins/plugins/htmltotext/tests/__init__.py +0 -0
  123. abx_plugins-0.9.0/abx_plugins/plugins/htmltotext/tests/test_htmltotext.py +93 -0
  124. abx_plugins-0.9.0/abx_plugins/plugins/infiniscroll/__init__.py +0 -0
  125. abx_plugins-0.9.0/abx_plugins/plugins/infiniscroll/config.json +51 -0
  126. abx_plugins-0.9.0/abx_plugins/plugins/infiniscroll/on_Snapshot__45_infiniscroll.js +435 -0
  127. abx_plugins-0.9.0/abx_plugins/plugins/infiniscroll/templates/icon.html +1 -0
  128. abx_plugins-0.9.0/abx_plugins/plugins/infiniscroll/tests/__init__.py +0 -0
  129. abx_plugins-0.9.0/abx_plugins/plugins/infiniscroll/tests/test_infiniscroll.py +248 -0
  130. abx_plugins-0.9.0/abx_plugins/plugins/istilldontcareaboutcookies/__init__.py +0 -0
  131. abx_plugins-0.9.0/abx_plugins/plugins/istilldontcareaboutcookies/config.json +14 -0
  132. abx_plugins-0.9.0/abx_plugins/plugins/istilldontcareaboutcookies/on_Crawl__81_install_istilldontcareaboutcookies_extension.js +126 -0
  133. abx_plugins-0.9.0/abx_plugins/plugins/istilldontcareaboutcookies/templates/icon.html +0 -0
  134. abx_plugins-0.9.0/abx_plugins/plugins/istilldontcareaboutcookies/tests/__init__.py +0 -0
  135. abx_plugins-0.9.0/abx_plugins/plugins/istilldontcareaboutcookies/tests/test_istilldontcareaboutcookies.py +641 -0
  136. abx_plugins-0.9.0/abx_plugins/plugins/media/__init__.py +0 -0
  137. abx_plugins-0.9.0/abx_plugins/plugins/media/tests/__init__.py +0 -0
  138. abx_plugins-0.9.0/abx_plugins/plugins/mercury/__init__.py +0 -0
  139. abx_plugins-0.9.0/abx_plugins/plugins/mercury/config.json +40 -0
  140. abx_plugins-0.9.0/abx_plugins/plugins/mercury/on_Crawl__40_mercury_install.py +67 -0
  141. abx_plugins-0.9.0/abx_plugins/plugins/mercury/on_Snapshot__57_mercury.py +199 -0
  142. abx_plugins-0.9.0/abx_plugins/plugins/mercury/templates/card.html +8 -0
  143. abx_plugins-0.9.0/abx_plugins/plugins/mercury/templates/icon.html +1 -0
  144. abx_plugins-0.9.0/abx_plugins/plugins/mercury/tests/__init__.py +0 -0
  145. abx_plugins-0.9.0/abx_plugins/plugins/mercury/tests/test_mercury.py +169 -0
  146. abx_plugins-0.9.0/abx_plugins/plugins/modalcloser/__init__.py +0 -0
  147. abx_plugins-0.9.0/abx_plugins/plugins/modalcloser/config.json +26 -0
  148. abx_plugins-0.9.0/abx_plugins/plugins/modalcloser/on_Snapshot__15_modalcloser.bg.js +341 -0
  149. abx_plugins-0.9.0/abx_plugins/plugins/modalcloser/templates/icon.html +1 -0
  150. abx_plugins-0.9.0/abx_plugins/plugins/modalcloser/tests/__init__.py +0 -0
  151. abx_plugins-0.9.0/abx_plugins/plugins/modalcloser/tests/test_modalcloser.py +459 -0
  152. abx_plugins-0.9.0/abx_plugins/plugins/npm/__init__.py +0 -0
  153. abx_plugins-0.9.0/abx_plugins/plugins/npm/on_Binary__10_npm_install.py +130 -0
  154. abx_plugins-0.9.0/abx_plugins/plugins/npm/on_Crawl__00_npm_install.py +62 -0
  155. abx_plugins-0.9.0/abx_plugins/plugins/npm/templates/icon.html +0 -0
  156. abx_plugins-0.9.0/abx_plugins/plugins/npm/tests/__init__.py +0 -0
  157. abx_plugins-0.9.0/abx_plugins/plugins/npm/tests/test_npm_provider.py +145 -0
  158. abx_plugins-0.9.0/abx_plugins/plugins/papersdl/__init__.py +0 -0
  159. abx_plugins-0.9.0/abx_plugins/plugins/papersdl/config.json +39 -0
  160. abx_plugins-0.9.0/abx_plugins/plugins/papersdl/on_Crawl__30_papersdl_install.py +61 -0
  161. abx_plugins-0.9.0/abx_plugins/plugins/papersdl/on_Snapshot__66_papersdl.bg.py +228 -0
  162. abx_plugins-0.9.0/abx_plugins/plugins/papersdl/templates/card.html +7 -0
  163. abx_plugins-0.9.0/abx_plugins/plugins/papersdl/templates/full.html +71 -0
  164. abx_plugins-0.9.0/abx_plugins/plugins/papersdl/templates/icon.html +1 -0
  165. abx_plugins-0.9.0/abx_plugins/plugins/papersdl/tests/__init__.py +0 -0
  166. abx_plugins-0.9.0/abx_plugins/plugins/papersdl/tests/test_papersdl.py +190 -0
  167. abx_plugins-0.9.0/abx_plugins/plugins/parse_dom_outlinks/__init__.py +0 -0
  168. abx_plugins-0.9.0/abx_plugins/plugins/parse_dom_outlinks/config.json +21 -0
  169. abx_plugins-0.9.0/abx_plugins/plugins/parse_dom_outlinks/on_Snapshot__75_parse_dom_outlinks.js +298 -0
  170. abx_plugins-0.9.0/abx_plugins/plugins/parse_dom_outlinks/templates/icon.html +1 -0
  171. abx_plugins-0.9.0/abx_plugins/plugins/parse_dom_outlinks/tests/__init__.py +0 -0
  172. abx_plugins-0.9.0/abx_plugins/plugins/parse_dom_outlinks/tests/test_parse_dom_outlinks.py +121 -0
  173. abx_plugins-0.9.0/abx_plugins/plugins/parse_html_urls/__init__.py +0 -0
  174. abx_plugins-0.9.0/abx_plugins/plugins/parse_html_urls/config.json +13 -0
  175. abx_plugins-0.9.0/abx_plugins/plugins/parse_html_urls/on_Snapshot__70_parse_html_urls.py +301 -0
  176. abx_plugins-0.9.0/abx_plugins/plugins/parse_html_urls/templates/icon.html +1 -0
  177. abx_plugins-0.9.0/abx_plugins/plugins/parse_html_urls/tests/__init__.py +0 -0
  178. abx_plugins-0.9.0/abx_plugins/plugins/parse_html_urls/tests/test_parse_html_urls.py +267 -0
  179. abx_plugins-0.9.0/abx_plugins/plugins/parse_jsonl_urls/__init__.py +0 -0
  180. abx_plugins-0.9.0/abx_plugins/plugins/parse_jsonl_urls/config.json +13 -0
  181. abx_plugins-0.9.0/abx_plugins/plugins/parse_jsonl_urls/on_Snapshot__74_parse_jsonl_urls.py +222 -0
  182. abx_plugins-0.9.0/abx_plugins/plugins/parse_jsonl_urls/templates/icon.html +1 -0
  183. abx_plugins-0.9.0/abx_plugins/plugins/parse_jsonl_urls/tests/__init__.py +0 -0
  184. abx_plugins-0.9.0/abx_plugins/plugins/parse_jsonl_urls/tests/test_parse_jsonl_urls.py +276 -0
  185. abx_plugins-0.9.0/abx_plugins/plugins/parse_netscape_urls/__init__.py +0 -0
  186. abx_plugins-0.9.0/abx_plugins/plugins/parse_netscape_urls/config.json +13 -0
  187. abx_plugins-0.9.0/abx_plugins/plugins/parse_netscape_urls/on_Snapshot__73_parse_netscape_urls.py +266 -0
  188. abx_plugins-0.9.0/abx_plugins/plugins/parse_netscape_urls/templates/icon.html +1 -0
  189. abx_plugins-0.9.0/abx_plugins/plugins/parse_netscape_urls/tests/__init__.py +0 -0
  190. abx_plugins-0.9.0/abx_plugins/plugins/parse_netscape_urls/tests/test_parse_netscape_urls.py +208 -0
  191. abx_plugins-0.9.0/abx_plugins/plugins/parse_netscape_urls/tests/test_parse_netscape_urls_comprehensive.py +953 -0
  192. abx_plugins-0.9.0/abx_plugins/plugins/parse_rss_urls/__init__.py +0 -0
  193. abx_plugins-0.9.0/abx_plugins/plugins/parse_rss_urls/config.json +13 -0
  194. abx_plugins-0.9.0/abx_plugins/plugins/parse_rss_urls/on_Snapshot__72_parse_rss_urls.py +175 -0
  195. abx_plugins-0.9.0/abx_plugins/plugins/parse_rss_urls/templates/icon.html +1 -0
  196. abx_plugins-0.9.0/abx_plugins/plugins/parse_rss_urls/tests/__init__.py +0 -0
  197. abx_plugins-0.9.0/abx_plugins/plugins/parse_rss_urls/tests/test_parse_rss_urls.py +212 -0
  198. abx_plugins-0.9.0/abx_plugins/plugins/parse_rss_urls/tests/test_parse_rss_urls_comprehensive.py +1002 -0
  199. abx_plugins-0.9.0/abx_plugins/plugins/parse_txt_urls/__init__.py +0 -0
  200. abx_plugins-0.9.0/abx_plugins/plugins/parse_txt_urls/config.json +13 -0
  201. abx_plugins-0.9.0/abx_plugins/plugins/parse_txt_urls/on_Snapshot__71_parse_txt_urls.py +173 -0
  202. abx_plugins-0.9.0/abx_plugins/plugins/parse_txt_urls/templates/icon.html +1 -0
  203. abx_plugins-0.9.0/abx_plugins/plugins/parse_txt_urls/tests/__init__.py +0 -0
  204. abx_plugins-0.9.0/abx_plugins/plugins/parse_txt_urls/tests/test_parse_txt_urls.py +193 -0
  205. abx_plugins-0.9.0/abx_plugins/plugins/path_utils.py +30 -0
  206. abx_plugins-0.9.0/abx_plugins/plugins/pdf/__init__.py +0 -0
  207. abx_plugins-0.9.0/abx_plugins/plugins/pdf/config.json +28 -0
  208. abx_plugins-0.9.0/abx_plugins/plugins/pdf/on_Snapshot__52_pdf.js +199 -0
  209. abx_plugins-0.9.0/abx_plugins/plugins/pdf/templates/card.html +6 -0
  210. abx_plugins-0.9.0/abx_plugins/plugins/pdf/templates/full.html +5 -0
  211. abx_plugins-0.9.0/abx_plugins/plugins/pdf/templates/icon.html +1 -0
  212. abx_plugins-0.9.0/abx_plugins/plugins/pdf/tests/__init__.py +0 -0
  213. abx_plugins-0.9.0/abx_plugins/plugins/pdf/tests/test_pdf.py +197 -0
  214. abx_plugins-0.9.0/abx_plugins/plugins/pip/__init__.py +0 -0
  215. abx_plugins-0.9.0/abx_plugins/plugins/pip/on_Binary__11_pip_install.py +138 -0
  216. abx_plugins-0.9.0/abx_plugins/plugins/pip/templates/icon.html +0 -0
  217. abx_plugins-0.9.0/abx_plugins/plugins/pip/tests/__init__.py +0 -0
  218. abx_plugins-0.9.0/abx_plugins/plugins/pip/tests/test_pip_provider.py +190 -0
  219. abx_plugins-0.9.0/abx_plugins/plugins/puppeteer/__init__.py +1 -0
  220. abx_plugins-0.9.0/abx_plugins/plugins/puppeteer/on_Binary__12_puppeteer_install.py +176 -0
  221. abx_plugins-0.9.0/abx_plugins/plugins/puppeteer/on_Crawl__60_puppeteer_install.py +43 -0
  222. abx_plugins-0.9.0/abx_plugins/plugins/puppeteer/tests/__init__.py +0 -0
  223. abx_plugins-0.9.0/abx_plugins/plugins/puppeteer/tests/test_puppeteer.py +123 -0
  224. abx_plugins-0.9.0/abx_plugins/plugins/readability/__init__.py +0 -0
  225. abx_plugins-0.9.0/abx_plugins/plugins/readability/config.json +39 -0
  226. abx_plugins-0.9.0/abx_plugins/plugins/readability/on_Crawl__35_readability_install.py +63 -0
  227. abx_plugins-0.9.0/abx_plugins/plugins/readability/on_Snapshot__56_readability.py +209 -0
  228. abx_plugins-0.9.0/abx_plugins/plugins/readability/templates/card.html +8 -0
  229. abx_plugins-0.9.0/abx_plugins/plugins/readability/templates/full.html +6 -0
  230. abx_plugins-0.9.0/abx_plugins/plugins/readability/templates/icon.html +1 -0
  231. abx_plugins-0.9.0/abx_plugins/plugins/readability/tests/__init__.py +0 -0
  232. abx_plugins-0.9.0/abx_plugins/plugins/readability/tests/test_readability.py +235 -0
  233. abx_plugins-0.9.0/abx_plugins/plugins/redirects/__init__.py +0 -0
  234. abx_plugins-0.9.0/abx_plugins/plugins/redirects/config.json +21 -0
  235. abx_plugins-0.9.0/abx_plugins/plugins/redirects/on_Snapshot__25_redirects.bg.js +244 -0
  236. abx_plugins-0.9.0/abx_plugins/plugins/redirects/templates/icon.html +1 -0
  237. abx_plugins-0.9.0/abx_plugins/plugins/redirects/tests/__init__.py +0 -0
  238. abx_plugins-0.9.0/abx_plugins/plugins/redirects/tests/test_redirects.py +149 -0
  239. abx_plugins-0.9.0/abx_plugins/plugins/responses/__init__.py +0 -0
  240. abx_plugins-0.9.0/abx_plugins/plugins/responses/config.json +21 -0
  241. abx_plugins-0.9.0/abx_plugins/plugins/responses/on_Snapshot__24_responses.bg.js +308 -0
  242. abx_plugins-0.9.0/abx_plugins/plugins/responses/templates/icon.html +1 -0
  243. abx_plugins-0.9.0/abx_plugins/plugins/responses/tests/__init__.py +0 -0
  244. abx_plugins-0.9.0/abx_plugins/plugins/responses/tests/test_responses.py +127 -0
  245. abx_plugins-0.9.0/abx_plugins/plugins/screenshot/__init__.py +0 -0
  246. abx_plugins-0.9.0/abx_plugins/plugins/screenshot/config.json +28 -0
  247. abx_plugins-0.9.0/abx_plugins/plugins/screenshot/on_Snapshot__51_screenshot.js +185 -0
  248. abx_plugins-0.9.0/abx_plugins/plugins/screenshot/templates/card.html +8 -0
  249. abx_plugins-0.9.0/abx_plugins/plugins/screenshot/templates/full.html +7 -0
  250. abx_plugins-0.9.0/abx_plugins/plugins/screenshot/templates/icon.html +1 -0
  251. abx_plugins-0.9.0/abx_plugins/plugins/screenshot/tests/__init__.py +0 -0
  252. abx_plugins-0.9.0/abx_plugins/plugins/screenshot/tests/test_screenshot.py +477 -0
  253. abx_plugins-0.9.0/abx_plugins/plugins/search_backend_ripgrep/__init__.py +0 -0
  254. abx_plugins-0.9.0/abx_plugins/plugins/search_backend_ripgrep/config.json +34 -0
  255. abx_plugins-0.9.0/abx_plugins/plugins/search_backend_ripgrep/on_Crawl__50_ripgrep_install.py +43 -0
  256. abx_plugins-0.9.0/abx_plugins/plugins/search_backend_ripgrep/search.py +109 -0
  257. abx_plugins-0.9.0/abx_plugins/plugins/search_backend_ripgrep/templates/icon.html +0 -0
  258. abx_plugins-0.9.0/abx_plugins/plugins/search_backend_ripgrep/tests/__init__.py +0 -0
  259. abx_plugins-0.9.0/abx_plugins/plugins/search_backend_ripgrep/tests/test_ripgrep_detection.py +144 -0
  260. abx_plugins-0.9.0/abx_plugins/plugins/search_backend_ripgrep/tests/test_ripgrep_search.py +295 -0
  261. abx_plugins-0.9.0/abx_plugins/plugins/search_backend_sonic/__init__.py +0 -0
  262. abx_plugins-0.9.0/abx_plugins/plugins/search_backend_sonic/config.json +39 -0
  263. abx_plugins-0.9.0/abx_plugins/plugins/search_backend_sonic/on_Snapshot__91_index_sonic.py +201 -0
  264. abx_plugins-0.9.0/abx_plugins/plugins/search_backend_sonic/search.py +56 -0
  265. abx_plugins-0.9.0/abx_plugins/plugins/search_backend_sonic/templates/icon.html +1 -0
  266. abx_plugins-0.9.0/abx_plugins/plugins/search_backend_sqlite/__init__.py +0 -0
  267. abx_plugins-0.9.0/abx_plugins/plugins/search_backend_sqlite/config.json +25 -0
  268. abx_plugins-0.9.0/abx_plugins/plugins/search_backend_sqlite/on_Snapshot__90_index_sqlite.py +192 -0
  269. abx_plugins-0.9.0/abx_plugins/plugins/search_backend_sqlite/search.py +75 -0
  270. abx_plugins-0.9.0/abx_plugins/plugins/search_backend_sqlite/templates/icon.html +1 -0
  271. abx_plugins-0.9.0/abx_plugins/plugins/search_backend_sqlite/tests/__init__.py +0 -0
  272. abx_plugins-0.9.0/abx_plugins/plugins/search_backend_sqlite/tests/test_sqlite_search.py +348 -0
  273. abx_plugins-0.9.0/abx_plugins/plugins/seo/__init__.py +0 -0
  274. abx_plugins-0.9.0/abx_plugins/plugins/seo/config.json +21 -0
  275. abx_plugins-0.9.0/abx_plugins/plugins/seo/on_Snapshot__38_seo.js +175 -0
  276. abx_plugins-0.9.0/abx_plugins/plugins/seo/templates/icon.html +1 -0
  277. abx_plugins-0.9.0/abx_plugins/plugins/seo/tests/__init__.py +0 -0
  278. abx_plugins-0.9.0/abx_plugins/plugins/seo/tests/test_seo.py +129 -0
  279. abx_plugins-0.9.0/abx_plugins/plugins/singlefile/__init__.py +0 -0
  280. abx_plugins-0.9.0/abx_plugins/plugins/singlefile/config.json +77 -0
  281. abx_plugins-0.9.0/abx_plugins/plugins/singlefile/on_Crawl__45_singlefile_install.py +66 -0
  282. abx_plugins-0.9.0/abx_plugins/plugins/singlefile/on_Crawl__82_singlefile_install.js +352 -0
  283. abx_plugins-0.9.0/abx_plugins/plugins/singlefile/on_Snapshot__50_singlefile.py +407 -0
  284. abx_plugins-0.9.0/abx_plugins/plugins/singlefile/singlefile_extension_save.js +210 -0
  285. abx_plugins-0.9.0/abx_plugins/plugins/singlefile/templates/card.html +8 -0
  286. abx_plugins-0.9.0/abx_plugins/plugins/singlefile/templates/icon.html +1 -0
  287. abx_plugins-0.9.0/abx_plugins/plugins/singlefile/tests/__init__.py +0 -0
  288. abx_plugins-0.9.0/abx_plugins/plugins/singlefile/tests/test_singlefile.py +304 -0
  289. abx_plugins-0.9.0/abx_plugins/plugins/ssl/__init__.py +0 -0
  290. abx_plugins-0.9.0/abx_plugins/plugins/ssl/config.json +21 -0
  291. abx_plugins-0.9.0/abx_plugins/plugins/ssl/on_Snapshot__23_ssl.bg.js +203 -0
  292. abx_plugins-0.9.0/abx_plugins/plugins/ssl/templates/icon.html +1 -0
  293. abx_plugins-0.9.0/abx_plugins/plugins/ssl/tests/__init__.py +0 -0
  294. abx_plugins-0.9.0/abx_plugins/plugins/ssl/tests/test_ssl.py +147 -0
  295. abx_plugins-0.9.0/abx_plugins/plugins/staticfile/__init__.py +0 -0
  296. abx_plugins-0.9.0/abx_plugins/plugins/staticfile/config.json +21 -0
  297. abx_plugins-0.9.0/abx_plugins/plugins/staticfile/on_Snapshot__26_staticfile.bg.js +372 -0
  298. abx_plugins-0.9.0/abx_plugins/plugins/staticfile/templates/card.html +24 -0
  299. abx_plugins-0.9.0/abx_plugins/plugins/staticfile/templates/icon.html +1 -0
  300. abx_plugins-0.9.0/abx_plugins/plugins/staticfile/tests/__init__.py +0 -0
  301. abx_plugins-0.9.0/abx_plugins/plugins/staticfile/tests/test_staticfile.py +122 -0
  302. abx_plugins-0.9.0/abx_plugins/plugins/title/__init__.py +0 -0
  303. abx_plugins-0.9.0/abx_plugins/plugins/title/config.json +21 -0
  304. abx_plugins-0.9.0/abx_plugins/plugins/title/on_Snapshot__54_title.js +145 -0
  305. abx_plugins-0.9.0/abx_plugins/plugins/title/templates/icon.html +1 -0
  306. abx_plugins-0.9.0/abx_plugins/plugins/title/tests/__init__.py +0 -0
  307. abx_plugins-0.9.0/abx_plugins/plugins/title/tests/test_title.py +279 -0
  308. abx_plugins-0.9.0/abx_plugins/plugins/twocaptcha/__init__.py +0 -0
  309. abx_plugins-0.9.0/abx_plugins/plugins/twocaptcha/config.json +50 -0
  310. abx_plugins-0.9.0/abx_plugins/plugins/twocaptcha/on_Crawl__83_twocaptcha_install.js +77 -0
  311. abx_plugins-0.9.0/abx_plugins/plugins/twocaptcha/on_Crawl__95_twocaptcha_config.js +393 -0
  312. abx_plugins-0.9.0/abx_plugins/plugins/twocaptcha/templates/icon.html +0 -0
  313. abx_plugins-0.9.0/abx_plugins/plugins/twocaptcha/tests/__init__.py +0 -0
  314. abx_plugins-0.9.0/abx_plugins/plugins/twocaptcha/tests/test_twocaptcha.py +338 -0
  315. abx_plugins-0.9.0/abx_plugins/plugins/ublock/__init__.py +0 -0
  316. abx_plugins-0.9.0/abx_plugins/plugins/ublock/config.json +14 -0
  317. abx_plugins-0.9.0/abx_plugins/plugins/ublock/on_Crawl__80_install_ublock_extension.js +71 -0
  318. abx_plugins-0.9.0/abx_plugins/plugins/ublock/templates/icon.html +0 -0
  319. abx_plugins-0.9.0/abx_plugins/plugins/ublock/tests/__init__.py +0 -0
  320. abx_plugins-0.9.0/abx_plugins/plugins/ublock/tests/test_ublock.py +725 -0
  321. abx_plugins-0.9.0/abx_plugins/plugins/wget/__init__.py +0 -0
  322. abx_plugins-0.9.0/abx_plugins/plugins/wget/config.json +75 -0
  323. abx_plugins-0.9.0/abx_plugins/plugins/wget/on_Crawl__10_wget_install.py +108 -0
  324. abx_plugins-0.9.0/abx_plugins/plugins/wget/on_Snapshot__06_wget.bg.py +241 -0
  325. abx_plugins-0.9.0/abx_plugins/plugins/wget/templates/card.html +8 -0
  326. abx_plugins-0.9.0/abx_plugins/plugins/wget/templates/icon.html +1 -0
  327. abx_plugins-0.9.0/abx_plugins/plugins/wget/tests/__init__.py +0 -0
  328. abx_plugins-0.9.0/abx_plugins/plugins/wget/tests/test_wget.py +437 -0
  329. abx_plugins-0.9.0/abx_plugins/plugins/ytdlp/__init__.py +0 -0
  330. abx_plugins-0.9.0/abx_plugins/plugins/ytdlp/config.json +92 -0
  331. abx_plugins-0.9.0/abx_plugins/plugins/ytdlp/on_Crawl__15_ytdlp_install.py +77 -0
  332. abx_plugins-0.9.0/abx_plugins/plugins/ytdlp/on_Snapshot__02_ytdlp.bg.py +269 -0
  333. abx_plugins-0.9.0/abx_plugins/plugins/ytdlp/templates/card.html +17 -0
  334. abx_plugins-0.9.0/abx_plugins/plugins/ytdlp/templates/full.html +10 -0
  335. abx_plugins-0.9.0/abx_plugins/plugins/ytdlp/templates/icon.html +1 -0
  336. abx_plugins-0.9.0/abx_plugins/plugins/ytdlp/tests/__init__.py +0 -0
  337. abx_plugins-0.9.0/abx_plugins/plugins/ytdlp/tests/test_ytdlp.py +202 -0
  338. abx_plugins-0.9.0/conftest.py +22 -0
  339. abx_plugins-0.9.0/pyproject.toml +52 -0
@@ -0,0 +1,6 @@
1
+ .DS_Store
2
+
3
+ data/
4
+ *.sqlite3*
5
+ __pycache__/
6
+ *.pyc
@@ -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"]
@@ -0,0 +1 @@
1
+ """Plugin suite root package for abx-plugins."""
@@ -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>