ofscraper-community 3.16.2__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 (563) hide show
  1. ofscraper_community-3.16.2/.dockerignore +28 -0
  2. ofscraper_community-3.16.2/.gitattributes +1 -0
  3. ofscraper_community-3.16.2/.github/ISSUE_TEMPLATE/bug_report.md +66 -0
  4. ofscraper_community-3.16.2/.github/ISSUE_TEMPLATE/feature_request.md +19 -0
  5. ofscraper_community-3.16.2/.github/actions/retry-artifact-operation/action.yml +186 -0
  6. ofscraper_community-3.16.2/.github/dependabot.yml +11 -0
  7. ofscraper_community-3.16.2/.github/workflows/codecov.yml +56 -0
  8. ofscraper_community-3.16.2/.github/workflows/commit_bundler.yml +302 -0
  9. ofscraper_community-3.16.2/.github/workflows/docker-daily.yml +129 -0
  10. ofscraper_community-3.16.2/.github/workflows/docker-purge.yml +45 -0
  11. ofscraper_community-3.16.2/.github/workflows/package-delete.yml +24 -0
  12. ofscraper_community-3.16.2/.gitignore +71 -0
  13. ofscraper_community-3.16.2/AGENTS.md +78 -0
  14. ofscraper_community-3.16.2/CHANGES.md +36 -0
  15. ofscraper_community-3.16.2/CLAUDE.md +1 -0
  16. ofscraper_community-3.16.2/COLLISION_RECOVERY.md +62 -0
  17. ofscraper_community-3.16.2/CONTRIBUTING.md +22 -0
  18. ofscraper_community-3.16.2/Dockerfile +97 -0
  19. ofscraper_community-3.16.2/LICENSE +21 -0
  20. ofscraper_community-3.16.2/PKG-INFO +245 -0
  21. ofscraper_community-3.16.2/README.md +181 -0
  22. ofscraper_community-3.16.2/codecov.yml +16 -0
  23. ofscraper_community-3.16.2/cosign.pub +4 -0
  24. ofscraper_community-3.16.2/crypto +0 -0
  25. ofscraper_community-3.16.2/docker-compose.yml +53 -0
  26. ofscraper_community-3.16.2/donate/btc +1 -0
  27. ofscraper_community-3.16.2/donate/eth +1 -0
  28. ofscraper_community-3.16.2/gitbook-docs.yaml +12 -0
  29. ofscraper_community-3.16.2/media/browser_tools_open.png +0 -0
  30. ofscraper_community-3.16.2/media/dp.png +0 -0
  31. ofscraper_community-3.16.2/media/example.png +0 -0
  32. ofscraper_community-3.16.2/media/headers.png +0 -0
  33. ofscraper_community-3.16.2/media/icon.png +0 -0
  34. ofscraper_community-3.16.2/media/init.png +0 -0
  35. ofscraper_community-3.16.2/media/list_or_username.png +0 -0
  36. ofscraper_community-3.16.2/media/main_menu.png +0 -0
  37. ofscraper_community-3.16.2/media/network_tab.png +0 -0
  38. ofscraper_community-3.16.2/media/request_headers.png +0 -0
  39. ofscraper_community-3.16.2/media/xhr_tab.png +0 -0
  40. ofscraper_community-3.16.2/ofscraper/__main__.py +9 -0
  41. ofscraper_community-3.16.2/ofscraper/__version__.py +13 -0
  42. ofscraper_community-3.16.2/ofscraper/classes/labels.py +40 -0
  43. ofscraper_community-3.16.2/ofscraper/classes/of/base.py +54 -0
  44. ofscraper_community-3.16.2/ofscraper/classes/of/media.py +742 -0
  45. ofscraper_community-3.16.2/ofscraper/classes/of/models.py +230 -0
  46. ofscraper_community-3.16.2/ofscraper/classes/of/posts.py +347 -0
  47. ofscraper_community-3.16.2/ofscraper/classes/placeholder.py +556 -0
  48. ofscraper_community-3.16.2/ofscraper/classes/table/app.py +854 -0
  49. ofscraper_community-3.16.2/ofscraper/classes/table/compose.py +188 -0
  50. ofscraper_community-3.16.2/ofscraper/classes/table/const.py +1 -0
  51. ofscraper_community-3.16.2/ofscraper/classes/table/css.py +178 -0
  52. ofscraper_community-3.16.2/ofscraper/classes/table/fields/boolfield.py +36 -0
  53. ofscraper_community-3.16.2/ofscraper/classes/table/fields/datefield.py +94 -0
  54. ofscraper_community-3.16.2/ofscraper/classes/table/fields/downloadfield.py +65 -0
  55. ofscraper_community-3.16.2/ofscraper/classes/table/fields/mediafield.py +60 -0
  56. ofscraper_community-3.16.2/ofscraper/classes/table/fields/numfield.py +60 -0
  57. ofscraper_community-3.16.2/ofscraper/classes/table/fields/pricefield.py +47 -0
  58. ofscraper_community-3.16.2/ofscraper/classes/table/fields/responsefield.py +100 -0
  59. ofscraper_community-3.16.2/ofscraper/classes/table/fields/selectfield.py +69 -0
  60. ofscraper_community-3.16.2/ofscraper/classes/table/fields/sizefield.py +32 -0
  61. ofscraper_community-3.16.2/ofscraper/classes/table/fields/textsearch.py +45 -0
  62. ofscraper_community-3.16.2/ofscraper/classes/table/fields/timefield.py +129 -0
  63. ofscraper_community-3.16.2/ofscraper/classes/table/inputs/filterinput.py +16 -0
  64. ofscraper_community-3.16.2/ofscraper/classes/table/inputs/intergerinput.py +13 -0
  65. ofscraper_community-3.16.2/ofscraper/classes/table/inputs/strinput.py +10 -0
  66. ofscraper_community-3.16.2/ofscraper/classes/table/sections/sidebar.py +10 -0
  67. ofscraper_community-3.16.2/ofscraper/classes/table/sections/table.py +139 -0
  68. ofscraper_community-3.16.2/ofscraper/classes/table/sections/table_console.py +6 -0
  69. ofscraper_community-3.16.2/ofscraper/classes/table/utils/lock.py +2 -0
  70. ofscraper_community-3.16.2/ofscraper/classes/table/utils/names.py +30 -0
  71. ofscraper_community-3.16.2/ofscraper/commands/check.py +874 -0
  72. ofscraper_community-3.16.2/ofscraper/commands/db.py +370 -0
  73. ofscraper_community-3.16.2/ofscraper/commands/manual.py +322 -0
  74. ofscraper_community-3.16.2/ofscraper/commands/metadata/consumer.py +93 -0
  75. ofscraper_community-3.16.2/ofscraper/commands/metadata/desc.py +1 -0
  76. ofscraper_community-3.16.2/ofscraper/commands/metadata/manager.py +228 -0
  77. ofscraper_community-3.16.2/ofscraper/commands/metadata/metadata.py +295 -0
  78. ofscraper_community-3.16.2/ofscraper/commands/recover_collisions.py +156 -0
  79. ofscraper_community-3.16.2/ofscraper/commands/scraper/actions/download/download.py +147 -0
  80. ofscraper_community-3.16.2/ofscraper/commands/scraper/actions/download/managers/alt_download.py +580 -0
  81. ofscraper_community-3.16.2/ofscraper/commands/scraper/actions/download/managers/downloadmanager.py +283 -0
  82. ofscraper_community-3.16.2/ofscraper/commands/scraper/actions/download/managers/fansly_stream_download.py +311 -0
  83. ofscraper_community-3.16.2/ofscraper/commands/scraper/actions/download/managers/main_download.py +427 -0
  84. ofscraper_community-3.16.2/ofscraper/commands/scraper/actions/download/run.py +140 -0
  85. ofscraper_community-3.16.2/ofscraper/commands/scraper/actions/download/utils/chunk.py +29 -0
  86. ofscraper_community-3.16.2/ofscraper/commands/scraper/actions/download/utils/desc.py +1 -0
  87. ofscraper_community-3.16.2/ofscraper/commands/scraper/actions/download/utils/keyhelpers.py +242 -0
  88. ofscraper_community-3.16.2/ofscraper/commands/scraper/actions/download/utils/leaky.py +20 -0
  89. ofscraper_community-3.16.2/ofscraper/commands/scraper/actions/download/utils/retries.py +40 -0
  90. ofscraper_community-3.16.2/ofscraper/commands/scraper/actions/download/utils/text.py +32 -0
  91. ofscraper_community-3.16.2/ofscraper/commands/scraper/actions/like/like.py +180 -0
  92. ofscraper_community-3.16.2/ofscraper/commands/scraper/actions/utils/buffer.py +0 -0
  93. ofscraper_community-3.16.2/ofscraper/commands/scraper/actions/utils/chunk.py +14 -0
  94. ofscraper_community-3.16.2/ofscraper/commands/scraper/actions/utils/general.py +51 -0
  95. ofscraper_community-3.16.2/ofscraper/commands/scraper/actions/utils/globals.py +80 -0
  96. ofscraper_community-3.16.2/ofscraper/commands/scraper/actions/utils/log.py +64 -0
  97. ofscraper_community-3.16.2/ofscraper/commands/scraper/actions/utils/params.py +14 -0
  98. ofscraper_community-3.16.2/ofscraper/commands/scraper/actions/utils/paths.py +252 -0
  99. ofscraper_community-3.16.2/ofscraper/commands/scraper/actions/utils/progress/convert.py +14 -0
  100. ofscraper_community-3.16.2/ofscraper/commands/scraper/actions/utils/progress/update.py +6 -0
  101. ofscraper_community-3.16.2/ofscraper/commands/scraper/actions/utils/retries.py +31 -0
  102. ofscraper_community-3.16.2/ofscraper/commands/scraper/actions/utils/threads.py +52 -0
  103. ofscraper_community-3.16.2/ofscraper/commands/scraper/actions/utils/workers.py +8 -0
  104. ofscraper_community-3.16.2/ofscraper/commands/scraper/scraper.py +326 -0
  105. ofscraper_community-3.16.2/ofscraper/commands/scraper/utils/daemon.py +0 -0
  106. ofscraper_community-3.16.2/ofscraper/commands/scraper/utils/jobqueue.py +2 -0
  107. ofscraper_community-3.16.2/ofscraper/commands/scraper/utils/prepare.py +59 -0
  108. ofscraper_community-3.16.2/ofscraper/commands/scraper/utils/print.py +4 -0
  109. ofscraper_community-3.16.2/ofscraper/commands/scraper/utils/schedule.py +86 -0
  110. ofscraper_community-3.16.2/ofscraper/commands/utils/command.py +142 -0
  111. ofscraper_community-3.16.2/ofscraper/commands/utils/scrape_context.py +42 -0
  112. ofscraper_community-3.16.2/ofscraper/commands/utils/strings.py +25 -0
  113. ofscraper_community-3.16.2/ofscraper/data/api/archive.py +362 -0
  114. ofscraper_community-3.16.2/ofscraper/data/api/common/after.py +26 -0
  115. ofscraper_community-3.16.2/ofscraper/data/api/common/cache/read.py +20 -0
  116. ofscraper_community-3.16.2/ofscraper/data/api/common/cache/write.py +40 -0
  117. ofscraper_community-3.16.2/ofscraper/data/api/common/check.py +27 -0
  118. ofscraper_community-3.16.2/ofscraper/data/api/common/logs/logs.py +44 -0
  119. ofscraper_community-3.16.2/ofscraper/data/api/common/logs/strings.py +14 -0
  120. ofscraper_community-3.16.2/ofscraper/data/api/common/old.py +36 -0
  121. ofscraper_community-3.16.2/ofscraper/data/api/common/page.py +38 -0
  122. ofscraper_community-3.16.2/ofscraper/data/api/common/timeline.py +39 -0
  123. ofscraper_community-3.16.2/ofscraper/data/api/highlights.py +311 -0
  124. ofscraper_community-3.16.2/ofscraper/data/api/init.py +99 -0
  125. ofscraper_community-3.16.2/ofscraper/data/api/labels.py +464 -0
  126. ofscraper_community-3.16.2/ofscraper/data/api/me.py +82 -0
  127. ofscraper_community-3.16.2/ofscraper/data/api/messages.py +430 -0
  128. ofscraper_community-3.16.2/ofscraper/data/api/paid.py +318 -0
  129. ofscraper_community-3.16.2/ofscraper/data/api/pinned.py +149 -0
  130. ofscraper_community-3.16.2/ofscraper/data/api/profile.py +173 -0
  131. ofscraper_community-3.16.2/ofscraper/data/api/streams.py +355 -0
  132. ofscraper_community-3.16.2/ofscraper/data/api/subscriptions/common.py +48 -0
  133. ofscraper_community-3.16.2/ofscraper/data/api/subscriptions/individual.py +81 -0
  134. ofscraper_community-3.16.2/ofscraper/data/api/subscriptions/lists.py +272 -0
  135. ofscraper_community-3.16.2/ofscraper/data/api/subscriptions/subscriptions.py +237 -0
  136. ofscraper_community-3.16.2/ofscraper/data/api/tasks.py +67 -0
  137. ofscraper_community-3.16.2/ofscraper/data/api/timeline.py +411 -0
  138. ofscraper_community-3.16.2/ofscraper/data/models/utils/retriver.py +117 -0
  139. ofscraper_community-3.16.2/ofscraper/data/posts/post.py +660 -0
  140. ofscraper_community-3.16.2/ofscraper/data/posts/scrape_paid.py +141 -0
  141. ofscraper_community-3.16.2/ofscraper/db/__init__.py +1 -0
  142. ofscraper_community-3.16.2/ofscraper/db/backup.py +103 -0
  143. ofscraper_community-3.16.2/ofscraper/db/difference.py +37 -0
  144. ofscraper_community-3.16.2/ofscraper/db/merge.py +358 -0
  145. ofscraper_community-3.16.2/ofscraper/db/operations.py +105 -0
  146. ofscraper_community-3.16.2/ofscraper/db/operations_/empty.py +62 -0
  147. ofscraper_community-3.16.2/ofscraper/db/operations_/labels.py +253 -0
  148. ofscraper_community-3.16.2/ofscraper/db/operations_/media.py +801 -0
  149. ofscraper_community-3.16.2/ofscraper/db/operations_/messages.py +308 -0
  150. ofscraper_community-3.16.2/ofscraper/db/operations_/others.py +312 -0
  151. ofscraper_community-3.16.2/ofscraper/db/operations_/posts.py +456 -0
  152. ofscraper_community-3.16.2/ofscraper/db/operations_/profile.py +219 -0
  153. ofscraper_community-3.16.2/ofscraper/db/operations_/stories.py +227 -0
  154. ofscraper_community-3.16.2/ofscraper/db/operations_/wrapper.py +131 -0
  155. ofscraper_community-3.16.2/ofscraper/db/transition.py +280 -0
  156. ofscraper_community-3.16.2/ofscraper/db/utils/convert.py +7 -0
  157. ofscraper_community-3.16.2/ofscraper/db/utils/rebuild.py +55 -0
  158. ofscraper_community-3.16.2/ofscraper/filters/media/filters.py +352 -0
  159. ofscraper_community-3.16.2/ofscraper/filters/models/date.py +88 -0
  160. ofscraper_community-3.16.2/ofscraper/filters/models/flags.py +76 -0
  161. ofscraper_community-3.16.2/ofscraper/filters/models/other.py +35 -0
  162. ofscraper_community-3.16.2/ofscraper/filters/models/price.py +185 -0
  163. ofscraper_community-3.16.2/ofscraper/filters/models/sort.py +55 -0
  164. ofscraper_community-3.16.2/ofscraper/filters/models/subtype.py +31 -0
  165. ofscraper_community-3.16.2/ofscraper/filters/models/utils/logs.py +13 -0
  166. ofscraper_community-3.16.2/ofscraper/main/close/exit.py +34 -0
  167. ofscraper_community-3.16.2/ofscraper/main/close/final/final.py +23 -0
  168. ofscraper_community-3.16.2/ofscraper/main/close/final/final_log.py +43 -0
  169. ofscraper_community-3.16.2/ofscraper/main/open/load.py +62 -0
  170. ofscraper_community-3.16.2/ofscraper/main/open/run.py +32 -0
  171. ofscraper_community-3.16.2/ofscraper/managers/manager.py +135 -0
  172. ofscraper_community-3.16.2/ofscraper/managers/model.py +580 -0
  173. ofscraper_community-3.16.2/ofscraper/managers/postcollection.py +330 -0
  174. ofscraper_community-3.16.2/ofscraper/managers/profile.py +129 -0
  175. ofscraper_community-3.16.2/ofscraper/managers/sessionHandler.py +60 -0
  176. ofscraper_community-3.16.2/ofscraper/managers/sessionmanager/cert.py +152 -0
  177. ofscraper_community-3.16.2/ofscraper/managers/sessionmanager/ofsession.py +316 -0
  178. ofscraper_community-3.16.2/ofscraper/managers/sessionmanager/sessionmanager.py +772 -0
  179. ofscraper_community-3.16.2/ofscraper/managers/sessionmanager/sleepers.py +127 -0
  180. ofscraper_community-3.16.2/ofscraper/managers/stats.py +588 -0
  181. ofscraper_community-3.16.2/ofscraper/managers/utils/state.py +275 -0
  182. ofscraper_community-3.16.2/ofscraper/prompts/keybindings.py +38 -0
  183. ofscraper_community-3.16.2/ofscraper/prompts/promptConvert.py +272 -0
  184. ofscraper_community-3.16.2/ofscraper/prompts/prompt_groups/actions.py +41 -0
  185. ofscraper_community-3.16.2/ofscraper/prompts/prompt_groups/area.py +301 -0
  186. ofscraper_community-3.16.2/ofscraper/prompts/prompt_groups/auth.py +275 -0
  187. ofscraper_community-3.16.2/ofscraper/prompts/prompt_groups/config.py +854 -0
  188. ofscraper_community-3.16.2/ofscraper/prompts/prompt_groups/menu.py +46 -0
  189. ofscraper_community-3.16.2/ofscraper/prompts/prompt_groups/merge.py +129 -0
  190. ofscraper_community-3.16.2/ofscraper/prompts/prompt_groups/misc.py +18 -0
  191. ofscraper_community-3.16.2/ofscraper/prompts/prompt_groups/model.py +451 -0
  192. ofscraper_community-3.16.2/ofscraper/prompts/prompt_groups/profile.py +141 -0
  193. ofscraper_community-3.16.2/ofscraper/prompts/prompt_strings.py +273 -0
  194. ofscraper_community-3.16.2/ofscraper/prompts/prompt_validators.py +362 -0
  195. ofscraper_community-3.16.2/ofscraper/prompts/prompts.py +22 -0
  196. ofscraper_community-3.16.2/ofscraper/prompts/utils/model_helpers.py +85 -0
  197. ofscraper_community-3.16.2/ofscraper/prompts/utils/prompt_helpers.py +284 -0
  198. ofscraper_community-3.16.2/ofscraper/scripts/after_download_action_script.py +105 -0
  199. ofscraper_community-3.16.2/ofscraper/scripts/after_download_script.py +73 -0
  200. ofscraper_community-3.16.2/ofscraper/scripts/after_like_action_script.py +101 -0
  201. ofscraper_community-3.16.2/ofscraper/scripts/final_script.py +85 -0
  202. ofscraper_community-3.16.2/ofscraper/scripts/naming_script.py +101 -0
  203. ofscraper_community-3.16.2/ofscraper/scripts/skip_download_script.py +95 -0
  204. ofscraper_community-3.16.2/ofscraper/sites/__init__.py +88 -0
  205. ofscraper_community-3.16.2/ofscraper/sites/fansly/__init__.py +0 -0
  206. ofscraper_community-3.16.2/ofscraper/sites/fansly/api.py +208 -0
  207. ofscraper_community-3.16.2/ofscraper/sites/fansly/auth.py +200 -0
  208. ofscraper_community-3.16.2/ofscraper/sites/fansly/constants.py +27 -0
  209. ofscraper_community-3.16.2/ofscraper/sites/fansly/headers.py +58 -0
  210. ofscraper_community-3.16.2/ofscraper/sites/fansly/live.py +702 -0
  211. ofscraper_community-3.16.2/ofscraper/sites/fansly/live_api.py +73 -0
  212. ofscraper_community-3.16.2/ofscraper/sites/fansly/live_chat.py +174 -0
  213. ofscraper_community-3.16.2/ofscraper/sites/fansly/me.py +73 -0
  214. ofscraper_community-3.16.2/ofscraper/sites/fansly/normalize.py +355 -0
  215. ofscraper_community-3.16.2/ofscraper/sites/fansly/scrape.py +83 -0
  216. ofscraper_community-3.16.2/ofscraper/sites/fansly/signing.py +60 -0
  217. ofscraper_community-3.16.2/ofscraper/sites/fansly/video.py +346 -0
  218. ofscraper_community-3.16.2/ofscraper/utils/__init__.py +1 -0
  219. ofscraper_community-3.16.2/ofscraper/utils/actions.py +129 -0
  220. ofscraper_community-3.16.2/ofscraper/utils/ads.py +2 -0
  221. ofscraper_community-3.16.2/ofscraper/utils/args/accessors/actions.py +0 -0
  222. ofscraper_community-3.16.2/ofscraper/utils/args/accessors/areas.py +72 -0
  223. ofscraper_community-3.16.2/ofscraper/utils/args/accessors/output.py +9 -0
  224. ofscraper_community-3.16.2/ofscraper/utils/args/accessors/quality.py +22 -0
  225. ofscraper_community-3.16.2/ofscraper/utils/args/accessors/read.py +18 -0
  226. ofscraper_community-3.16.2/ofscraper/utils/args/accessors/time.py +53 -0
  227. ofscraper_community-3.16.2/ofscraper/utils/args/callbacks/arguments/post.py +6 -0
  228. ofscraper_community-3.16.2/ofscraper/utils/args/callbacks/arguments/username.py +9 -0
  229. ofscraper_community-3.16.2/ofscraper/utils/args/callbacks/parse/choice.py +14 -0
  230. ofscraper_community-3.16.2/ofscraper/utils/args/callbacks/parse/file.py +22 -0
  231. ofscraper_community-3.16.2/ofscraper/utils/args/callbacks/parse/string.py +38 -0
  232. ofscraper_community-3.16.2/ofscraper/utils/args/callbacks/parse/username.py +6 -0
  233. ofscraper_community-3.16.2/ofscraper/utils/args/globals.py +1 -0
  234. ofscraper_community-3.16.2/ofscraper/utils/args/helpers/hide_args.py +15 -0
  235. ofscraper_community-3.16.2/ofscraper/utils/args/main.py +70 -0
  236. ofscraper_community-3.16.2/ofscraper/utils/args/mutators/before.py +11 -0
  237. ofscraper_community-3.16.2/ofscraper/utils/args/mutators/user.py +29 -0
  238. ofscraper_community-3.16.2/ofscraper/utils/args/mutators/write.py +10 -0
  239. ofscraper_community-3.16.2/ofscraper/utils/args/parse/arguments/advanced_processing.py +33 -0
  240. ofscraper_community-3.16.2/ofscraper/utils/args/parse/arguments/advanced_program.py +73 -0
  241. ofscraper_community-3.16.2/ofscraper/utils/args/parse/arguments/advanced_user_filter.py +129 -0
  242. ofscraper_community-3.16.2/ofscraper/utils/args/parse/arguments/automatic.py +68 -0
  243. ofscraper_community-3.16.2/ofscraper/utils/args/parse/arguments/check.py +133 -0
  244. ofscraper_community-3.16.2/ofscraper/utils/args/parse/arguments/download.py +48 -0
  245. ofscraper_community-3.16.2/ofscraper/utils/args/parse/arguments/file.py +25 -0
  246. ofscraper_community-3.16.2/ofscraper/utils/args/parse/arguments/logging.py +50 -0
  247. ofscraper_community-3.16.2/ofscraper/utils/args/parse/arguments/media_content.py +166 -0
  248. ofscraper_community-3.16.2/ofscraper/utils/args/parse/arguments/metadata_filters.py +90 -0
  249. ofscraper_community-3.16.2/ofscraper/utils/args/parse/arguments/post_content.py +346 -0
  250. ofscraper_community-3.16.2/ofscraper/utils/args/parse/arguments/program.py +48 -0
  251. ofscraper_community-3.16.2/ofscraper/utils/args/parse/arguments/scripts.py +53 -0
  252. ofscraper_community-3.16.2/ofscraper/utils/args/parse/arguments/shared.py +1 -0
  253. ofscraper_community-3.16.2/ofscraper/utils/args/parse/arguments/user_list.py +120 -0
  254. ofscraper_community-3.16.2/ofscraper/utils/args/parse/arguments/user_select.py +81 -0
  255. ofscraper_community-3.16.2/ofscraper/utils/args/parse/arguments/user_sort.py +30 -0
  256. ofscraper_community-3.16.2/ofscraper/utils/args/parse/arguments/utils/date.py +13 -0
  257. ofscraper_community-3.16.2/ofscraper/utils/args/parse/arguments/utils/retry.py +22 -0
  258. ofscraper_community-3.16.2/ofscraper/utils/args/parse/commands/db.py +13 -0
  259. ofscraper_community-3.16.2/ofscraper/utils/args/parse/commands/main.py +19 -0
  260. ofscraper_community-3.16.2/ofscraper/utils/args/parse/commands/manual.py +9 -0
  261. ofscraper_community-3.16.2/ofscraper/utils/args/parse/commands/message.py +9 -0
  262. ofscraper_community-3.16.2/ofscraper/utils/args/parse/commands/metadata.py +11 -0
  263. ofscraper_community-3.16.2/ofscraper/utils/args/parse/commands/paid.py +9 -0
  264. ofscraper_community-3.16.2/ofscraper/utils/args/parse/commands/post.py +10 -0
  265. ofscraper_community-3.16.2/ofscraper/utils/args/parse/commands/story.py +9 -0
  266. ofscraper_community-3.16.2/ofscraper/utils/args/parse/group_bundles/advanced_common.py +17 -0
  267. ofscraper_community-3.16.2/ofscraper/utils/args/parse/group_bundles/check.py +89 -0
  268. ofscraper_community-3.16.2/ofscraper/utils/args/parse/group_bundles/common.py +23 -0
  269. ofscraper_community-3.16.2/ofscraper/utils/args/parse/group_bundles/db.py +111 -0
  270. ofscraper_community-3.16.2/ofscraper/utils/args/parse/group_bundles/main.py +35 -0
  271. ofscraper_community-3.16.2/ofscraper/utils/args/parse/group_bundles/manual.py +26 -0
  272. ofscraper_community-3.16.2/ofscraper/utils/args/parse/group_bundles/message_check.py +33 -0
  273. ofscraper_community-3.16.2/ofscraper/utils/args/parse/group_bundles/metadata.py +155 -0
  274. ofscraper_community-3.16.2/ofscraper/utils/args/parse/group_bundles/paid_check.py +32 -0
  275. ofscraper_community-3.16.2/ofscraper/utils/args/parse/group_bundles/post_check.py +33 -0
  276. ofscraper_community-3.16.2/ofscraper/utils/args/parse/group_bundles/story_check.py +35 -0
  277. ofscraper_community-3.16.2/ofscraper/utils/args/parse/group_bundles/utils/check.py +16 -0
  278. ofscraper_community-3.16.2/ofscraper/utils/args/parse/groups/advanced_processing.py +17 -0
  279. ofscraper_community-3.16.2/ofscraper/utils/args/parse/groups/advanced_program.py +29 -0
  280. ofscraper_community-3.16.2/ofscraper/utils/args/parse/groups/advanced_user_filter.py +43 -0
  281. ofscraper_community-3.16.2/ofscraper/utils/args/parse/groups/automatic.py +31 -0
  282. ofscraper_community-3.16.2/ofscraper/utils/args/parse/groups/check_content.py +28 -0
  283. ofscraper_community-3.16.2/ofscraper/utils/args/parse/groups/download.py +22 -0
  284. ofscraper_community-3.16.2/ofscraper/utils/args/parse/groups/file.py +26 -0
  285. ofscraper_community-3.16.2/ofscraper/utils/args/parse/groups/logging.py +24 -0
  286. ofscraper_community-3.16.2/ofscraper/utils/args/parse/groups/media_filter.py +47 -0
  287. ofscraper_community-3.16.2/ofscraper/utils/args/parse/groups/post_filter.py +49 -0
  288. ofscraper_community-3.16.2/ofscraper/utils/args/parse/groups/program.py +25 -0
  289. ofscraper_community-3.16.2/ofscraper/utils/args/parse/groups/scripts.py +23 -0
  290. ofscraper_community-3.16.2/ofscraper/utils/args/parse/groups/user_list.py +35 -0
  291. ofscraper_community-3.16.2/ofscraper/utils/args/parse/groups/user_select.py +26 -0
  292. ofscraper_community-3.16.2/ofscraper/utils/args/parse/groups/user_sort.py +16 -0
  293. ofscraper_community-3.16.2/ofscraper/utils/args/types/arrow.py +49 -0
  294. ofscraper_community-3.16.2/ofscraper/utils/args/types/choice.py +139 -0
  295. ofscraper_community-3.16.2/ofscraper/utils/async_cached_property.py +66 -0
  296. ofscraper_community-3.16.2/ofscraper/utils/auth/data.py +67 -0
  297. ofscraper_community-3.16.2/ofscraper/utils/auth/file.py +113 -0
  298. ofscraper_community-3.16.2/ofscraper/utils/auth/make.py +59 -0
  299. ofscraper_community-3.16.2/ofscraper/utils/auth/request.py +370 -0
  300. ofscraper_community-3.16.2/ofscraper/utils/auth/schema.py +34 -0
  301. ofscraper_community-3.16.2/ofscraper/utils/auth/utils/dict.py +43 -0
  302. ofscraper_community-3.16.2/ofscraper/utils/auth/utils/error.py +77 -0
  303. ofscraper_community-3.16.2/ofscraper/utils/auth/utils/prompt.py +42 -0
  304. ofscraper_community-3.16.2/ofscraper/utils/auth/utils/warning/check.py +7 -0
  305. ofscraper_community-3.16.2/ofscraper/utils/auth/utils/warning/print.py +39 -0
  306. ofscraper_community-3.16.2/ofscraper/utils/auth/utils/warning/warning.py +14 -0
  307. ofscraper_community-3.16.2/ofscraper/utils/cache/cache.py +82 -0
  308. ofscraper_community-3.16.2/ofscraper/utils/cache/profile.py +32 -0
  309. ofscraper_community-3.16.2/ofscraper/utils/checkers.py +46 -0
  310. ofscraper_community-3.16.2/ofscraper/utils/config/config.py +61 -0
  311. ofscraper_community-3.16.2/ofscraper/utils/config/data.py +738 -0
  312. ofscraper_community-3.16.2/ofscraper/utils/config/file.py +86 -0
  313. ofscraper_community-3.16.2/ofscraper/utils/config/menu.py +89 -0
  314. ofscraper_community-3.16.2/ofscraper/utils/config/schema.py +124 -0
  315. ofscraper_community-3.16.2/ofscraper/utils/config/utils/context.py +43 -0
  316. ofscraper_community-3.16.2/ofscraper/utils/config/utils/wrapper.py +16 -0
  317. ofscraper_community-3.16.2/ofscraper/utils/console.py +88 -0
  318. ofscraper_community-3.16.2/ofscraper/utils/const.py +34 -0
  319. ofscraper_community-3.16.2/ofscraper/utils/context/exit.py +113 -0
  320. ofscraper_community-3.16.2/ofscraper/utils/context/run_async.py +73 -0
  321. ofscraper_community-3.16.2/ofscraper/utils/context/stdout.py +30 -0
  322. ofscraper_community-3.16.2/ofscraper/utils/dates.py +107 -0
  323. ofscraper_community-3.16.2/ofscraper/utils/encoding.py +18 -0
  324. ofscraper_community-3.16.2/ofscraper/utils/hash.py +58 -0
  325. ofscraper_community-3.16.2/ofscraper/utils/live/classes/progress.py +109 -0
  326. ofscraper_community-3.16.2/ofscraper/utils/live/classes/task.py +53 -0
  327. ofscraper_community-3.16.2/ofscraper/utils/live/classes/transfercol.py +41 -0
  328. ofscraper_community-3.16.2/ofscraper/utils/live/clear.py +109 -0
  329. ofscraper_community-3.16.2/ofscraper/utils/live/empty.py +21 -0
  330. ofscraper_community-3.16.2/ofscraper/utils/live/groups.py +86 -0
  331. ofscraper_community-3.16.2/ofscraper/utils/live/live.py +39 -0
  332. ofscraper_community-3.16.2/ofscraper/utils/live/panel.py +5 -0
  333. ofscraper_community-3.16.2/ofscraper/utils/live/progress.py +106 -0
  334. ofscraper_community-3.16.2/ofscraper/utils/live/screens.py +284 -0
  335. ofscraper_community-3.16.2/ofscraper/utils/live/tasks.py +47 -0
  336. ofscraper_community-3.16.2/ofscraper/utils/live/updater.py +109 -0
  337. ofscraper_community-3.16.2/ofscraper/utils/logs/classes/classes.py +132 -0
  338. ofscraper_community-3.16.2/ofscraper/utils/logs/classes/handlers/discord.py +133 -0
  339. ofscraper_community-3.16.2/ofscraper/utils/logs/classes/handlers/text.py +23 -0
  340. ofscraper_community-3.16.2/ofscraper/utils/logs/close.py +32 -0
  341. ofscraper_community-3.16.2/ofscraper/utils/logs/logger.py +49 -0
  342. ofscraper_community-3.16.2/ofscraper/utils/logs/logs.py +132 -0
  343. ofscraper_community-3.16.2/ofscraper/utils/logs/other.py +56 -0
  344. ofscraper_community-3.16.2/ofscraper/utils/logs/stdout.py +51 -0
  345. ofscraper_community-3.16.2/ofscraper/utils/logs/utils/level.py +68 -0
  346. ofscraper_community-3.16.2/ofscraper/utils/logs/utils/sensitive.py +62 -0
  347. ofscraper_community-3.16.2/ofscraper/utils/logs/utils/trace.py +9 -0
  348. ofscraper_community-3.16.2/ofscraper/utils/markup.py +14 -0
  349. ofscraper_community-3.16.2/ofscraper/utils/me.py +25 -0
  350. ofscraper_community-3.16.2/ofscraper/utils/menu.py +140 -0
  351. ofscraper_community-3.16.2/ofscraper/utils/merge.py +44 -0
  352. ofscraper_community-3.16.2/ofscraper/utils/of_env/__init__.py +124 -0
  353. ofscraper_community-3.16.2/ofscraper/utils/of_env/load.py +97 -0
  354. ofscraper_community-3.16.2/ofscraper/utils/of_env/of_env.py +98 -0
  355. ofscraper_community-3.16.2/ofscraper/utils/of_env/values/action/download.py +126 -0
  356. ofscraper_community-3.16.2/ofscraper/utils/of_env/values/action/like.py +36 -0
  357. ofscraper_community-3.16.2/ofscraper/utils/of_env/values/action/metadata.py +31 -0
  358. ofscraper_community-3.16.2/ofscraper/utils/of_env/values/date.py +22 -0
  359. ofscraper_community-3.16.2/ofscraper/utils/of_env/values/dynamic.py +49 -0
  360. ofscraper_community-3.16.2/ofscraper/utils/of_env/values/general.py +122 -0
  361. ofscraper_community-3.16.2/ofscraper/utils/of_env/values/list.py +50 -0
  362. ofscraper_community-3.16.2/ofscraper/utils/of_env/values/live.py +56 -0
  363. ofscraper_community-3.16.2/ofscraper/utils/of_env/values/logger.py +30 -0
  364. ofscraper_community-3.16.2/ofscraper/utils/of_env/values/main.py +344 -0
  365. ofscraper_community-3.16.2/ofscraper/utils/of_env/values/path/bytes.py +38 -0
  366. ofscraper_community-3.16.2/ofscraper/utils/of_env/values/path/files.py +44 -0
  367. ofscraper_community-3.16.2/ofscraper/utils/of_env/values/path/general.py +34 -0
  368. ofscraper_community-3.16.2/ofscraper/utils/of_env/values/path/length.py +38 -0
  369. ofscraper_community-3.16.2/ofscraper/utils/of_env/values/prompts.py +87 -0
  370. ofscraper_community-3.16.2/ofscraper/utils/of_env/values/req/anon.py +21 -0
  371. ofscraper_community-3.16.2/ofscraper/utils/of_env/values/req/api.py +110 -0
  372. ofscraper_community-3.16.2/ofscraper/utils/of_env/values/req/auth.py +10 -0
  373. ofscraper_community-3.16.2/ofscraper/utils/of_env/values/req/cdm.py +42 -0
  374. ofscraper_community-3.16.2/ofscraper/utils/of_env/values/req/discord.py +42 -0
  375. ofscraper_community-3.16.2/ofscraper/utils/of_env/values/req/git.py +26 -0
  376. ofscraper_community-3.16.2/ofscraper/utils/of_env/values/req/mpd.py +57 -0
  377. ofscraper_community-3.16.2/ofscraper/utils/of_env/values/req/ratelimit.py +329 -0
  378. ofscraper_community-3.16.2/ofscraper/utils/of_env/values/req/req.py +209 -0
  379. ofscraper_community-3.16.2/ofscraper/utils/of_env/values/system.py +53 -0
  380. ofscraper_community-3.16.2/ofscraper/utils/of_env/values/test/test_constants.py +7355 -0
  381. ofscraper_community-3.16.2/ofscraper/utils/of_env/values/time.py +71 -0
  382. ofscraper_community-3.16.2/ofscraper/utils/of_env/values/url/dynamic.py +61 -0
  383. ofscraper_community-3.16.2/ofscraper/utils/of_env/values/url/other_url.py +33 -0
  384. ofscraper_community-3.16.2/ofscraper/utils/of_env/values/url/url.py +254 -0
  385. ofscraper_community-3.16.2/ofscraper/utils/paths/common.py +131 -0
  386. ofscraper_community-3.16.2/ofscraper/utils/paths/db.py +18 -0
  387. ofscraper_community-3.16.2/ofscraper/utils/paths/manage.py +89 -0
  388. ofscraper_community-3.16.2/ofscraper/utils/paths/paths.py +217 -0
  389. ofscraper_community-3.16.2/ofscraper/utils/profiles/data.py +50 -0
  390. ofscraper_community-3.16.2/ofscraper/utils/profiles/manage.py +77 -0
  391. ofscraper_community-3.16.2/ofscraper/utils/profiles/tools.py +49 -0
  392. ofscraper_community-3.16.2/ofscraper/utils/sems.py +1 -0
  393. ofscraper_community-3.16.2/ofscraper/utils/separate.py +36 -0
  394. ofscraper_community-3.16.2/ofscraper/utils/settings.py +257 -0
  395. ofscraper_community-3.16.2/ofscraper/utils/string.py +62 -0
  396. ofscraper_community-3.16.2/ofscraper/utils/system/ffmpeg.py +180 -0
  397. ofscraper_community-3.16.2/ofscraper/utils/system/ffprobe.py +124 -0
  398. ofscraper_community-3.16.2/ofscraper/utils/system/free.py +25 -0
  399. ofscraper_community-3.16.2/ofscraper/utils/system/network.py +71 -0
  400. ofscraper_community-3.16.2/ofscraper/utils/system/priority.py +19 -0
  401. ofscraper_community-3.16.2/ofscraper/utils/system/speed.py +51 -0
  402. ofscraper_community-3.16.2/ofscraper/utils/system/subprocess.py +195 -0
  403. ofscraper_community-3.16.2/ofscraper/utils/system/system.py +62 -0
  404. ofscraper_community-3.16.2/ofscraper/utils/text.py +69 -0
  405. ofscraper_community-3.16.2/plugins.py +59 -0
  406. ofscraper_community-3.16.2/pyproject.toml +94 -0
  407. ofscraper_community-3.16.2/reference/README.md +103 -0
  408. ofscraper_community-3.16.2/reference/cli.md +1177 -0
  409. ofscraper_community-3.16.2/reference/config.md +423 -0
  410. ofscraper_community-3.16.2/reference/database.md +275 -0
  411. ofscraper_community-3.16.2/reference/env.md +860 -0
  412. ofscraper_community-3.16.2/reference/placeholders.md +51 -0
  413. ofscraper_community-3.16.2/scripts/commit_version.sh +146 -0
  414. ofscraper_community-3.16.2/scripts/creator_names.py +173 -0
  415. ofscraper_community-3.16.2/scripts/determine_docker_stable_dev_tags.py +205 -0
  416. ofscraper_community-3.16.2/scripts/entry/entrypoint.sh +70 -0
  417. ofscraper_community-3.16.2/scripts/entry/lib_paths.sh +37 -0
  418. ofscraper_community-3.16.2/scripts/entry/lib_permissions.sh +49 -0
  419. ofscraper_community-3.16.2/scripts/entry/lib_user_setup.sh +169 -0
  420. ofscraper_community-3.16.2/scripts/reference/build_reference.py +939 -0
  421. ofscraper_community-3.16.2/scripts/reference/notes.py +466 -0
  422. ofscraper_community-3.16.2/scripts/retry_action.sh +31 -0
  423. ofscraper_community-3.16.2/specs/onedir.spec +56 -0
  424. ofscraper_community-3.16.2/specs/onefile.spec +57 -0
  425. ofscraper_community-3.16.2/test/conftest.py +9 -0
  426. ofscraper_community-3.16.2/test/daemon_signal_probe.py +73 -0
  427. ofscraper_community-3.16.2/test/fixtures/fansly/account.json +272 -0
  428. ofscraper_community-3.16.2/test/fixtures/fansly/groups.json +178 -0
  429. ofscraper_community-3.16.2/test/fixtures/fansly/media_playlist.m3u8 +13 -0
  430. ofscraper_community-3.16.2/test/fixtures/fansly/messages.json +2041 -0
  431. ofscraper_community-3.16.2/test/fixtures/fansly/messages_missing_media.json +137 -0
  432. ofscraper_community-3.16.2/test/fixtures/fansly/timeline.json +1590 -0
  433. ofscraper_community-3.16.2/test/fixtures/fansly/timeline_missing_media.json +1163 -0
  434. ofscraper_community-3.16.2/test/fixtures/fansly/video_4k_account_media.json +151 -0
  435. ofscraper_community-3.16.2/test/legacy/README.md +8 -0
  436. ofscraper_community-3.16.2/test/legacy/calls/example.py +7 -0
  437. ofscraper_community-3.16.2/test/legacy/calls/utils_test.py +56 -0
  438. ofscraper_community-3.16.2/test/legacy/db/archive_test.py +78 -0
  439. ofscraper_community-3.16.2/test/legacy/db/highlights_test.py +74 -0
  440. ofscraper_community-3.16.2/test/legacy/db/media_test.py +82 -0
  441. ofscraper_community-3.16.2/test/legacy/db/message_test.py +73 -0
  442. ofscraper_community-3.16.2/test/legacy/db/pinned_test.py +78 -0
  443. ofscraper_community-3.16.2/test/legacy/db/post_test.py +77 -0
  444. ofscraper_community-3.16.2/test/legacy/db/profile_test.py +73 -0
  445. ofscraper_community-3.16.2/test/legacy/db/stories_test.py +64 -0
  446. ofscraper_community-3.16.2/test/legacy/general/auth_test.py +0 -0
  447. ofscraper_community-3.16.2/test/legacy/general/config_test.py +337 -0
  448. ofscraper_community-3.16.2/test/legacy/general/filter_test.py +112 -0
  449. ofscraper_community-3.16.2/test/legacy/general/like_test.py +64 -0
  450. ofscraper_community-3.16.2/test/legacy/general/misc_test.py +43 -0
  451. ofscraper_community-3.16.2/test/legacy/general/path_test.py +640 -0
  452. ofscraper_community-3.16.2/test/legacy/general/profile_folder_test.py +184 -0
  453. ofscraper_community-3.16.2/test/legacy/general/profile_scrape_test.py +57 -0
  454. ofscraper_community-3.16.2/test/legacy/general/validator_test.py +254 -0
  455. ofscraper_community-3.16.2/test/legacy/post/archived_post_test.py +598 -0
  456. ofscraper_community-3.16.2/test/legacy/post/highlight_post_test.py +595 -0
  457. ofscraper_community-3.16.2/test/legacy/post/messages_post_test.py +597 -0
  458. ofscraper_community-3.16.2/test/legacy/post/paid_post_test.py +596 -0
  459. ofscraper_community-3.16.2/test/legacy/post/pinned_post_test.py +598 -0
  460. ofscraper_community-3.16.2/test/legacy/post/stories_post_test.py +610 -0
  461. ofscraper_community-3.16.2/test/legacy/post/timeline_post_test.py +598 -0
  462. ofscraper_community-3.16.2/test/test_403_backoff.py +83 -0
  463. ofscraper_community-3.16.2/test/test_area_prompt.py +39 -0
  464. ofscraper_community-3.16.2/test/test_arrow_type.py +37 -0
  465. ofscraper_community-3.16.2/test/test_async_cached_property.py +62 -0
  466. ofscraper_community-3.16.2/test/test_auth_check_broken_rule.py +87 -0
  467. ofscraper_community-3.16.2/test/test_auth_check_logged_out.py +66 -0
  468. ofscraper_community-3.16.2/test/test_auth_check_network.py +170 -0
  469. ofscraper_community-3.16.2/test/test_auth_check_rule_fetch.py +51 -0
  470. ofscraper_community-3.16.2/test/test_auth_prompt_choice.py +52 -0
  471. ofscraper_community-3.16.2/test/test_backoff_decay_ends.py +89 -0
  472. ofscraper_community-3.16.2/test/test_batch_tempfile_cleanup_env.py +20 -0
  473. ofscraper_community-3.16.2/test/test_cdrm.py +88 -0
  474. ofscraper_community-3.16.2/test/test_check_commands.py +124 -0
  475. ofscraper_community-3.16.2/test/test_cli_options_201.py +81 -0
  476. ofscraper_community-3.16.2/test/test_cli_usage_errors.py +26 -0
  477. ofscraper_community-3.16.2/test/test_collision_recovery.py +196 -0
  478. ofscraper_community-3.16.2/test/test_config_paths.py +70 -0
  479. ofscraper_community-3.16.2/test/test_config_settings_200.py +209 -0
  480. ofscraper_community-3.16.2/test/test_console_outside_text.py +157 -0
  481. ofscraper_community-3.16.2/test/test_creator_names.py +148 -0
  482. ofscraper_community-3.16.2/test/test_daemon_shutdown.py +95 -0
  483. ofscraper_community-3.16.2/test/test_daemon_wakeup.py +160 -0
  484. ofscraper_community-3.16.2/test/test_db_export.py +44 -0
  485. ofscraper_community-3.16.2/test/test_db_writes.py +384 -0
  486. ofscraper_community-3.16.2/test/test_dir_bookkeeping.py +82 -0
  487. ofscraper_community-3.16.2/test/test_download_args.py +35 -0
  488. ofscraper_community-3.16.2/test/test_download_empty_reply.py +172 -0
  489. ofscraper_community-3.16.2/test/test_download_error_status.py +213 -0
  490. ofscraper_community-3.16.2/test/test_download_limit.py +99 -0
  491. ofscraper_community-3.16.2/test/test_download_limit_help.py +19 -0
  492. ofscraper_community-3.16.2/test/test_download_resume.py +599 -0
  493. ofscraper_community-3.16.2/test/test_download_retry_cancel.py +54 -0
  494. ofscraper_community-3.16.2/test/test_download_retry_keeps_part.py +177 -0
  495. ofscraper_community-3.16.2/test/test_download_session_zero_args.py +148 -0
  496. ofscraper_community-3.16.2/test/test_download_unknown_size.py +330 -0
  497. ofscraper_community-3.16.2/test/test_drm_alt_download.py +85 -0
  498. ofscraper_community-3.16.2/test/test_drm_decrypt_output.py +80 -0
  499. ofscraper_community-3.16.2/test/test_drm_license_url.py +30 -0
  500. ofscraper_community-3.16.2/test/test_dynamic_rule_names_226.py +134 -0
  501. ofscraper_community-3.16.2/test/test_dynamic_rules_option_232.py +36 -0
  502. ofscraper_community-3.16.2/test/test_env_and_helpers.py +107 -0
  503. ofscraper_community-3.16.2/test/test_env_files.py +155 -0
  504. ofscraper_community-3.16.2/test/test_fansly_api.py +561 -0
  505. ofscraper_community-3.16.2/test/test_fansly_auth_safety.py +116 -0
  506. ofscraper_community-3.16.2/test/test_fansly_live.py +1059 -0
  507. ofscraper_community-3.16.2/test/test_fansly_site.py +272 -0
  508. ofscraper_community-3.16.2/test/test_fansly_video.py +906 -0
  509. ofscraper_community-3.16.2/test/test_ffmpeg_version.py +30 -0
  510. ofscraper_community-3.16.2/test/test_filename_collisions.py +485 -0
  511. ofscraper_community-3.16.2/test/test_httpx_cookies.py +26 -0
  512. ofscraper_community-3.16.2/test/test_import_no_argv.py +90 -0
  513. ofscraper_community-3.16.2/test/test_integrity_no_duration.py +36 -0
  514. ofscraper_community-3.16.2/test/test_labels_incremental.py +356 -0
  515. ofscraper_community-3.16.2/test/test_like_bad_response.py +40 -0
  516. ofscraper_community-3.16.2/test/test_like_restore.py +80 -0
  517. ofscraper_community-3.16.2/test/test_log_stray_markup.py +77 -0
  518. ofscraper_community-3.16.2/test/test_manual_dynamic_rule.py +77 -0
  519. ofscraper_community-3.16.2/test/test_messages_pagination.py +132 -0
  520. ofscraper_community-3.16.2/test/test_metadata_hash.py +50 -0
  521. ofscraper_community-3.16.2/test/test_metadata_mark_stray_236.py +25 -0
  522. ofscraper_community-3.16.2/test/test_model_active.py +45 -0
  523. ofscraper_community-3.16.2/test/test_model_selector.py +59 -0
  524. ofscraper_community-3.16.2/test/test_my_id_placeholder.py +37 -0
  525. ofscraper_community-3.16.2/test/test_new_config_env_225.py +54 -0
  526. ofscraper_community-3.16.2/test/test_of_env_bare_key_types.py +60 -0
  527. ofscraper_community-3.16.2/test/test_of_env_getattr.py +20 -0
  528. ofscraper_community-3.16.2/test/test_old_posts.py +38 -0
  529. ofscraper_community-3.16.2/test/test_output_level_quiet.py +66 -0
  530. ofscraper_community-3.16.2/test/test_output_quiet_messages.py +198 -0
  531. ofscraper_community-3.16.2/test/test_paid_placeholder_models.py +34 -0
  532. ofscraper_community-3.16.2/test/test_paid_scan_warnings.py +114 -0
  533. ofscraper_community-3.16.2/test/test_previous_download_filter.py +61 -0
  534. ofscraper_community-3.16.2/test/test_profile_deleted_model.py +41 -0
  535. ofscraper_community-3.16.2/test/test_profile_info_after_failure.py +38 -0
  536. ofscraper_community-3.16.2/test/test_reference.py +149 -0
  537. ofscraper_community-3.16.2/test/test_resource_cleanup.py +44 -0
  538. ofscraper_community-3.16.2/test/test_run_exit_status.py +31 -0
  539. ofscraper_community-3.16.2/test/test_scrape_paid_excluded_username.py +160 -0
  540. ofscraper_community-3.16.2/test/test_scrape_paid_workers.py +47 -0
  541. ofscraper_community-3.16.2/test/test_sess_cookie_masked.py +246 -0
  542. ofscraper_community-3.16.2/test/test_session_cancel.py +162 -0
  543. ofscraper_community-3.16.2/test/test_session_read_timeout.py +221 -0
  544. ofscraper_community-3.16.2/test/test_session_request_retry_args.py +154 -0
  545. ofscraper_community-3.16.2/test/test_session_sleep.py +43 -0
  546. ofscraper_community-3.16.2/test/test_session_stream_cleanup.py +137 -0
  547. ofscraper_community-3.16.2/test/test_session_sync_connect_timeout.py +88 -0
  548. ofscraper_community-3.16.2/test/test_signals.py +53 -0
  549. ofscraper_community-3.16.2/test/test_site_onlyfans_db_paths_pin.py +323 -0
  550. ofscraper_community-3.16.2/test/test_site_onlyfans_pin.py +142 -0
  551. ofscraper_community-3.16.2/test/test_sleeper_settings.py +68 -0
  552. ofscraper_community-3.16.2/test/test_supress_display_bool.py +73 -0
  553. ofscraper_community-3.16.2/test/test_supress_display_restore.py +151 -0
  554. ofscraper_community-3.16.2/test/test_table_styled_other_values.py +30 -0
  555. ofscraper_community-3.16.2/test/test_temp_cleanup_prefix.py +57 -0
  556. ofscraper_community-3.16.2/test/test_text_file.py +65 -0
  557. ofscraper_community-3.16.2/test/test_textlength.py +78 -0
  558. ofscraper_community-3.16.2/test/test_tls_clienthello.py +162 -0
  559. ofscraper_community-3.16.2/test/test_update_check.py +69 -0
  560. ofscraper_community-3.16.2/test/test_update_selection.py +30 -0
  561. ofscraper_community-3.16.2/test/test_url_log.py +21 -0
  562. ofscraper_community-3.16.2/test/test_version.py +39 -0
  563. ofscraper_community-3.16.2/uv.lock +2996 -0
@@ -0,0 +1,28 @@
1
+ # Ignore Python's virtual environment directory (your 'info' folder)
2
+ info/
3
+ .venv/
4
+ venv/
5
+ env/
6
+
7
+ # Ignore Python cache and artifacts
8
+ __pycache__/
9
+ *.pyc
10
+ *.pyo
11
+ *.pyd
12
+ dist/
13
+ build/
14
+ wiki/
15
+ *.egg-info/
16
+
17
+ # Ignore editor and OS-specific files
18
+ .vscode/
19
+ .idea/
20
+ *.DS_Store
21
+
22
+ # Ignore test files if they aren't needed in the final image
23
+ test/
24
+
25
+ # Ignore local secrets or temp files
26
+ .env
27
+ .tempmedia/
28
+ *.log
@@ -0,0 +1 @@
1
+ .git_archival.json export-subst
@@ -0,0 +1,66 @@
1
+ ---
2
+ name: Bug report
3
+ about: Report an issue with running the script
4
+ title: "# Clear Description of issue"
5
+ labels: ""
6
+ assignees: ""
7
+ ---
8
+
9
+ <!---
10
+ Issues pertaining to the script not working
11
+ Must have a log file and config, otherwhise they will be closed
12
+
13
+ You may submit tickets privately on discord
14
+ In other cases a log and config may be helpful
15
+ -->
16
+
17
+ ## Describe the bug
18
+
19
+ A clear and concise description of what the bug is.
20
+
21
+ ## To Reproduce
22
+
23
+ Steps to reproduce the behavior:
24
+ Hint: enter the command and args would be a good idea
25
+
26
+ Example
27
+
28
+ 1. Go to '...'
29
+ 2. Click on '....'
30
+ 3. Scroll down to '....'
31
+ 4. See error
32
+
33
+ ## Expected behavior
34
+
35
+ A clear and concise description of what you expected to happen.
36
+
37
+ ## Screenshots/Logs
38
+
39
+ Logs are required for any reports of any issue, unless the issue is related to setup of script
40
+ Logs must be at least debug level
41
+
42
+ Hint: Please make sure that the log formatting is readable, use a paste site
43
+ like
44
+ [Private Bin](https://privatebin.io/)
45
+
46
+ ## Config
47
+
48
+ Please provide details about your correct config
49
+ This is required for all reports
50
+
51
+ Feel free to anonymize information
52
+
53
+ - for example home directory
54
+ - keydb api key
55
+
56
+ ## System Info
57
+
58
+ - OS: [e.g. iOS]
59
+ - Browser [e.g. chrome, safari]
60
+ - Version [e.g. 22]
61
+ - binary or python
62
+ - python version if installed via pip or pypi
63
+
64
+ ## Additional context
65
+
66
+ Add any other context about the problem here.
@@ -0,0 +1,19 @@
1
+ ---
2
+ name: Feature request
3
+ about: Suggest an idea for this project
4
+ title: ""
5
+ labels: ""
6
+ assignees: ""
7
+ ---
8
+
9
+ **Is your feature request related to a problem? Please describe.**
10
+ A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
11
+
12
+ **Describe the solution you'd like**
13
+ A clear and concise description of what you want to happen.
14
+
15
+ **Describe alternatives you've considered**
16
+ A clear and concise description of any alternative solutions or features you've considered.
17
+
18
+ **Additional context**
19
+ Add any other context or screenshots about the feature request here.
@@ -0,0 +1,186 @@
1
+ # .github/actions/retry-artifact-operation/action.yml
2
+ name: 'Retryable Artifact Operation (Fixed Attempts)'
3
+ description: 'Uploads or downloads artifacts with a fixed number of retries.'
4
+
5
+ inputs:
6
+ operation_type:
7
+ description: 'Specify "upload", "download-specific", or "download-all".' # Updated description for clarity
8
+ required: true
9
+ type: string
10
+ name:
11
+ description: 'Artifact name for upload or specific download. Omit/leave empty for "download-all".'
12
+ required: false # <--- CRITICAL: Set to false to allow omitting for "download-all"
13
+ type: string
14
+ path:
15
+ description: 'Paths for operation.'
16
+ required: true
17
+ type: string
18
+ if_no_files_found:
19
+ description: 'For upload: warn, error, ignore.'
20
+ required: false
21
+ default: 'warn'
22
+ type: string
23
+ overwrite:
24
+ description: 'For upload: true/false.'
25
+ required: false
26
+ default: 'true'
27
+ type: boolean
28
+
29
+ runs:
30
+ using: "composite"
31
+ steps:
32
+ # --- ATTEMPT 1 ---
33
+ # Path 1: Upload Logic for Attempt 1
34
+ - name: Attempt 1 - Upload Artifact
35
+ id: upload_attempt_1
36
+ if: ${{ inputs.operation_type == 'upload' }}
37
+ uses: actions/upload-artifact@v7
38
+ with:
39
+ name: ${{ inputs.name }}
40
+ path: ${{ inputs.path }}
41
+ if-no-files-found: ${{ inputs.if_no_files_found }}
42
+ overwrite: ${{ inputs.overwrite }}
43
+ continue-on-error: true
44
+
45
+ # Path 2: Download Specific Artifact Logic for Attempt 1
46
+ - name: Attempt 1 - Download Specific Artifact
47
+ id: download_specific_attempt_1 # Unique ID for specific download
48
+ if: ${{ inputs.operation_type == 'download' && inputs.name != '' }} # Run if download AND name is provided
49
+ uses: actions/download-artifact@v8
50
+ with:
51
+ name: ${{ inputs.name }}
52
+ path: ${{ inputs.path }}
53
+ continue-on-error: true
54
+
55
+ # Path 3: Download All Artifacts Logic for Attempt 1
56
+ - name: Attempt 1 - Download All Artifacts
57
+ id: download_all_attempt_1 # Unique ID for download all
58
+ if: ${{ inputs.operation_type == 'download' && inputs.name == '' }} # Run if download AND name is empty (implying download all)
59
+ uses: actions/download-artifact@v8
60
+ with:
61
+ # NO 'name' input here to explicitly trigger download all behavior
62
+ path: ${{ inputs.path }}
63
+ continue-on-error: true
64
+
65
+ # --- ATTEMPT 2 ---
66
+ # Delay for Attempt 2 (checking outcomes of previous attempt for all 3 paths)
67
+ - name: Delay for Attempt 2
68
+ if: | # Multi-line if condition for readability
69
+ ${{ (inputs.operation_type == 'upload' && steps.upload_attempt_1.outcome == 'failure') ||
70
+ (inputs.operation_type == 'download' && inputs.name != '' && steps.download_specific_attempt_1.outcome == 'failure') ||
71
+ (inputs.operation_type == 'download' && inputs.name == '' && steps.download_all_attempt_1.outcome == 'failure') }}
72
+ run: |
73
+ echo "Previous attempt failed. Retrying in 10 seconds..." >&2
74
+ sleep 10
75
+ shell: bash
76
+
77
+ # Path 1: Upload Logic for Attempt 2
78
+ - name: Attempt 2 - Upload Artifact
79
+ id: upload_attempt_2
80
+ if: ${{ inputs.operation_type == 'upload' && steps.upload_attempt_1.outcome == 'failure' }}
81
+ uses: actions/upload-artifact@v7
82
+ with:
83
+ name: ${{ inputs.name }}
84
+ path: ${{ inputs.path }}
85
+ if-no-files-found: ${{ inputs.if_no_files_found }}
86
+ overwrite: ${{ inputs.overwrite }}
87
+ continue-on-error: true
88
+
89
+ # Path 2: Download Specific Artifact Logic for Attempt 2
90
+ - name: Attempt 2 - Download Specific Artifact
91
+ id: download_specific_attempt_2
92
+ if: ${{ inputs.operation_type == 'download' && inputs.name != '' && steps.download_specific_attempt_1.outcome == 'failure' }}
93
+ uses: actions/download-artifact@v8
94
+ with:
95
+ name: ${{ inputs.name }}
96
+ path: ${{ inputs.path }}
97
+ continue-on-error: true
98
+
99
+ # Path 3: Download All Artifacts Logic for Attempt 2
100
+ - name: Attempt 2 - Download All Artifacts
101
+ id: download_all_attempt_2
102
+ if: ${{ inputs.operation_type == 'download' && inputs.name == '' && steps.download_all_attempt_1.outcome == 'failure' }}
103
+ uses: actions/download-artifact@v8
104
+ with:
105
+ path: ${{ inputs.path }}
106
+ continue-on-error: true
107
+
108
+ # --- ATTEMPT 3 ---
109
+ # Delay for Attempt 3
110
+ - name: Delay for Attempt 3
111
+ if: |
112
+ ${{ (inputs.operation_type == 'upload' && steps.upload_attempt_2.outcome == 'failure') ||
113
+ (inputs.operation_type == 'download' && inputs.name != '' && steps.download_specific_attempt_2.outcome == 'failure') ||
114
+ (inputs.operation_type == 'download' && inputs.name == '' && steps.download_all_attempt_2.outcome == 'failure') }}
115
+ run: |
116
+ echo "Previous attempt failed. Retrying in 10 seconds..." >&2
117
+ sleep 10
118
+ shell: bash
119
+
120
+ # Path 1: Upload Logic for Attempt 3
121
+ - name: Attempt 3 - Upload Artifact
122
+ id: upload_attempt_3
123
+ if: ${{ inputs.operation_type == 'upload' && steps.upload_attempt_2.outcome == 'failure' }}
124
+ uses: actions/upload-artifact@v7
125
+ with:
126
+ name: ${{ inputs.name }}
127
+ path: ${{ inputs.path }}
128
+ if-no-files-found: ${{ inputs.if_no_files_found }}
129
+ overwrite: ${{ inputs.overwrite }}
130
+ continue-on-error: true
131
+
132
+ # Path 2: Download Specific Artifact Logic for Attempt 3
133
+ - name: Attempt 3 - Download Specific Artifact
134
+ id: download_specific_attempt_3
135
+ if: ${{ inputs.operation_type == 'download' && inputs.name != '' && steps.download_specific_attempt_2.outcome == 'failure' }}
136
+ uses: actions/download-artifact@v8
137
+ with:
138
+ name: ${{ inputs.name }}
139
+ path: ${{ inputs.path }}
140
+ continue-on-error: true
141
+
142
+ # Path 3: Download All Artifacts Logic for Attempt 3
143
+ - name: Attempt 3 - Download All Artifacts
144
+ id: download_all_attempt_3
145
+ if: ${{ inputs.operation_type == 'download' && inputs.name == '' && steps.download_all_attempt_2.outcome == 'failure' }}
146
+ uses: actions/download-artifact@v8
147
+ with:
148
+ path: ${{ inputs.path }}
149
+ continue-on-error: true
150
+
151
+ # --- FINAL STATUS CHECK ---
152
+ # This step will fail the composite action if all attempts for the chosen operation failed
153
+ - name: Final Check on Operation Status
154
+ run: |
155
+ if [ "${{ inputs.operation_type }}" == "upload" ]; then
156
+ if [ "${{ steps.upload_attempt_1.outcome }}" == "failure" ] && \
157
+ [ "${{ steps.upload_attempt_2.outcome }}" == "failure" ] && \
158
+ [ "${{ steps.upload_attempt_3.outcome }}" == "failure" ]; then
159
+ echo "::error::Artifact upload failed after all 3 attempts." >&2
160
+ exit 1
161
+ fi
162
+ elif [ "${{ inputs.operation_type }}" == "download" ]; then
163
+ DOWNLOAD_FAILED="false"
164
+ if [ "${{ inputs.name }}" != "" ]; then # Check specific download path if name was provided
165
+ if [ "${{ steps.download_specific_attempt_1.outcome }}" == "failure" ] && \
166
+ [ "${{ steps.download_specific_attempt_2.outcome }}" == "failure" ] && \
167
+ [ "${{ steps.download_specific_attempt_3.outcome }}" == "failure" ]; then
168
+ DOWNLOAD_FAILED="true"
169
+ fi
170
+ else # Check download all path if name was NOT provided
171
+ if [ "${{ steps.download_all_attempt_1.outcome }}" == "failure" ] && \
172
+ [ "${{ steps.download_all_attempt_2.outcome }}" == "failure" ] && \
173
+ [ "${{ steps.download_all_attempt_3.outcome }}" == "failure" ]; then
174
+ DOWNLOAD_FAILED="true"
175
+ fi
176
+ fi
177
+
178
+ if [ "$DOWNLOAD_FAILED" == "true" ]; then
179
+ echo "::error::Artifact download failed after all 3 attempts." >&2
180
+ exit 1
181
+ fi
182
+ else
183
+ echo "::error::Invalid operation_type specified. Must be 'upload' or 'download'." >&2
184
+ exit 1
185
+ fi
186
+ shell: bash
@@ -0,0 +1,11 @@
1
+ # To get started with Dependabot version updates, you'll need to specify which
2
+ # package ecosystems to update and where the package manifests are located.
3
+ # Please see the documentation for all configuration options:
4
+ # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
5
+
6
+ version: 2
7
+ updates:
8
+ - package-ecosystem: "" # See documentation for possible values
9
+ directory: / # Location of package manifests
10
+ schedule:
11
+ interval: weekly
@@ -0,0 +1,56 @@
1
+ name: codecov
2
+ permissions: read-all
3
+ on:
4
+ push:
5
+ branches: main
6
+ # doc-only changes don't need a build or test run
7
+ paths-ignore:
8
+ - '**.md'
9
+ - 'docs/**'
10
+ - 'media/**'
11
+ - 'LICENSE'
12
+ - '.github/ISSUE_TEMPLATE/**'
13
+ pull_request:
14
+ branches: main
15
+ # doc-only changes don't need a build or test run
16
+ paths-ignore:
17
+ - '**.md'
18
+ - 'docs/**'
19
+ - 'media/**'
20
+ - 'LICENSE'
21
+ - '.github/ISSUE_TEMPLATE/**'
22
+
23
+ jobs:
24
+ run:
25
+ runs-on: ubuntu-latest
26
+ strategy:
27
+ fail-fast: false
28
+ matrix:
29
+ # oldest supported and current
30
+ python-version: ["3.11", "3.15.2"]
31
+ steps:
32
+ - name: Checkout
33
+ uses: actions/checkout@v7
34
+ with:
35
+ # version-pioneer derives the package version from git tags
36
+ fetch-depth: 0
37
+ fetch-tags: true
38
+ - name: Set up uv and Python ${{ matrix.python-version }}
39
+ uses: astral-sh/setup-uv@v6
40
+ with:
41
+ python-version: ${{ matrix.python-version }}
42
+ # --frozen installs exactly what uv.lock pins, so a new upstream release
43
+ # can't change what CI tests
44
+ - name: Install dependencies
45
+ run: uv sync --frozen --extra test
46
+ - name: create required folder
47
+ run: mkdir -p /home/runner/.config/ofscraper/main_profile
48
+ - name: Run tests and collect coverage
49
+ run: uv run --frozen pytest test --cov-report term --cov-report xml:coverage.xml --cov=ofscraper
50
+ - name: Upload coverage to Codecov
51
+ if: ${{ !cancelled() && matrix.python-version == '3.15.2' }}
52
+ uses: codecov/codecov-action@v7
53
+ with:
54
+ token: ${{ secrets.CODECOV_TOKEN }}
55
+ files: coverage.xml
56
+ fail_ci_if_error: false
@@ -0,0 +1,302 @@
1
+ name: Build and Package
2
+
3
+ on:
4
+ push:
5
+ # Pushes to main build the binaries as a check. A version tag (e.g. 3.15.1)
6
+ # also publishes them as that version's release; path filters don't apply
7
+ # to tag pushes.
8
+ branches:
9
+ - main
10
+ tags:
11
+ - '[0-9]+.[0-9]+.[0-9]+'
12
+ - 'v[0-9]+.[0-9]+.[0-9]+'
13
+ # doc-only changes don't need a build or test run
14
+ paths-ignore:
15
+ - '**.md'
16
+ - 'docs/**'
17
+ - 'media/**'
18
+ - 'LICENSE'
19
+ - '.github/ISSUE_TEMPLATE/**'
20
+
21
+ permissions:
22
+ contents: read # Required for git checkout and gh CLI to read workflow runs
23
+
24
+ jobs:
25
+ generate_version:
26
+ name: Generate Version Info
27
+ runs-on: ubuntu-latest
28
+ env:
29
+ GH_TOKEN: ${{ github.token }}
30
+ GITHUB_REPOSITORY: ${{ github.repository }}
31
+ GITHUB_REF: ${{ github.ref }}
32
+ GITHUB_EVENT_BEFORE: ${{ github.event.before }}
33
+ outputs:
34
+ version: ${{ steps.version.outputs.VERSION }}
35
+ sanitized_version: ${{ steps.version.outputs.SANITIZED_VERSION }}
36
+ short_hash: ${{ steps.version.outputs.SHORT_HASH }}
37
+ long_hash: ${{ steps.version.outputs.LONG_HASH }}
38
+ commit_timestamp: ${{ steps.version.outputs.COMMIT_TIMESTAMP }}
39
+ base_version: ${{ steps.version.outputs.BASE_VERSION }}
40
+ push_type: ${{ steps.version.outputs.PUSH_TYPE }}
41
+ is_newer_than_last_successful_run: ${{ steps.version.outputs.IS_NEWER_THAN_LAST_SUCCESSFUL_RUN }}
42
+ steps:
43
+ - name: Checkout Code
44
+ uses: actions/checkout@v7
45
+ with:
46
+ fetch-depth: 0 # Essential for git merge-base to compare full history
47
+ fetch-tags: true
48
+
49
+ - name: Make script executable
50
+ run: chmod +x ./scripts/commit_version.sh
51
+ - name: Generate Version and Git Info
52
+ id: version # This step runs your commit_version.sh script
53
+ # Pass GitHub Actions context variables as environment variables to the script
54
+ run: ./scripts/commit_version.sh
55
+
56
+ build_binaries:
57
+ name: Build on ${{ matrix.os }}
58
+ needs: [generate_version]
59
+ runs-on: ${{ matrix.os }}
60
+
61
+ strategy:
62
+ fail-fast: false # <-- ADDED: Allows all OS builds to complete even if one fails
63
+ matrix:
64
+ os: [ubuntu-latest, windows-latest, macos-latest]
65
+ include:
66
+ - os: ubuntu-latest
67
+ artifact_suffix: linux
68
+ shell: bash
69
+ - os: windows-latest
70
+ artifact_suffix: windows
71
+ shell: pwsh
72
+ - os: macos-latest
73
+ artifact_suffix: macos
74
+ shell: bash
75
+
76
+ steps:
77
+ - name: Checkout Code
78
+ uses: actions/checkout@v7
79
+ with:
80
+ fetch-depth: 0
81
+ fetch-tags: true
82
+ - name: Set up Python
83
+ uses: actions/setup-python@v7
84
+ with:
85
+ python-version: 3.15.1
86
+ - name: Install uv
87
+ uses: astral-sh/setup-uv@v10.3.1
88
+
89
+ - name: Set Version Environment Variables
90
+ shell: bash
91
+ run: |
92
+ echo "HATCH_VCS_PRETEND_VERSION=${{ needs.generate_version.outputs.version }}" >> $GITHUB_ENV
93
+
94
+ - name: Install Dependencies and Build Tools
95
+ shell: bash
96
+ run: |
97
+ uv venv
98
+ if [ "${{ runner.os }}" == "Windows" ]; then
99
+ . .venv/Scripts/activate
100
+ else
101
+ source .venv/bin/activate
102
+ fi
103
+ uv sync --verbose --extra ffmpeg --extra dev
104
+
105
+ - name: Set UTF-8 environment (Windows)
106
+ if: runner.os == 'Windows'
107
+ run: |
108
+ echo "PYTHONUTF8=1" >> $env:GITHUB_ENV
109
+ echo "PYTHONLEGACYWINDOWSSTDIO=utf8" >> $env:GITHUB_ENV
110
+ shell: pwsh
111
+
112
+ - name: Build Executable using Spec Files (One-File)
113
+ id: build_onefile
114
+ shell: bash
115
+ continue-on-error: true # <-- ADDED: Allows this step to fail without stopping this OS matrix axis
116
+ run: |
117
+ SANITIZED_VERSION="${{ needs.generate_version.outputs.sanitized_version }}"
118
+ EXE_NAME="ofscraper_${{ matrix.artifact_suffix }}_${SANITIZED_VERSION}"
119
+
120
+ if [ "${{ runner.os }}" == "Windows" ]; then
121
+ source .venv/Scripts/activate
122
+ EXE_EXT=".exe"
123
+ else
124
+ source .venv/bin/activate
125
+ EXE_EXT=""
126
+ fi
127
+
128
+ echo "Building one-file executable from specs/onefile.spec..."
129
+ pyinstaller specs/onefile.spec
130
+ mv dist/ofscraper_file${EXE_EXT} dist/${EXE_NAME}${EXE_EXT}
131
+ echo "one_file_path=dist/${EXE_NAME}${EXE_EXT}" >> $GITHUB_OUTPUT
132
+ echo "one_file_name=${EXE_NAME}${EXE_EXT}" >> $GITHUB_OUTPUT
133
+
134
+ - name: Upload One-File Artifact
135
+ uses: actions/upload-artifact@v7
136
+ with:
137
+ name: ${{ steps.build_onefile.outputs.one_file_name }}
138
+ path: ${{ steps.build_onefile.outputs.one_file_path }}
139
+ if-no-files-found: ignore # Ensures upload step doesn't fail if previous build step failed
140
+
141
+ - name: Build and Zip One-Dir Bundle
142
+ id: build_onedir_zip
143
+ shell: bash
144
+ continue-on-error: true # Already present: Allows this step to fail without stopping this OS matrix axis
145
+ run: |
146
+ SANITIZED_VERSION="${{ needs.generate_version.outputs.sanitized_version }}"
147
+ DIR_NAME="ofscraper_${{ matrix.artifact_suffix }}_dir"
148
+ ZIP_NAME="ofscraper_${{ matrix.artifact_suffix }}_${SANITIZED_VERSION}.zip"
149
+
150
+ if [ "${{ runner.os }}" == "Windows" ]; then
151
+ source .venv/Scripts/activate
152
+ else
153
+ source .venv/bin/activate
154
+ fi
155
+
156
+ echo "Building one-dir bundle from specs/onedir.spec..."
157
+ pyinstaller specs/onedir.spec
158
+ mv dist/ofscraper_dir dist/${DIR_NAME}
159
+
160
+ echo "Zipping one-dir build..."
161
+ if [ "${{ runner.os }}" == "Windows" ]; then
162
+ powershell -Command "Compress-Archive -Path dist/${DIR_NAME} -DestinationPath dist/${ZIP_NAME} -Force"
163
+ else
164
+ zip -r "dist/${ZIP_NAME}" "dist/${DIR_NAME}"
165
+ fi
166
+ echo "zip_path=dist/${ZIP_NAME}" >> $GITHUB_OUTPUT
167
+ echo "zip_name=${ZIP_NAME}" >> $GITHUB_OUTPUT
168
+ echo "dir_path=dist/${DIR_NAME}" >> $GITHUB_OUTPUT
169
+ echo "dir_name=dist/${DIR_NAME}" >> $GITHUB_OUTPUT
170
+
171
+ - name: Upload Zipped One-Dir Artifact
172
+ if: success() && steps.build_onedir_zip.outcome == 'success'
173
+ uses: actions/upload-artifact@v7
174
+ with:
175
+ name: ${{ steps.build_onedir_zip.outputs.zip_name }}
176
+ path: ${{ steps.build_onedir_zip.outputs.zip_path }}
177
+ if-no-files-found: ignore # Ensures upload step doesn't fail if previous build step failed
178
+
179
+ - name: Upload One-Dir Folder (if zip failed)
180
+ if: failure() && steps.build_onedir_zip.outcome == 'failure'
181
+ uses: actions/upload-artifact@v7
182
+ with:
183
+ name: ${{ steps.build_onedir_zip.outputs.dir_name }}
184
+ path: ${{ steps.build_onedir_zip.outputs.dir_path }}
185
+ if-no-files-found: ignore # Ensures upload step doesn't fail if previous build step failed
186
+
187
+ publish_release:
188
+ name: Publish GitHub Release
189
+ if: startsWith(github.ref, 'refs/tags/')
190
+ needs: [build_binaries, generate_version] # Waits for version info AND all binary builds to complete (even partially)
191
+ runs-on: ubuntu-latest
192
+ permissions:
193
+ contents: write # Required to create/update GitHub Releases
194
+ steps:
195
+ - name: Download all build artifacts
196
+ uses: actions/download-artifact@v8
197
+ with:
198
+ path: artifacts/
199
+ # No specific `if-no-files-found` here on download-artifact, it will download what's available
200
+ # and log warnings for missing ones by default.
201
+
202
+ - name: List downloaded files for debugging
203
+ run: ls -R artifacts
204
+
205
+ - name: Create or Update Release
206
+ uses: ncipollo/release-action@v1.21.0
207
+
208
+ with:
209
+ artifacts: artifacts/*/* # Attach any downloaded artifacts (will include only those that were built successfully)
210
+ # One release per version tag; a re-run updates it
211
+ tag: ${{ github.ref_name }}
212
+ name: ${{ needs.generate_version.outputs.version }}
213
+ generateReleaseNotes: true
214
+ allowUpdates: true
215
+ prerelease: false
216
+ makeLatest: true
217
+
218
+ build_pypi_dist:
219
+ name: Build PyPI Packages
220
+ if: startsWith(github.ref, 'refs/tags/')
221
+ needs: [generate_version]
222
+ runs-on: ubuntu-latest
223
+ steps:
224
+ - name: Checkout Code
225
+ uses: actions/checkout@v7
226
+ with:
227
+ fetch-depth: 0
228
+ fetch-tags: true
229
+ persist-credentials: false
230
+ - name: Install uv
231
+ uses: astral-sh/setup-uv@v10.3.1
232
+
233
+ - name: Build sdist and wheel
234
+ env:
235
+ # the plain tag version (e.g. 3.16.2); plugins.py would add +g<hash>
236
+ HATCH_VCS_PRETEND_VERSION: ${{ needs.generate_version.outputs.version }}
237
+ run: uv build --python 3.15
238
+
239
+ - name: Check the version is the plain tag
240
+ env:
241
+ TAG: ${{ github.ref_name }}
242
+ run: |
243
+ EXPECTED="${TAG#v}"
244
+ for f in dist/*; do echo "built: $f"; done
245
+ WHEELS=(dist/ofscraper_community-*-py3-none-any.whl)
246
+ SDISTS=(dist/ofscraper_community-*.tar.gz)
247
+ if [ ${#WHEELS[@]} -ne 1 ] || [ ! -f "${WHEELS[0]}" ] || [ ${#SDISTS[@]} -ne 1 ] || [ ! -f "${SDISTS[0]}" ]; then
248
+ echo "::error::expected one ofscraper-community wheel and one sdist"; exit 1
249
+ fi
250
+ BUILT=$(unzip -p "${WHEELS[0]}" '*.dist-info/METADATA' | sed -n 's/^Version: //p' | tr -d '\r')
251
+ NAME=$(unzip -p "${WHEELS[0]}" '*.dist-info/METADATA' | sed -n 's/^Name: //p' | tr -d '\r')
252
+ echo "name: $NAME, version: $BUILT, tag: $TAG"
253
+ if [ "$NAME" != "ofscraper-community" ]; then
254
+ echo "::error::package name is '$NAME', not 'ofscraper-community'"; exit 1
255
+ fi
256
+ case "$BUILT" in
257
+ *+*) echo "::error::version '$BUILT' has a local part, which PyPI rejects"; exit 1 ;;
258
+ esac
259
+ if [ "$BUILT" != "$EXPECTED" ]; then
260
+ echo "::error::version '$BUILT' doesn't match tag '$TAG'"; exit 1
261
+ fi
262
+ if [ "${SDISTS[0]}" != "dist/ofscraper_community-${EXPECTED}.tar.gz" ]; then
263
+ echo "::error::sdist '${SDISTS[0]}' doesn't match tag '$TAG'"; exit 1
264
+ fi
265
+
266
+ - name: Check the wheel installs and runs
267
+ env:
268
+ TAG: ${{ github.ref_name }}
269
+ run: |
270
+ uv venv --python 3.11 "$RUNNER_TEMP/smoke"
271
+ uv pip install --python "$RUNNER_TEMP/smoke" dist/*.whl
272
+ OUTPUT=$("$RUNNER_TEMP/smoke/bin/ofscraper" --version)
273
+ echo "$OUTPUT"
274
+ echo "$OUTPUT" | grep -qF "${TAG#v}"
275
+
276
+ - name: Upload packages
277
+ uses: actions/upload-artifact@v7
278
+ with:
279
+ name: pypi-dist
280
+ path: dist/
281
+ if-no-files-found: error
282
+
283
+ publish_pypi:
284
+ name: Publish to PyPI
285
+ if: startsWith(github.ref, 'refs/tags/')
286
+ # A PyPI version can't be replaced once uploaded, so publish last: only
287
+ # after the packages passed their checks and the GitHub release exists.
288
+ needs: [build_pypi_dist, publish_release]
289
+ runs-on: ubuntu-latest
290
+ environment:
291
+ name: pypi
292
+ url: https://pypi.org/project/ofscraper-community/
293
+ permissions:
294
+ id-token: write # trusted publishing; no token or password is stored
295
+ steps:
296
+ - name: Download packages
297
+ uses: actions/download-artifact@v8
298
+ with:
299
+ name: pypi-dist
300
+ path: dist/
301
+ - name: Publish to PyPI
302
+ uses: pypa/gh-action-pypi-publish@v1.14.3