cyberdrop-dl-patched 5.7.2.dev2__tar.gz → 5.7.2.dev4__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 (121) hide show
  1. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/CHANGELOG.md +5 -5
  2. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/PKG-INFO +1 -1
  3. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/clients/download_client.py +3 -3
  4. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/clients/scraper_client.py +3 -3
  5. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/downloader/downloader.py +1 -2
  6. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/main.py +38 -20
  7. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/managers/client_manager.py +147 -10
  8. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/managers/config_manager.py +88 -118
  9. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/managers/download_manager.py +6 -6
  10. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/managers/live_manager.py +2 -10
  11. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/managers/manager.py +1 -0
  12. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/managers/real_debrid/api.py +1 -1
  13. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/scraper/crawler.py +1 -2
  14. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/scraper/crawlers/celebforum_crawler.py +1 -1
  15. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/scraper/crawlers/chevereto_crawler.py +2 -1
  16. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/scraper/crawlers/coomer_crawler.py +11 -5
  17. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/scraper/crawlers/cyberfile_crawler.py +1 -0
  18. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/scraper/crawlers/erome_crawler.py +1 -1
  19. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/scraper/crawlers/f95zone_crawler.py +1 -1
  20. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/scraper/crawlers/kemono_crawler.py +7 -4
  21. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/scraper/crawlers/nudostar_crawler.py +1 -1
  22. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/scraper/crawlers/pixeldrain_crawler.py +1 -1
  23. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/scraper/crawlers/saint_crawler.py +1 -1
  24. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/scraper/crawlers/simpcity_crawler.py +1 -1
  25. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/scraper/crawlers/socialmediagirls_crawler.py +3 -2
  26. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/scraper/crawlers/xbunker_crawler.py +1 -1
  27. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/scraper/jdownloader.py +1 -1
  28. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/scraper/scraper.py +6 -1
  29. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/ui/prompts/settings_authentication_prompts.py +19 -7
  30. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/ui/prompts/settings_hash_prompts.py +1 -3
  31. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/ui/prompts/settings_user_prompts.py +111 -2
  32. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/ui/ui.py +1 -1
  33. cyberdrop_dl_patched-5.7.2.dev4/cyberdrop_dl/utils/args/browser_cookie_extraction.py +134 -0
  34. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/utils/args/config_definitions.py +5 -0
  35. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/utils/utilities.py +9 -9
  36. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/pyproject.toml +16 -12
  37. cyberdrop_dl_patched-5.7.2.dev2/cyberdrop_dl/utils/args/browser_cookie_extraction.py +0 -78
  38. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/LICENSE +0 -0
  39. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/README.md +0 -0
  40. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/__init__.py +0 -0
  41. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/clients/__init__.py +0 -0
  42. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/clients/errors.py +0 -0
  43. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/clients/hash_client.py +0 -0
  44. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/downloader/__init__.py +0 -0
  45. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/managers/__init__.py +0 -0
  46. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/managers/args_manager.py +0 -0
  47. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/managers/cache_manager.py +0 -0
  48. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/managers/db_manager.py +0 -0
  49. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/managers/hash_manager.py +0 -0
  50. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/managers/leaky.py +0 -0
  51. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/managers/log_manager.py +0 -0
  52. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/managers/path_manager.py +0 -0
  53. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/managers/progress_manager.py +0 -0
  54. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/managers/real_debrid/__init__.py +0 -0
  55. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/managers/real_debrid/errors.py +0 -0
  56. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/managers/realdebrid_manager.py +0 -0
  57. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/scraper/__init__.py +0 -0
  58. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/scraper/crawlers/__init__.py +0 -0
  59. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/scraper/crawlers/bunkrr_crawler.py +0 -0
  60. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/scraper/crawlers/cyberdrop_crawler.py +0 -0
  61. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/scraper/crawlers/ehentai_crawler.py +0 -0
  62. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/scraper/crawlers/fapello_crawler.py +0 -0
  63. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/scraper/crawlers/gofile_crawler.py +0 -0
  64. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/scraper/crawlers/hotpic_crawler.py +0 -0
  65. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/scraper/crawlers/imageban_crawler.py +0 -0
  66. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/scraper/crawlers/imgbb_crawler.py +0 -0
  67. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/scraper/crawlers/imgbox_crawler.py +0 -0
  68. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/scraper/crawlers/imgur_crawler.py +0 -0
  69. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/scraper/crawlers/leakedmodels_crawler.py +0 -0
  70. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/scraper/crawlers/mediafire_crawler.py +0 -0
  71. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/scraper/crawlers/nekohouse_crawler.py +0 -0
  72. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/scraper/crawlers/nudostartv_crawler.py +0 -0
  73. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/scraper/crawlers/omegascans_crawler.py +0 -0
  74. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/scraper/crawlers/pimpandhost_crawler.py +0 -0
  75. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/scraper/crawlers/postimg_crawler.py +0 -0
  76. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/scraper/crawlers/realbooru_crawler.py +0 -0
  77. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/scraper/crawlers/realdebrid_crawler.py +0 -0
  78. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/scraper/crawlers/reddit_crawler.py +0 -0
  79. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/scraper/crawlers/redgifs_crawler.py +0 -0
  80. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/scraper/crawlers/rule34vault_crawler.py +0 -0
  81. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/scraper/crawlers/rule34xxx_crawler.py +0 -0
  82. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/scraper/crawlers/rule34xyz_crawler.py +0 -0
  83. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/scraper/crawlers/scrolller_crawler.py +0 -0
  84. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/scraper/crawlers/tokyomotion_crawler.py +0 -0
  85. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/scraper/crawlers/toonily_crawler.py +0 -0
  86. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/scraper/crawlers/xbunkr_crawler.py +0 -0
  87. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/scraper/crawlers/xxxbunker_crawler.py +0 -0
  88. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/scraper/filters.py +0 -0
  89. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/ui/__init__.py +0 -0
  90. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/ui/progress/__init__.py +0 -0
  91. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/ui/progress/downloads_progress.py +0 -0
  92. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/ui/progress/file_progress.py +0 -0
  93. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/ui/progress/hash_progress.py +0 -0
  94. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/ui/progress/scraping_progress.py +0 -0
  95. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/ui/progress/sort_progress.py +0 -0
  96. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/ui/progress/statistic_progress.py +0 -0
  97. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/ui/prompts/__init__.py +0 -0
  98. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/ui/prompts/continue_prompt.py +0 -0
  99. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/ui/prompts/general_prompts.py +0 -0
  100. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/ui/prompts/settings_global_prompts.py +0 -0
  101. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/ui/prompts/url_file_prompts.py +0 -0
  102. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/utils/__init__.py +0 -0
  103. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/utils/args/__init__.py +0 -0
  104. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/utils/args/args.py +0 -0
  105. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/utils/constants.py +0 -0
  106. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/utils/database/__init__.py +0 -0
  107. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/utils/database/table_definitions.py +0 -0
  108. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/utils/database/tables/__init__.py +0 -0
  109. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/utils/database/tables/hash_table.py +0 -0
  110. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/utils/database/tables/history_table.py +0 -0
  111. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/utils/database/tables/temp_referer_table.py +0 -0
  112. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/utils/database/tables/temp_table.py +0 -0
  113. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/utils/dataclasses/__init__.py +0 -0
  114. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/utils/dataclasses/supported_domains.py +0 -0
  115. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/utils/dataclasses/url_objects.py +0 -0
  116. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/utils/logger.py +0 -0
  117. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/utils/sorting.py +0 -0
  118. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/utils/transfer/__init__.py +0 -0
  119. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/utils/transfer/first_time_setup.py +0 -0
  120. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/utils/transfer/transfer_v4_config.py +0 -0
  121. {cyberdrop_dl_patched-5.7.2.dev2 → cyberdrop_dl_patched-5.7.2.dev4}/cyberdrop_dl/utils/transfer/transfer_v4_db.py +0 -0
@@ -13,7 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
13
13
 
14
14
  This update introduces the following changes:
15
15
 
16
- 1. Adds the option to limit how many items are scraped
16
+ 1. Adds the option to limit how many items are scraped
17
17
  2. Add support for scraping a users' coomer favorites
18
18
  3. Add integration to handle downloads supported by https://real-debrid.com
19
19
  4. Add support for https://nekohouse.su profiles and posts
@@ -29,7 +29,7 @@ This update introduces the following changes:
29
29
 
30
30
  - Users can limit the number of items to scrape by type, using the `--maximum-number-of-children` parameter. For more details on how to use this feature, visit the wiki: https://script-ware.gitbook.io/cyberdrop-dl/reference/configuration-options/settings#download-options
31
31
  - Add support for scraping a users' coomer favorites by allowing the user to pass the coomer favorites page URL as an input URL (https://coomer.su/favorites). This requires them to have their coomer session token in the `authentication.yaml` file.
32
- - Add real-debrid integration to download from any site that they support (`mega.nz`,`rapidgator`, `google drive`, `k2s`, etc). User needs to provide their API key in the `authentication.yaml` file in order to allow downloads
32
+ - Add real-debrid integration to download from any site that they support (`mega.nz`,`rapidgator`, `google drive`, `k2s`, etc). User needs to provide their API key in the `authentication.yaml` file in order to allow downloads
33
33
  - Nekohouse URLs can now be scraped and downloaded by CDL
34
34
  - Users can now get the stats report of the run via multiple services and include the main log as an attachment. For more information on how to setup notifications, visit: https://script-ware.gitbook.io/cyberdrop-dl/reference/notifications
35
35
  - Fix parsing of bunkr file extensions when `--remove-generated-id` is enabled
@@ -41,7 +41,7 @@ This update introduces the following changes:
41
41
  ## [5.7.0] - 2024-10-25
42
42
 
43
43
  This update introduces the following changes:
44
- 1. Rotating log files
44
+ 1. Rotating log files
45
45
  2. Overhaul hashing functions
46
46
  3. Add support for https://tokyomotion.net URLs
47
47
  4. Add support for https://xxxbunker.com URLs
@@ -69,7 +69,7 @@ This update introduces the following changes:
69
69
  - Fix error during program exit when referers table no longer exists
70
70
  - Prevents crashes when there are insufficient permissions to move a file
71
71
  - Fix an issue where CDL would delete URLs input file
72
- - Move functions for after download to `post_runtime`
72
+ - Move functions for after download to `post_runtime`
73
73
  - Fix handling of deleted imgbox albums if they return `HTTP 200`
74
74
  - Fix cyberfile deleted folders not being correctly scraped
75
75
  - Update logging to include when a file is being downloaded with no crawler
@@ -164,7 +164,7 @@ This update introduces the following changes:
164
164
  ## [5.6.40] - 2024-10-01
165
165
 
166
166
  This update introduces the following changes:
167
- 1. Fixes empty folder cleanup
167
+ 1. Fixes empty folder cleanup
168
168
 
169
169
  #### Details:
170
170
  - Fixes incorrent path objects on post-runtime folder cleanup
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cyberdrop-dl-patched
3
- Version: 5.7.2.dev2
3
+ Version: 5.7.2.dev4
4
4
  Summary: Bulk downloader for multiple file hosts
5
5
  Home-page: https://github.com/jbsparrow/CyberDropDownloader
6
6
  Author: Jacob B
@@ -76,12 +76,12 @@ class DownloadClient:
76
76
  def add_request_log_hooks(self) -> None:
77
77
  async def on_request_start(*args):
78
78
  params: aiohttp.TraceRequestStartParams = args[2]
79
- log(f"Starting download {params.method} request to {params.url}", 40)
79
+ log(f"Starting download {params.method} request to {params.url}", 20)
80
80
 
81
81
  async def on_request_end(*args):
82
82
  params: aiohttp.TraceRequestEndParams = args[2]
83
- log(f"Finishing download {params.method} request to {params.url}", 40)
84
- log(f"Response status for {params.url}: {params.response.status}", 40)
83
+ log(f"Finishing download {params.method} request to {params.url}", 20)
84
+ log(f"Response status for {params.url}: {params.response.status}", 20)
85
85
 
86
86
  trace_config = aiohttp.TraceConfig()
87
87
  trace_config.on_request_start.append(on_request_start)
@@ -65,12 +65,12 @@ class ScraperClient:
65
65
  def add_request_log_hooks(self) -> None:
66
66
  async def on_request_start(*args):
67
67
  params: aiohttp.TraceRequestStartParams = args[2]
68
- log(f"Starting download {params.method} request to {params.url}", 40)
68
+ log(f"Starting download {params.method} request to {params.url}", 20)
69
69
 
70
70
  async def on_request_end(*args):
71
71
  params: aiohttp.TraceRequestEndParams = args[2]
72
- log(f"Finishing download {params.method} request to {params.url}", 40)
73
- log(f"Response status for {params.url}: {params.response.status}", 40)
72
+ log(f"Finishing download {params.method} request to {params.url}", 20)
73
+ log(f"Response status for {params.url}: {params.response.status}", 20)
74
74
 
75
75
  trace_config = aiohttp.TraceConfig()
76
76
  trace_config.on_request_start.append(on_request_start)
@@ -144,8 +144,6 @@ class Downloader:
144
144
  log(f"{self.log_prefix} failed: {media_item.url} with error {e}", 40, exc_info=True)
145
145
  self.manager.progress_manager.download_stats_progress.add_failure("Unknown")
146
146
  self.manager.progress_manager.download_progress.add_failed()
147
- else:
148
- log(f"{self.log_prefix} finished: {media_item.url}", 20)
149
147
  finally:
150
148
  await self._file_lock.release_lock(media_item.file_lock_reference_name)
151
149
  self._semaphore.release()
@@ -195,6 +193,7 @@ class Downloader:
195
193
  self.set_file_datetime(media_item, media_item.complete_file)
196
194
  self.attempt_task_removal(media_item)
197
195
  self.manager.progress_manager.download_progress.add_completed()
196
+ log(f"Download finished: {media_item.url}", 20)
198
197
 
199
198
  except RestrictedFiletypeError:
200
199
  self.manager.progress_manager.download_progress.add_skipped()
@@ -5,8 +5,11 @@ import contextlib
5
5
  import logging
6
6
  import os
7
7
  import sys
8
+ from functools import wraps
8
9
  from pathlib import Path
10
+ from textwrap import indent
9
11
  from time import perf_counter
12
+ from typing import TYPE_CHECKING
10
13
 
11
14
  from rich.console import Console
12
15
  from rich.logging import RichHandler
@@ -15,6 +18,7 @@ from cyberdrop_dl.clients.errors import InvalidYamlError
15
18
  from cyberdrop_dl.managers.manager import Manager
16
19
  from cyberdrop_dl.scraper.scraper import ScrapeMapper
17
20
  from cyberdrop_dl.ui.ui import program_ui
21
+ from cyberdrop_dl.utils.args.browser_cookie_extraction import get_cookies_from_browser
18
22
  from cyberdrop_dl.utils.logger import (
19
23
  log,
20
24
  log_spacer,
@@ -29,6 +33,9 @@ from cyberdrop_dl.utils.utilities import (
29
33
  sent_apprise_notifications,
30
34
  )
31
35
 
36
+ if TYPE_CHECKING:
37
+ from collections.abc import Callable
38
+
32
39
 
33
40
  def startup() -> Manager:
34
41
  """Starts the program and returns the manager.
@@ -67,6 +74,12 @@ async def runtime(manager: Manager) -> None:
67
74
  await scrape_mapper.start()
68
75
 
69
76
 
77
+ def pre_runtime(manager: Manager) -> None:
78
+ """Actions to complete before main runtime."""
79
+ if manager.config_manager.settings_data["Browser_Cookies"]["auto_import"]:
80
+ get_cookies_from_browser(manager)
81
+
82
+
70
83
  async def post_runtime(manager: Manager) -> None:
71
84
  """Actions to complete after main runtime, and before ui shutdown."""
72
85
  log_spacer(20)
@@ -158,6 +171,25 @@ def setup_logger(manager: Manager, config_name: str) -> None:
158
171
  constants.CONSOLE_LEVEL = manager.config_manager.settings_data["Runtime_Options"]["console_log_level"]
159
172
 
160
173
 
174
+ def ui_error_handling_wrapper(func: Callable) -> None:
175
+ """Wrapper handles errors from the main UI"""
176
+
177
+ @wraps(func)
178
+ async def wrapper(*args, **kwargs):
179
+ try:
180
+ return await func(*args, **kwargs)
181
+ except* Exception as e:
182
+ exc_list = str(e)
183
+ if isinstance(e, ExceptionGroup):
184
+ exc_list = "\n".join(map(str, e.exceptions))
185
+ exc_list = indent(exc_list, " ")
186
+ msg = f"An error occurred, please report this to the developer with your logs file:\n{exc_list}"
187
+ log_with_color(msg, "bold red", 50, show_in_stats=False, exc_info=e)
188
+
189
+ return wrapper
190
+
191
+
192
+ @ui_error_handling_wrapper
161
193
  async def director(manager: Manager) -> None:
162
194
  """Runs the program and handles the UI."""
163
195
  manager.path_manager.startup()
@@ -182,18 +214,9 @@ async def director(manager: Manager) -> None:
182
214
  log_spacer(20)
183
215
  log("Starting CDL...\n", 20)
184
216
 
185
- try:
186
- await runtime(manager)
187
- await post_runtime(manager)
188
- except* Exception as e:
189
- log_with_color(
190
- f"An error occurred, please report this to the developer: {e}",
191
- "bold red",
192
- 50,
193
- show_in_stats=False,
194
- exc_info=True,
195
- )
196
- sys.exit(1)
217
+ pre_runtime(manager)
218
+ await runtime(manager)
219
+ await post_runtime(manager)
197
220
 
198
221
  log_spacer(20)
199
222
  manager.progress_manager.print_stats(start_time)
@@ -204,7 +227,6 @@ async def director(manager: Manager) -> None:
204
227
  check_latest_pypi()
205
228
  log_spacer(20)
206
229
  log("Closing Program...", 20)
207
- await manager.close()
208
230
  log_with_color("Finished downloading. Enjoy :)", "green", 20, show_in_stats=False)
209
231
 
210
232
  await send_webhook_message(manager)
@@ -217,18 +239,14 @@ def main() -> None:
217
239
  asyncio.set_event_loop(loop)
218
240
  exit_code = 1
219
241
  manager = startup()
220
- with contextlib.suppress(RuntimeError):
242
+ with contextlib.suppress(Exception):
221
243
  try:
222
244
  asyncio.run(director(manager))
223
245
  exit_code = 0
224
246
  except KeyboardInterrupt:
225
247
  print_to_console("Trying to Exit ...")
226
- with contextlib.suppress(Exception):
227
- asyncio.run(manager.close())
228
- sys.exit(1)
229
- loop.close()
230
- sys.exit(0)
231
-
248
+ finally:
249
+ asyncio.run(manager.close())
232
250
  loop.close()
233
251
  sys.exit(exit_code)
234
252
 
@@ -8,18 +8,19 @@ from typing import TYPE_CHECKING
8
8
 
9
9
  import aiohttp
10
10
  import certifi
11
- from aiohttp import ClientResponse, ContentTypeError
11
+ from aiohttp import ClientResponse, ClientSession, ContentTypeError
12
12
  from aiolimiter import AsyncLimiter
13
+ from bs4 import BeautifulSoup
14
+ from yarl import URL
13
15
 
14
16
  from cyberdrop_dl.clients.download_client import DownloadClient
15
17
  from cyberdrop_dl.clients.errors import DDOSGuardError, DownloadError, ScrapeError
16
18
  from cyberdrop_dl.clients.scraper_client import ScraperClient
17
19
  from cyberdrop_dl.managers.leaky import LeakyBucket
18
20
  from cyberdrop_dl.utils.constants import CustomHTTPStatus
21
+ from cyberdrop_dl.utils.logger import log
19
22
 
20
23
  if TYPE_CHECKING:
21
- from yarl import URL
22
-
23
24
  from cyberdrop_dl.managers.manager import Manager
24
25
  from cyberdrop_dl.scraper.crawler import ScrapeItem
25
26
 
@@ -28,6 +29,18 @@ DOWNLOAD_ERROR_ETAGS = {
28
29
  "65b7753c-528a": "SC Scrape Image",
29
30
  }
30
31
 
32
+ DDOS_GUARD_CHALLENGE_TITLES = ["Just a moment...", "DDoS-Guard"]
33
+ DDOS_GUARD_CHALLENGE_SELECTORS = [
34
+ "#cf-challenge-running",
35
+ ".ray_id",
36
+ ".attack-box",
37
+ "#cf-please-wait",
38
+ "#challenge-spinner",
39
+ "#trk_jschal_js",
40
+ "#turnstile-wrapper",
41
+ ".lds-ring",
42
+ ]
43
+
31
44
 
32
45
  class ClientManager:
33
46
  """Creates a 'client' that can be referenced by scraping or download sessions."""
@@ -54,11 +67,6 @@ class ClientManager:
54
67
  if not manager.args_manager.proxy
55
68
  else manager.args_manager.proxy
56
69
  )
57
- self.flaresolverr = (
58
- manager.config_manager.global_settings_data["General"]["flaresolverr"]
59
- if not manager.args_manager.flaresolverr
60
- else manager.args_manager.flaresolverr
61
- )
62
70
 
63
71
  self.domain_rate_limits = {
64
72
  "bunkrr": AsyncLimiter(5, 1),
@@ -88,6 +96,7 @@ class ClientManager:
88
96
  self.scraper_session = ScraperClient(self)
89
97
  self.downloader_session = DownloadClient(manager, self)
90
98
  self._leaky_bucket = LeakyBucket(manager)
99
+ self.flaresolverr = Flaresolverr(self)
91
100
 
92
101
  """~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"""
93
102
 
@@ -105,8 +114,9 @@ class ClientManager:
105
114
 
106
115
  """~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"""
107
116
 
108
- @staticmethod
117
+ @classmethod
109
118
  async def check_http_status(
119
+ cls,
110
120
  response: ClientResponse,
111
121
  download: bool = False,
112
122
  origin: ScrapeItem | URL | None = None,
@@ -130,9 +140,13 @@ class ClientManager:
130
140
  if "data" in JSON_Resp and "error" in JSON_Resp["data"]:
131
141
  raise ScrapeError(JSON_Resp["status"], JSON_Resp["data"]["error"], origin=origin)
132
142
 
143
+ response_text = None
133
144
  with contextlib.suppress(UnicodeDecodeError):
134
145
  response_text = await response.text()
135
- if "<title>DDoS-Guard</title>" in response_text:
146
+
147
+ if response_text:
148
+ soup = BeautifulSoup(response_text, "html.parser")
149
+ if cls.check_ddos_guard(soup):
136
150
  raise DDOSGuardError(origin=origin)
137
151
 
138
152
  status = status if headers.get("Content-Type") else CustomHTTPStatus.IM_A_TEAPOT
@@ -147,3 +161,126 @@ class ClientManager:
147
161
 
148
162
  async def check_bucket(self, size: float) -> None:
149
163
  await self._leaky_bucket.acquire(size)
164
+
165
+ @staticmethod
166
+ def check_ddos_guard(soup: BeautifulSoup) -> bool:
167
+ if soup.title:
168
+ for title in DDOS_GUARD_CHALLENGE_TITLES:
169
+ challenge_found = title.casefold() == soup.title.string.casefold()
170
+ if challenge_found:
171
+ return True
172
+
173
+ for selector in DDOS_GUARD_CHALLENGE_SELECTORS:
174
+ challenge_found = soup.find(selector)
175
+ if challenge_found:
176
+ return True
177
+
178
+ return False
179
+
180
+ async def close(self) -> None:
181
+ await self.flaresolverr._destroy_session()
182
+
183
+
184
+ class Flaresolverr:
185
+ """Class that handles communication with flaresolverr."""
186
+
187
+ def __init__(self, client_manager: ClientManager) -> None:
188
+ self.client_manager = client_manager
189
+ self.flaresolverr_host = (
190
+ client_manager.manager.args_manager.flaresolverr
191
+ or client_manager.manager.config_manager.global_settings_data["General"]["flaresolverr"]
192
+ )
193
+ self.enabled = bool(self.flaresolverr_host)
194
+ if "http" not in self.flaresolverr_host:
195
+ self.flaresolverr_host = f"http://{self.flaresolverr_host}"
196
+ self.session_id = None
197
+ self.flaresolverr_host = URL(self.flaresolverr_host)
198
+
199
+ async def _request(
200
+ self,
201
+ command: str,
202
+ client_session: ClientSession,
203
+ origin: ScrapeItem | URL | None = None,
204
+ **kwargs,
205
+ ) -> dict:
206
+ """Base request function to call flaresolverr."""
207
+ if not self.enabled:
208
+ raise DDOSGuardError(message="FlareSolverr is not configured", origin=origin)
209
+
210
+ if not (self.session_id or kwargs.get("session")):
211
+ await self._create_session()
212
+
213
+ headers = client_session.headers.copy()
214
+ headers.update({"Content-Type": "application/json"})
215
+ for key, value in kwargs.items():
216
+ if isinstance(value, URL):
217
+ kwargs[key] = str(value)
218
+
219
+ data = {"cmd": command, "maxTimeout": 60000, "session": self.session_id} | kwargs
220
+
221
+ async with client_session.post(
222
+ self.flaresolverr_host / "v1",
223
+ headers=headers,
224
+ ssl=self.client_manager.ssl_context,
225
+ proxy=self.client_manager.proxy,
226
+ json=data,
227
+ ) as response:
228
+ json_obj: dict = await response.json() # type: ignore
229
+
230
+ return json_obj
231
+
232
+ async def _create_session(self) -> None:
233
+ """Creates a permanet flaresolverr session."""
234
+ session_id = "cyberdrop-dl"
235
+ async with ClientSession() as client_session:
236
+ flaresolverr_resp = await self._request("sessions.create", client_session, session=session_id)
237
+ status = flaresolverr_resp.get("status")
238
+ if status != "ok":
239
+ raise DDOSGuardError(message="Failed to create flaresolverr session")
240
+ self.session_id = session_id
241
+
242
+ async def _destroy_session(self):
243
+ if self.session_id:
244
+ async with ClientSession() as client_session:
245
+ await self._request("sessions.destroy", client_session, session=self.session_id)
246
+
247
+ async def get(
248
+ self,
249
+ url: URL,
250
+ client_session: ClientSession,
251
+ origin: ScrapeItem | URL | None = None,
252
+ update_cookies: bool = True,
253
+ ) -> tuple[BeautifulSoup, URL]:
254
+ """Returns the resolved URL from the given URL."""
255
+ flaresolverr_resp: dict = await self._request("request.get", client_session, origin, url=url)
256
+
257
+ status = flaresolverr_resp.get("status")
258
+ if status != "ok":
259
+ raise DDOSGuardError(message="Failed to resolve URL with flaresolverr", origin=origin)
260
+
261
+ solution: dict = flaresolverr_resp.get("solution")
262
+ if not solution:
263
+ raise DDOSGuardError(message="Invalid response from flaresolverr", origin=origin)
264
+ response = BeautifulSoup(solution.get("response"), "html.parser")
265
+ response_url = URL(solution.get("url"))
266
+ cookies: list[dict] = solution.get("cookies")
267
+ user_agent = client_session.headers.get("User-Agent").strip()
268
+ flaresolverr_user_agent = solution.get("userAgent").strip()
269
+ mismatch_msg = f"Config user_agent and flaresolverr user_agent do not match:\n Cyberdrop-DL: {user_agent}\n Flaresolverr: {flaresolverr_user_agent}"
270
+
271
+ if self.client_manager.check_ddos_guard(response):
272
+ if not update_cookies:
273
+ raise DDOSGuardError(message="Invalid response from flaresolverr", origin=origin)
274
+ if flaresolverr_user_agent != user_agent:
275
+ raise DDOSGuardError(message=mismatch_msg, origin=origin)
276
+
277
+ if update_cookies:
278
+ if flaresolverr_user_agent != user_agent:
279
+ log(f"{mismatch_msg}\nResponse was successful but cookies will not be valid", 30)
280
+
281
+ for cookie in cookies:
282
+ self.client_manager.cookies.update_cookies(
283
+ {cookie["name"]: cookie["value"]}, URL(f"https://{cookie['domain']}")
284
+ )
285
+
286
+ return response, response_url