StreamingCommunity 2.5.2__py3-none-any.whl → 2.5.5__py3-none-any.whl

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.

Potentially problematic release.


This version of StreamingCommunity might be problematic. Click here for more details.

Files changed (268) hide show
  1. StreamingCommunity/Api/Player/Helper/Vixcloud/js_parser.py +143 -143
  2. StreamingCommunity/Api/Player/Helper/Vixcloud/util.py +136 -136
  3. StreamingCommunity/Api/Player/ddl.py +89 -89
  4. StreamingCommunity/Api/Player/maxstream.py +151 -151
  5. StreamingCommunity/Api/Player/supervideo.py +193 -193
  6. StreamingCommunity/Api/Player/vixcloud.py +272 -272
  7. StreamingCommunity/Api/Site/1337xx/__init__.py +51 -50
  8. StreamingCommunity/Api/Site/1337xx/costant.py +14 -14
  9. StreamingCommunity/Api/Site/1337xx/site.py +87 -89
  10. StreamingCommunity/Api/Site/1337xx/title.py +63 -64
  11. StreamingCommunity/Api/Site/altadefinizionegratis/__init__.py +74 -50
  12. StreamingCommunity/Api/Site/altadefinizionegratis/costant.py +21 -19
  13. StreamingCommunity/Api/Site/altadefinizionegratis/film.py +81 -72
  14. StreamingCommunity/Api/Site/altadefinizionegratis/site.py +116 -94
  15. StreamingCommunity/Api/Site/animeunity/__init__.py +75 -50
  16. StreamingCommunity/Api/Site/animeunity/costant.py +21 -19
  17. StreamingCommunity/Api/Site/animeunity/film_serie.py +171 -134
  18. StreamingCommunity/Api/Site/animeunity/site.py +191 -174
  19. StreamingCommunity/Api/Site/animeunity/util/ScrapeSerie.py +97 -97
  20. StreamingCommunity/Api/Site/cb01new/__init__.py +51 -51
  21. StreamingCommunity/Api/Site/cb01new/costant.py +19 -19
  22. StreamingCommunity/Api/Site/cb01new/film.py +61 -71
  23. StreamingCommunity/Api/Site/cb01new/site.py +82 -82
  24. StreamingCommunity/Api/Site/ddlstreamitaly/__init__.py +55 -55
  25. StreamingCommunity/Api/Site/ddlstreamitaly/costant.py +20 -20
  26. StreamingCommunity/Api/Site/ddlstreamitaly/series.py +149 -145
  27. StreamingCommunity/Api/Site/ddlstreamitaly/site.py +98 -98
  28. StreamingCommunity/Api/Site/ddlstreamitaly/util/ScrapeSerie.py +84 -84
  29. StreamingCommunity/Api/Site/guardaserie/__init__.py +50 -50
  30. StreamingCommunity/Api/Site/guardaserie/costant.py +19 -19
  31. StreamingCommunity/Api/Site/guardaserie/series.py +199 -198
  32. StreamingCommunity/Api/Site/guardaserie/site.py +89 -89
  33. StreamingCommunity/Api/Site/guardaserie/util/ScrapeSerie.py +110 -110
  34. StreamingCommunity/Api/Site/ilcorsaronero/__init__.py +51 -51
  35. StreamingCommunity/Api/Site/ilcorsaronero/costant.py +18 -18
  36. StreamingCommunity/Api/Site/ilcorsaronero/site.py +71 -71
  37. StreamingCommunity/Api/Site/ilcorsaronero/title.py +44 -44
  38. StreamingCommunity/Api/Site/ilcorsaronero/util/ilCorsarScraper.py +149 -149
  39. StreamingCommunity/Api/Site/mostraguarda/__init__.py +48 -48
  40. StreamingCommunity/Api/Site/mostraguarda/costant.py +18 -18
  41. StreamingCommunity/Api/Site/mostraguarda/film.py +90 -101
  42. StreamingCommunity/Api/Site/streamingcommunity/__init__.py +79 -55
  43. StreamingCommunity/Api/Site/streamingcommunity/costant.py +21 -19
  44. StreamingCommunity/Api/Site/streamingcommunity/film.py +86 -75
  45. StreamingCommunity/Api/Site/streamingcommunity/series.py +259 -207
  46. StreamingCommunity/Api/Site/streamingcommunity/site.py +156 -142
  47. StreamingCommunity/Api/Site/streamingcommunity/util/ScrapeSerie.py +124 -124
  48. StreamingCommunity/Api/Template/Class/SearchType.py +101 -101
  49. StreamingCommunity/Api/Template/Util/__init__.py +4 -4
  50. StreamingCommunity/Api/Template/Util/get_domain.py +201 -201
  51. StreamingCommunity/Api/Template/Util/manage_ep.py +178 -178
  52. StreamingCommunity/Api/Template/Util/recall_search.py +37 -37
  53. StreamingCommunity/Api/Template/__init__.py +2 -2
  54. StreamingCommunity/Api/Template/site.py +87 -87
  55. StreamingCommunity/Lib/Downloader/HLS/downloader.py +529 -1008
  56. StreamingCommunity/Lib/Downloader/HLS/proxyes.py +110 -110
  57. StreamingCommunity/Lib/Downloader/HLS/segments.py +446 -573
  58. StreamingCommunity/Lib/Downloader/MP4/downloader.py +181 -155
  59. StreamingCommunity/Lib/Downloader/TOR/downloader.py +297 -295
  60. StreamingCommunity/Lib/Downloader/__init__.py +4 -4
  61. StreamingCommunity/Lib/FFmpeg/__init__.py +4 -4
  62. StreamingCommunity/Lib/FFmpeg/capture.py +170 -170
  63. StreamingCommunity/Lib/FFmpeg/command.py +264 -296
  64. StreamingCommunity/Lib/FFmpeg/util.py +248 -248
  65. StreamingCommunity/Lib/M3U8/__init__.py +5 -5
  66. StreamingCommunity/Lib/M3U8/decryptor.py +164 -164
  67. StreamingCommunity/Lib/M3U8/estimator.py +146 -228
  68. StreamingCommunity/Lib/M3U8/parser.py +666 -666
  69. StreamingCommunity/Lib/M3U8/url_fixer.py +57 -57
  70. StreamingCommunity/Lib/TMBD/__init__.py +1 -1
  71. StreamingCommunity/Lib/TMBD/obj_tmbd.py +39 -39
  72. StreamingCommunity/Lib/TMBD/tmdb.py +345 -345
  73. StreamingCommunity/TelegramHelp/__init__.py +0 -0
  74. StreamingCommunity/TelegramHelp/request_manager.py +82 -0
  75. StreamingCommunity/TelegramHelp/session.py +56 -0
  76. StreamingCommunity/TelegramHelp/telegram_bot.py +561 -0
  77. StreamingCommunity/Upload/update.py +75 -67
  78. StreamingCommunity/Upload/version.py +5 -5
  79. StreamingCommunity/Util/_jsonConfig.py +227 -228
  80. StreamingCommunity/Util/call_stack.py +42 -42
  81. StreamingCommunity/Util/color.py +20 -20
  82. StreamingCommunity/Util/console.py +12 -12
  83. StreamingCommunity/Util/ffmpeg_installer.py +342 -370
  84. StreamingCommunity/Util/headers.py +159 -159
  85. StreamingCommunity/Util/logger.py +61 -61
  86. StreamingCommunity/Util/message.py +36 -64
  87. StreamingCommunity/Util/os.py +500 -507
  88. StreamingCommunity/Util/table.py +271 -228
  89. StreamingCommunity/run.py +352 -245
  90. {StreamingCommunity-2.5.2.dist-info → StreamingCommunity-2.5.5.dist-info}/LICENSE +674 -674
  91. {StreamingCommunity-2.5.2.dist-info → StreamingCommunity-2.5.5.dist-info}/METADATA +601 -543
  92. StreamingCommunity-2.5.5.dist-info/RECORD +96 -0
  93. {StreamingCommunity-2.5.2.dist-info → StreamingCommunity-2.5.5.dist-info}/entry_points.txt +0 -1
  94. StreamingCommunity/Api/Player/Helper/Vixcloud/__pycache__/js_parser.cpython-313.pyc +0 -0
  95. StreamingCommunity/Api/Player/Helper/Vixcloud/__pycache__/js_parser.cpython-39.pyc +0 -0
  96. StreamingCommunity/Api/Player/Helper/Vixcloud/__pycache__/util.cpython-313.pyc +0 -0
  97. StreamingCommunity/Api/Player/Helper/Vixcloud/__pycache__/util.cpython-39.pyc +0 -0
  98. StreamingCommunity/Api/Player/__pycache__/ddl.cpython-313.pyc +0 -0
  99. StreamingCommunity/Api/Player/__pycache__/ddl.cpython-39.pyc +0 -0
  100. StreamingCommunity/Api/Player/__pycache__/maxstream.cpython-313.pyc +0 -0
  101. StreamingCommunity/Api/Player/__pycache__/maxstream.cpython-39.pyc +0 -0
  102. StreamingCommunity/Api/Player/__pycache__/supervideo.cpython-313.pyc +0 -0
  103. StreamingCommunity/Api/Player/__pycache__/supervideo.cpython-39.pyc +0 -0
  104. StreamingCommunity/Api/Player/__pycache__/vixcloud.cpython-313.pyc +0 -0
  105. StreamingCommunity/Api/Player/__pycache__/vixcloud.cpython-39.pyc +0 -0
  106. StreamingCommunity/Api/Site/1337xx/__pycache__/__init__.cpython-313.pyc +0 -0
  107. StreamingCommunity/Api/Site/1337xx/__pycache__/__init__.cpython-39.pyc +0 -0
  108. StreamingCommunity/Api/Site/1337xx/__pycache__/costant.cpython-313.pyc +0 -0
  109. StreamingCommunity/Api/Site/1337xx/__pycache__/costant.cpython-39.pyc +0 -0
  110. StreamingCommunity/Api/Site/1337xx/__pycache__/site.cpython-313.pyc +0 -0
  111. StreamingCommunity/Api/Site/1337xx/__pycache__/site.cpython-39.pyc +0 -0
  112. StreamingCommunity/Api/Site/1337xx/__pycache__/title.cpython-313.pyc +0 -0
  113. StreamingCommunity/Api/Site/1337xx/__pycache__/title.cpython-39.pyc +0 -0
  114. StreamingCommunity/Api/Site/altadefinizionegratis/__pycache__/__init__.cpython-313.pyc +0 -0
  115. StreamingCommunity/Api/Site/altadefinizionegratis/__pycache__/__init__.cpython-39.pyc +0 -0
  116. StreamingCommunity/Api/Site/altadefinizionegratis/__pycache__/costant.cpython-313.pyc +0 -0
  117. StreamingCommunity/Api/Site/altadefinizionegratis/__pycache__/costant.cpython-39.pyc +0 -0
  118. StreamingCommunity/Api/Site/altadefinizionegratis/__pycache__/film.cpython-313.pyc +0 -0
  119. StreamingCommunity/Api/Site/altadefinizionegratis/__pycache__/film.cpython-39.pyc +0 -0
  120. StreamingCommunity/Api/Site/altadefinizionegratis/__pycache__/site.cpython-313.pyc +0 -0
  121. StreamingCommunity/Api/Site/altadefinizionegratis/__pycache__/site.cpython-39.pyc +0 -0
  122. StreamingCommunity/Api/Site/animeunity/__pycache__/__init__.cpython-313.pyc +0 -0
  123. StreamingCommunity/Api/Site/animeunity/__pycache__/__init__.cpython-39.pyc +0 -0
  124. StreamingCommunity/Api/Site/animeunity/__pycache__/costant.cpython-313.pyc +0 -0
  125. StreamingCommunity/Api/Site/animeunity/__pycache__/costant.cpython-39.pyc +0 -0
  126. StreamingCommunity/Api/Site/animeunity/__pycache__/film_serie.cpython-313.pyc +0 -0
  127. StreamingCommunity/Api/Site/animeunity/__pycache__/film_serie.cpython-39.pyc +0 -0
  128. StreamingCommunity/Api/Site/animeunity/__pycache__/site.cpython-313.pyc +0 -0
  129. StreamingCommunity/Api/Site/animeunity/__pycache__/site.cpython-39.pyc +0 -0
  130. StreamingCommunity/Api/Site/animeunity/util/__pycache__/ScrapeSerie.cpython-313.pyc +0 -0
  131. StreamingCommunity/Api/Site/animeunity/util/__pycache__/ScrapeSerie.cpython-39.pyc +0 -0
  132. StreamingCommunity/Api/Site/cb01new/__pycache__/__init__.cpython-313.pyc +0 -0
  133. StreamingCommunity/Api/Site/cb01new/__pycache__/__init__.cpython-39.pyc +0 -0
  134. StreamingCommunity/Api/Site/cb01new/__pycache__/costant.cpython-313.pyc +0 -0
  135. StreamingCommunity/Api/Site/cb01new/__pycache__/costant.cpython-39.pyc +0 -0
  136. StreamingCommunity/Api/Site/cb01new/__pycache__/film.cpython-313.pyc +0 -0
  137. StreamingCommunity/Api/Site/cb01new/__pycache__/film.cpython-39.pyc +0 -0
  138. StreamingCommunity/Api/Site/cb01new/__pycache__/site.cpython-313.pyc +0 -0
  139. StreamingCommunity/Api/Site/cb01new/__pycache__/site.cpython-39.pyc +0 -0
  140. StreamingCommunity/Api/Site/ddlstreamitaly/__pycache__/__init__.cpython-313.pyc +0 -0
  141. StreamingCommunity/Api/Site/ddlstreamitaly/__pycache__/__init__.cpython-39.pyc +0 -0
  142. StreamingCommunity/Api/Site/ddlstreamitaly/__pycache__/costant.cpython-313.pyc +0 -0
  143. StreamingCommunity/Api/Site/ddlstreamitaly/__pycache__/costant.cpython-39.pyc +0 -0
  144. StreamingCommunity/Api/Site/ddlstreamitaly/__pycache__/series.cpython-313.pyc +0 -0
  145. StreamingCommunity/Api/Site/ddlstreamitaly/__pycache__/series.cpython-39.pyc +0 -0
  146. StreamingCommunity/Api/Site/ddlstreamitaly/__pycache__/site.cpython-313.pyc +0 -0
  147. StreamingCommunity/Api/Site/ddlstreamitaly/__pycache__/site.cpython-39.pyc +0 -0
  148. StreamingCommunity/Api/Site/ddlstreamitaly/util/__pycache__/ScrapeSerie.cpython-313.pyc +0 -0
  149. StreamingCommunity/Api/Site/ddlstreamitaly/util/__pycache__/ScrapeSerie.cpython-39.pyc +0 -0
  150. StreamingCommunity/Api/Site/guardaserie/__pycache__/__init__.cpython-313.pyc +0 -0
  151. StreamingCommunity/Api/Site/guardaserie/__pycache__/__init__.cpython-39.pyc +0 -0
  152. StreamingCommunity/Api/Site/guardaserie/__pycache__/costant.cpython-313.pyc +0 -0
  153. StreamingCommunity/Api/Site/guardaserie/__pycache__/costant.cpython-39.pyc +0 -0
  154. StreamingCommunity/Api/Site/guardaserie/__pycache__/series.cpython-313.pyc +0 -0
  155. StreamingCommunity/Api/Site/guardaserie/__pycache__/series.cpython-39.pyc +0 -0
  156. StreamingCommunity/Api/Site/guardaserie/__pycache__/site.cpython-313.pyc +0 -0
  157. StreamingCommunity/Api/Site/guardaserie/__pycache__/site.cpython-39.pyc +0 -0
  158. StreamingCommunity/Api/Site/guardaserie/util/__pycache__/ScrapeSerie.cpython-313.pyc +0 -0
  159. StreamingCommunity/Api/Site/guardaserie/util/__pycache__/ScrapeSerie.cpython-39.pyc +0 -0
  160. StreamingCommunity/Api/Site/ilcorsaronero/__pycache__/__init__.cpython-313.pyc +0 -0
  161. StreamingCommunity/Api/Site/ilcorsaronero/__pycache__/__init__.cpython-39.pyc +0 -0
  162. StreamingCommunity/Api/Site/ilcorsaronero/__pycache__/costant.cpython-313.pyc +0 -0
  163. StreamingCommunity/Api/Site/ilcorsaronero/__pycache__/costant.cpython-39.pyc +0 -0
  164. StreamingCommunity/Api/Site/ilcorsaronero/__pycache__/site.cpython-313.pyc +0 -0
  165. StreamingCommunity/Api/Site/ilcorsaronero/__pycache__/site.cpython-39.pyc +0 -0
  166. StreamingCommunity/Api/Site/ilcorsaronero/__pycache__/title.cpython-313.pyc +0 -0
  167. StreamingCommunity/Api/Site/ilcorsaronero/__pycache__/title.cpython-39.pyc +0 -0
  168. StreamingCommunity/Api/Site/ilcorsaronero/util/__pycache__/ilCorsarScraper.cpython-313.pyc +0 -0
  169. StreamingCommunity/Api/Site/ilcorsaronero/util/__pycache__/ilCorsarScraper.cpython-39.pyc +0 -0
  170. StreamingCommunity/Api/Site/mostraguarda/__pycache__/__init__.cpython-313.pyc +0 -0
  171. StreamingCommunity/Api/Site/mostraguarda/__pycache__/__init__.cpython-39.pyc +0 -0
  172. StreamingCommunity/Api/Site/mostraguarda/__pycache__/costant.cpython-313.pyc +0 -0
  173. StreamingCommunity/Api/Site/mostraguarda/__pycache__/costant.cpython-39.pyc +0 -0
  174. StreamingCommunity/Api/Site/mostraguarda/__pycache__/film.cpython-313.pyc +0 -0
  175. StreamingCommunity/Api/Site/mostraguarda/__pycache__/film.cpython-39.pyc +0 -0
  176. StreamingCommunity/Api/Site/streamingcommunity/__pycache__/__init__.cpython-313.pyc +0 -0
  177. StreamingCommunity/Api/Site/streamingcommunity/__pycache__/__init__.cpython-39.pyc +0 -0
  178. StreamingCommunity/Api/Site/streamingcommunity/__pycache__/costant.cpython-313.pyc +0 -0
  179. StreamingCommunity/Api/Site/streamingcommunity/__pycache__/costant.cpython-39.pyc +0 -0
  180. StreamingCommunity/Api/Site/streamingcommunity/__pycache__/film.cpython-313.pyc +0 -0
  181. StreamingCommunity/Api/Site/streamingcommunity/__pycache__/film.cpython-39.pyc +0 -0
  182. StreamingCommunity/Api/Site/streamingcommunity/__pycache__/series.cpython-313.pyc +0 -0
  183. StreamingCommunity/Api/Site/streamingcommunity/__pycache__/series.cpython-39.pyc +0 -0
  184. StreamingCommunity/Api/Site/streamingcommunity/__pycache__/site.cpython-313.pyc +0 -0
  185. StreamingCommunity/Api/Site/streamingcommunity/__pycache__/site.cpython-39.pyc +0 -0
  186. StreamingCommunity/Api/Site/streamingcommunity/util/__pycache__/ScrapeSerie.cpython-313.pyc +0 -0
  187. StreamingCommunity/Api/Site/streamingcommunity/util/__pycache__/ScrapeSerie.cpython-39.pyc +0 -0
  188. StreamingCommunity/Api/Template/Class/__pycache__/SearchType.cpython-313.pyc +0 -0
  189. StreamingCommunity/Api/Template/Class/__pycache__/SearchType.cpython-39.pyc +0 -0
  190. StreamingCommunity/Api/Template/Util/__pycache__/__init__.cpython-313.pyc +0 -0
  191. StreamingCommunity/Api/Template/Util/__pycache__/__init__.cpython-39.pyc +0 -0
  192. StreamingCommunity/Api/Template/Util/__pycache__/get_domain.cpython-313.pyc +0 -0
  193. StreamingCommunity/Api/Template/Util/__pycache__/get_domain.cpython-39.pyc +0 -0
  194. StreamingCommunity/Api/Template/Util/__pycache__/manage_ep.cpython-313.pyc +0 -0
  195. StreamingCommunity/Api/Template/Util/__pycache__/manage_ep.cpython-39.pyc +0 -0
  196. StreamingCommunity/Api/Template/Util/__pycache__/recall_search.cpython-313.pyc +0 -0
  197. StreamingCommunity/Api/Template/Util/__pycache__/recall_search.cpython-39.pyc +0 -0
  198. StreamingCommunity/Api/Template/__pycache__/__init__.cpython-313.pyc +0 -0
  199. StreamingCommunity/Api/Template/__pycache__/__init__.cpython-39.pyc +0 -0
  200. StreamingCommunity/Api/Template/__pycache__/site.cpython-313.pyc +0 -0
  201. StreamingCommunity/Api/Template/__pycache__/site.cpython-39.pyc +0 -0
  202. StreamingCommunity/Lib/Downloader/HLS/__pycache__/downloader.cpython-313.pyc +0 -0
  203. StreamingCommunity/Lib/Downloader/HLS/__pycache__/downloader.cpython-39.pyc +0 -0
  204. StreamingCommunity/Lib/Downloader/HLS/__pycache__/proxyes.cpython-313.pyc +0 -0
  205. StreamingCommunity/Lib/Downloader/HLS/__pycache__/proxyes.cpython-39.pyc +0 -0
  206. StreamingCommunity/Lib/Downloader/HLS/__pycache__/segments.cpython-313.pyc +0 -0
  207. StreamingCommunity/Lib/Downloader/HLS/__pycache__/segments.cpython-39.pyc +0 -0
  208. StreamingCommunity/Lib/Downloader/MP4/__pycache__/downloader.cpython-313.pyc +0 -0
  209. StreamingCommunity/Lib/Downloader/MP4/__pycache__/downloader.cpython-39.pyc +0 -0
  210. StreamingCommunity/Lib/Downloader/TOR/__pycache__/downloader.cpython-313.pyc +0 -0
  211. StreamingCommunity/Lib/Downloader/TOR/__pycache__/downloader.cpython-39.pyc +0 -0
  212. StreamingCommunity/Lib/Downloader/__pycache__/__init__.cpython-313.pyc +0 -0
  213. StreamingCommunity/Lib/Downloader/__pycache__/__init__.cpython-39.pyc +0 -0
  214. StreamingCommunity/Lib/FFmpeg/__pycache__/__init__.cpython-313.pyc +0 -0
  215. StreamingCommunity/Lib/FFmpeg/__pycache__/__init__.cpython-39.pyc +0 -0
  216. StreamingCommunity/Lib/FFmpeg/__pycache__/capture.cpython-313.pyc +0 -0
  217. StreamingCommunity/Lib/FFmpeg/__pycache__/capture.cpython-39.pyc +0 -0
  218. StreamingCommunity/Lib/FFmpeg/__pycache__/command.cpython-313.pyc +0 -0
  219. StreamingCommunity/Lib/FFmpeg/__pycache__/command.cpython-39.pyc +0 -0
  220. StreamingCommunity/Lib/FFmpeg/__pycache__/util.cpython-313.pyc +0 -0
  221. StreamingCommunity/Lib/FFmpeg/__pycache__/util.cpython-39.pyc +0 -0
  222. StreamingCommunity/Lib/M3U8/__pycache__/__init__.cpython-313.pyc +0 -0
  223. StreamingCommunity/Lib/M3U8/__pycache__/__init__.cpython-39.pyc +0 -0
  224. StreamingCommunity/Lib/M3U8/__pycache__/decryptor.cpython-313.pyc +0 -0
  225. StreamingCommunity/Lib/M3U8/__pycache__/decryptor.cpython-39.pyc +0 -0
  226. StreamingCommunity/Lib/M3U8/__pycache__/estimator.cpython-313.pyc +0 -0
  227. StreamingCommunity/Lib/M3U8/__pycache__/estimator.cpython-39.pyc +0 -0
  228. StreamingCommunity/Lib/M3U8/__pycache__/parser.cpython-313.pyc +0 -0
  229. StreamingCommunity/Lib/M3U8/__pycache__/parser.cpython-39.pyc +0 -0
  230. StreamingCommunity/Lib/M3U8/__pycache__/url_fixer.cpython-313.pyc +0 -0
  231. StreamingCommunity/Lib/M3U8/__pycache__/url_fixer.cpython-39.pyc +0 -0
  232. StreamingCommunity/Lib/TMBD/__pycache__/__init__.cpython-313.pyc +0 -0
  233. StreamingCommunity/Lib/TMBD/__pycache__/__init__.cpython-39.pyc +0 -0
  234. StreamingCommunity/Lib/TMBD/__pycache__/obj_tmbd.cpython-313.pyc +0 -0
  235. StreamingCommunity/Lib/TMBD/__pycache__/obj_tmbd.cpython-39.pyc +0 -0
  236. StreamingCommunity/Lib/TMBD/__pycache__/tmdb.cpython-313.pyc +0 -0
  237. StreamingCommunity/Lib/TMBD/__pycache__/tmdb.cpython-39.pyc +0 -0
  238. StreamingCommunity/Upload/__pycache__/update.cpython-313.pyc +0 -0
  239. StreamingCommunity/Upload/__pycache__/update.cpython-39.pyc +0 -0
  240. StreamingCommunity/Upload/__pycache__/version.cpython-313.pyc +0 -0
  241. StreamingCommunity/Upload/__pycache__/version.cpython-39.pyc +0 -0
  242. StreamingCommunity/Util/__pycache__/_jsonConfig.cpython-313.pyc +0 -0
  243. StreamingCommunity/Util/__pycache__/_jsonConfig.cpython-39.pyc +0 -0
  244. StreamingCommunity/Util/__pycache__/call_stack.cpython-313.pyc +0 -0
  245. StreamingCommunity/Util/__pycache__/call_stack.cpython-39.pyc +0 -0
  246. StreamingCommunity/Util/__pycache__/color.cpython-313.pyc +0 -0
  247. StreamingCommunity/Util/__pycache__/color.cpython-39.pyc +0 -0
  248. StreamingCommunity/Util/__pycache__/console.cpython-313.pyc +0 -0
  249. StreamingCommunity/Util/__pycache__/console.cpython-39.pyc +0 -0
  250. StreamingCommunity/Util/__pycache__/ffmpeg_installer.cpython-313.pyc +0 -0
  251. StreamingCommunity/Util/__pycache__/ffmpeg_installer.cpython-39.pyc +0 -0
  252. StreamingCommunity/Util/__pycache__/headers.cpython-313.pyc +0 -0
  253. StreamingCommunity/Util/__pycache__/headers.cpython-39.pyc +0 -0
  254. StreamingCommunity/Util/__pycache__/logger.cpython-313.pyc +0 -0
  255. StreamingCommunity/Util/__pycache__/logger.cpython-39.pyc +0 -0
  256. StreamingCommunity/Util/__pycache__/message.cpython-313.pyc +0 -0
  257. StreamingCommunity/Util/__pycache__/message.cpython-39.pyc +0 -0
  258. StreamingCommunity/Util/__pycache__/os.cpython-313.pyc +0 -0
  259. StreamingCommunity/Util/__pycache__/os.cpython-39.pyc +0 -0
  260. StreamingCommunity/Util/__pycache__/table.cpython-313.pyc +0 -0
  261. StreamingCommunity/Util/__pycache__/table.cpython-39.pyc +0 -0
  262. StreamingCommunity/__pycache__/__init__.cpython-313.pyc +0 -0
  263. StreamingCommunity/__pycache__/__init__.cpython-39.pyc +0 -0
  264. StreamingCommunity/__pycache__/run.cpython-313.pyc +0 -0
  265. StreamingCommunity/__pycache__/run.cpython-39.pyc +0 -0
  266. StreamingCommunity-2.5.2.dist-info/RECORD +0 -264
  267. {StreamingCommunity-2.5.2.dist-info → StreamingCommunity-2.5.5.dist-info}/WHEEL +0 -0
  268. {StreamingCommunity-2.5.2.dist-info → StreamingCommunity-2.5.5.dist-info}/top_level.txt +0 -0
@@ -1,296 +1,298 @@
1
- # 23.06.24
2
-
3
- import os
4
- import re
5
- import sys
6
- import time
7
- import shutil
8
- import psutil
9
- import logging
10
-
11
-
12
- # Internal utilities
13
- from StreamingCommunity.Util.color import Colors
14
- from StreamingCommunity.Util.os import internet_manager
15
- from StreamingCommunity.Util.console import console
16
- from StreamingCommunity.Util._jsonConfig import config_manager
17
-
18
-
19
- # External libraries
20
- from tqdm import tqdm
21
- from qbittorrent import Client
22
-
23
-
24
- # Tor config
25
- HOST = str(config_manager.get_dict('DEFAULT', 'config_qbit_tor')['host'])
26
- PORT = str(config_manager.get_dict('DEFAULT', 'config_qbit_tor')['port'])
27
- USERNAME = str(config_manager.get_dict('DEFAULT', 'config_qbit_tor')['user'])
28
- PASSWORD = str(config_manager.get_dict('DEFAULT', 'config_qbit_tor')['pass'])
29
-
30
- # Config
31
- TQDM_USE_LARGE_BAR = config_manager.get_int('M3U8_DOWNLOAD', 'tqdm_use_large_bar')
32
- REQUEST_TIMEOUT = config_manager.get_float('REQUESTS', 'timeout')
33
-
34
-
35
-
36
- class TOR_downloader:
37
- def __init__(self):
38
- """
39
- Initializes the TorrentManager instance.
40
-
41
- Parameters:
42
- - host (str): IP address or hostname of the qBittorrent Web UI.
43
- - port (int): Port number of the qBittorrent Web UI.
44
- - username (str): Username for logging into qBittorrent.
45
- - password (str): Password for logging into qBittorrent.
46
- """
47
- try:
48
- console.print(f"[cyan]Connect to: [green]{HOST}:{PORT}")
49
- self.qb = Client(f'http://{HOST}:{PORT}/')
50
- except:
51
- logging.error("Start qbitorrent first.")
52
- sys.exit(0)
53
-
54
- self.username = USERNAME
55
- self.password = PASSWORD
56
- self.latest_torrent_hash = None
57
- self.output_file = None
58
- self.file_name = None
59
-
60
- self.login()
61
-
62
- def login(self):
63
- """
64
- Logs into the qBittorrent Web UI.
65
- """
66
- try:
67
- self.qb.login(self.username, self.password)
68
- self.logged_in = True
69
- logging.info("Successfully logged in to qBittorrent.")
70
-
71
- except Exception as e:
72
- logging.error(f"Failed to log in: {str(e)}")
73
- self.logged_in = False
74
-
75
- def delete_magnet(self, torrent_info):
76
-
77
- if (int(torrent_info.get('dl_speed')) == 0 and
78
- int(torrent_info.get('peers')) == 0 and
79
- int(torrent_info.get('seeds')) == 0):
80
-
81
- # Elimina il torrent appena aggiunto
82
- console.print(f"[bold red]⚠️ Torrent non scaricabile. Rimozione in corso...[/bold red]")
83
-
84
- try:
85
- # Rimuovi il torrent
86
- self.qb.delete_permanently(torrent_info['hash'])
87
-
88
- except Exception as delete_error:
89
- logging.error(f"Errore durante la rimozione del torrent: {delete_error}")
90
-
91
- # Resetta l'ultimo hash
92
- self.latest_torrent_hash = None
93
-
94
- def add_magnet_link(self, magnet_link):
95
- """
96
- Aggiunge un magnet link e recupera le informazioni dettagliate.
97
-
98
- Args:
99
- magnet_link (str): Magnet link da aggiungere
100
-
101
- Returns:
102
- dict: Informazioni del torrent aggiunto, o None se fallisce
103
- """
104
-
105
- # Estrai l'hash dal magnet link
106
- magnet_hash_match = re.search(r'urn:btih:([0-9a-fA-F]+)', magnet_link)
107
-
108
- if not magnet_hash_match:
109
- raise ValueError("Hash del magnet link non trovato")
110
-
111
- magnet_hash = magnet_hash_match.group(1).lower()
112
-
113
- # Estrai il nome del file dal magnet link (se presente)
114
- name_match = re.search(r'dn=([^&]+)', magnet_link)
115
- torrent_name = name_match.group(1).replace('+', ' ') if name_match else "Nome non disponibile"
116
-
117
- # Salva il timestamp prima di aggiungere il torrent
118
- before_add_time = time.time()
119
-
120
- # Aggiungi il magnet link
121
- console.print(f"[cyan]Aggiunta magnet link[/cyan]: [red]{magnet_link}")
122
- self.qb.download_from_link(magnet_link)
123
-
124
- # Aspetta un attimo per essere sicuri che il torrent sia stato aggiunto
125
- time.sleep(1)
126
-
127
- # Cerca il torrent
128
- torrents = self.qb.torrents()
129
- matching_torrents = [
130
- t for t in torrents
131
- if (t['hash'].lower() == magnet_hash) or (t.get('added_on', 0) > before_add_time)
132
- ]
133
-
134
- if not matching_torrents:
135
- raise ValueError("Nessun torrent corrispondente trovato")
136
-
137
- # Prendi il primo torrent corrispondente
138
- torrent_info = matching_torrents[0]
139
-
140
- # Formatta e stampa le informazioni
141
- console.print("\n[bold green]🔗 Dettagli Torrent Aggiunto:[/bold green]")
142
- console.print(f"[yellow]Name:[/yellow] {torrent_info.get('name', torrent_name)}")
143
- console.print(f"[yellow]Hash:[/yellow] {torrent_info['hash']}")
144
- print()
145
-
146
- # Salva l'hash per usi successivi e il path
147
- self.latest_torrent_hash = torrent_info['hash']
148
- self.output_file = torrent_info['content_path']
149
- self.file_name = torrent_info['name']
150
-
151
- # Controlla che sia possibile il download
152
- time.sleep(5)
153
- self.delete_magnet(self.qb.get_torrent(self.latest_torrent_hash))
154
-
155
- return torrent_info
156
-
157
- def start_download(self):
158
- """
159
- Starts downloading the latest added torrent and monitors progress.
160
- """
161
- if self.latest_torrent_hash is not None:
162
- try:
163
-
164
- # Custom bar for mobile and pc
165
- if TQDM_USE_LARGE_BAR:
166
- bar_format = (
167
- f"{Colors.YELLOW}[TOR] {Colors.WHITE}({Colors.CYAN}video{Colors.WHITE}): "
168
- f"{Colors.RED}{{percentage:.2f}}% {Colors.MAGENTA}{{bar}} {Colors.WHITE}[ "
169
- f"{Colors.YELLOW}{{elapsed}} {Colors.WHITE}< {Colors.CYAN}{{remaining}}{{postfix}} {Colors.WHITE}]"
170
- )
171
- else:
172
- bar_format = (
173
- f"{Colors.YELLOW}Proc{Colors.WHITE}: "
174
- f"{Colors.RED}{{percentage:.2f}}% {Colors.WHITE}| "
175
- f"{Colors.CYAN}{{remaining}}{{postfix}} {Colors.WHITE}]"
176
- )
177
-
178
- progress_bar = tqdm(
179
- total=100,
180
- ascii='░▒█',
181
- bar_format=bar_format,
182
- unit_scale=True,
183
- unit_divisor=1024,
184
- mininterval=0.05
185
- )
186
-
187
- with progress_bar as pbar:
188
- while True:
189
-
190
- # Get variable from qtorrent
191
- torrent_info = self.qb.get_torrent(self.latest_torrent_hash)
192
- self.save_path = torrent_info['save_path']
193
- self.torrent_name = torrent_info['name']
194
-
195
- # Fetch important variable
196
- pieces_have = torrent_info['pieces_have']
197
- pieces_num = torrent_info['pieces_num']
198
- progress = (pieces_have / pieces_num) * 100 if pieces_num else 0
199
- pbar.n = progress
200
-
201
- download_speed = torrent_info['dl_speed']
202
- total_size = torrent_info['total_size']
203
- downloaded_size = torrent_info['total_downloaded']
204
-
205
- # Format variable
206
- downloaded_size_str = internet_manager.format_file_size(downloaded_size)
207
- downloaded_size = downloaded_size_str.split(' ')[0]
208
-
209
- total_size_str = internet_manager.format_file_size(total_size)
210
- total_size = total_size_str.split(' ')[0]
211
- total_size_unit = total_size_str.split(' ')[1]
212
-
213
- average_internet_str = internet_manager.format_transfer_speed(download_speed)
214
- average_internet = average_internet_str.split(' ')[0]
215
- average_internet_unit = average_internet_str.split(' ')[1]
216
-
217
- # Update the progress bar's postfix
218
- if TQDM_USE_LARGE_BAR:
219
- pbar.set_postfix_str(
220
- f"{Colors.WHITE}[ {Colors.GREEN}{downloaded_size} {Colors.WHITE}< {Colors.GREEN}{total_size} {Colors.RED}{total_size_unit} "
221
- f"{Colors.WHITE}| {Colors.CYAN}{average_internet} {Colors.RED}{average_internet_unit}"
222
- )
223
- else:
224
- pbar.set_postfix_str(
225
- f"{Colors.WHITE}[ {Colors.GREEN}{downloaded_size}{Colors.RED} {total_size} "
226
- f"{Colors.WHITE}| {Colors.CYAN}{average_internet} {Colors.RED}{average_internet_unit}"
227
- )
228
-
229
- pbar.refresh()
230
- time.sleep(0.2)
231
-
232
- # Break at the end
233
- if int(progress) == 100:
234
- break
235
-
236
- except KeyboardInterrupt:
237
- logging.info("Download process interrupted.")
238
-
239
- def is_file_in_use(self, file_path: str) -> bool:
240
- """Check if a file is in use by any process."""
241
- for proc in psutil.process_iter(['open_files']):
242
- try:
243
- if any(file_path == f.path for f in proc.info['open_files'] or []):
244
- return True
245
- except (psutil.NoSuchProcess, psutil.AccessDenied):
246
- continue
247
-
248
- return False
249
-
250
- def move_downloaded_files(self, destination: str):
251
- """
252
- Moves downloaded files of the latest torrent to another location.
253
-
254
- Parameters:
255
- - destination (str): Destination directory to move files.
256
-
257
- Returns:
258
- - bool: True if files are moved successfully, False otherwise.
259
- """
260
- console.print(f"[cyan]Destination folder: [red]{destination}")
261
-
262
- try:
263
-
264
- # Ensure the file is not in use
265
- timeout = 3
266
- elapsed = 0
267
- while self.is_file_in_use(self.output_file) and elapsed < timeout:
268
- time.sleep(1)
269
- elapsed += 1
270
-
271
- if elapsed == timeout:
272
- raise Exception(f"File '{self.output_file}' is in use and could not be moved.")
273
-
274
- # Ensure destination directory exists
275
- os.makedirs(destination, exist_ok=True)
276
-
277
- # Perform the move operation
278
- try:
279
- shutil.move(self.output_file, destination)
280
-
281
- except OSError as e:
282
- if e.errno == 17: # Cross-disk move error
283
- # Perform copy and delete manually
284
- shutil.copy2(self.output_file, destination)
285
- os.remove(self.output_file)
286
- else:
287
- raise
288
-
289
- # Delete the torrent data
290
- time.sleep(5)
291
- self.qb.delete_permanently(self.qb.torrents()[-1]['hash'])
292
- return True
293
-
294
- except Exception as e:
295
- print(f"Error moving file: {e}")
1
+ # 23.06.24
2
+
3
+ import os
4
+ import re
5
+ import sys
6
+ import time
7
+ import shutil
8
+ import psutil
9
+ import logging
10
+
11
+
12
+ # Internal utilities
13
+ from StreamingCommunity.Util.color import Colors
14
+ from StreamingCommunity.Util.os import internet_manager
15
+ from StreamingCommunity.Util.console import console
16
+ from StreamingCommunity.Util._jsonConfig import config_manager
17
+
18
+
19
+ # External libraries
20
+ from tqdm import tqdm
21
+ from qbittorrent import Client
22
+
23
+
24
+ # Tor config
25
+ HOST = str(config_manager.get_dict('DEFAULT', 'config_qbit_tor')['host'])
26
+ PORT = str(config_manager.get_dict('DEFAULT', 'config_qbit_tor')['port'])
27
+ USERNAME = str(config_manager.get_dict('DEFAULT', 'config_qbit_tor')['user'])
28
+ PASSWORD = str(config_manager.get_dict('DEFAULT', 'config_qbit_tor')['pass'])
29
+
30
+
31
+ # Config
32
+ USE_LARGE_BAR = not ("android" in sys.platform or "ios" in sys.platform)
33
+ REQUEST_TIMEOUT = config_manager.get_float('REQUESTS', 'timeout')
34
+
35
+
36
+
37
+ class TOR_downloader:
38
+ def __init__(self):
39
+ """
40
+ Initializes the TorrentManager instance.
41
+
42
+ Parameters:
43
+ - host (str): IP address or hostname of the qBittorrent Web UI.
44
+ - port (int): Port number of the qBittorrent Web UI.
45
+ - username (str): Username for logging into qBittorrent.
46
+ - password (str): Password for logging into qBittorrent.
47
+ """
48
+ try:
49
+ console.print(f"[cyan]Connect to: [green]{HOST}:{PORT}")
50
+ self.qb = Client(f'http://{HOST}:{PORT}/')
51
+ except:
52
+ logging.error("Start qbitorrent first.")
53
+ sys.exit(0)
54
+
55
+ self.username = USERNAME
56
+ self.password = PASSWORD
57
+ self.latest_torrent_hash = None
58
+ self.output_file = None
59
+ self.file_name = None
60
+
61
+ self.login()
62
+
63
+ def login(self):
64
+ """
65
+ Logs into the qBittorrent Web UI.
66
+ """
67
+ try:
68
+ self.qb.login(self.username, self.password)
69
+ self.logged_in = True
70
+ logging.info("Successfully logged in to qBittorrent.")
71
+
72
+ except Exception as e:
73
+ logging.error(f"Failed to log in: {str(e)}")
74
+ self.logged_in = False
75
+
76
+ def delete_magnet(self, torrent_info):
77
+
78
+ if (int(torrent_info.get('dl_speed')) == 0 and
79
+ int(torrent_info.get('peers')) == 0 and
80
+ int(torrent_info.get('seeds')) == 0):
81
+
82
+ # Elimina il torrent appena aggiunto
83
+ console.print(f"[bold red]⚠️ Torrent non scaricabile. Rimozione in corso...[/bold red]")
84
+
85
+ try:
86
+ # Rimuovi il torrent
87
+ self.qb.delete_permanently(torrent_info['hash'])
88
+
89
+ except Exception as delete_error:
90
+ logging.error(f"Errore durante la rimozione del torrent: {delete_error}")
91
+
92
+ # Resetta l'ultimo hash
93
+ self.latest_torrent_hash = None
94
+
95
+ def add_magnet_link(self, magnet_link):
96
+ """
97
+ Aggiunge un magnet link e recupera le informazioni dettagliate.
98
+
99
+ Args:
100
+ magnet_link (str): Magnet link da aggiungere
101
+
102
+ Returns:
103
+ dict: Informazioni del torrent aggiunto, o None se fallisce
104
+ """
105
+
106
+ # Estrai l'hash dal magnet link
107
+ magnet_hash_match = re.search(r'urn:btih:([0-9a-fA-F]+)', magnet_link)
108
+
109
+ if not magnet_hash_match:
110
+ raise ValueError("Hash del magnet link non trovato")
111
+
112
+ magnet_hash = magnet_hash_match.group(1).lower()
113
+
114
+ # Estrai il nome del file dal magnet link (se presente)
115
+ name_match = re.search(r'dn=([^&]+)', magnet_link)
116
+ torrent_name = name_match.group(1).replace('+', ' ') if name_match else "Nome non disponibile"
117
+
118
+ # Salva il timestamp prima di aggiungere il torrent
119
+ before_add_time = time.time()
120
+
121
+ # Aggiungi il magnet link
122
+ console.print(f"[cyan]Aggiunta magnet link[/cyan]: [red]{magnet_link}")
123
+ self.qb.download_from_link(magnet_link)
124
+
125
+ # Aspetta un attimo per essere sicuri che il torrent sia stato aggiunto
126
+ time.sleep(1)
127
+
128
+ # Cerca il torrent
129
+ torrents = self.qb.torrents()
130
+ matching_torrents = [
131
+ t for t in torrents
132
+ if (t['hash'].lower() == magnet_hash) or (t.get('added_on', 0) > before_add_time)
133
+ ]
134
+
135
+ if not matching_torrents:
136
+ raise ValueError("Nessun torrent corrispondente trovato")
137
+
138
+ # Prendi il primo torrent corrispondente
139
+ torrent_info = matching_torrents[0]
140
+
141
+ # Formatta e stampa le informazioni
142
+ console.print("\n[bold green]🔗 Dettagli Torrent Aggiunto:[/bold green]")
143
+ console.print(f"[yellow]Name:[/yellow] {torrent_info.get('name', torrent_name)}")
144
+ console.print(f"[yellow]Hash:[/yellow] {torrent_info['hash']}")
145
+ print()
146
+
147
+ # Salva l'hash per usi successivi e il path
148
+ self.latest_torrent_hash = torrent_info['hash']
149
+ self.output_file = torrent_info['content_path']
150
+ self.file_name = torrent_info['name']
151
+
152
+ # Controlla che sia possibile il download
153
+ time.sleep(5)
154
+ self.delete_magnet(self.qb.get_torrent(self.latest_torrent_hash))
155
+
156
+ return torrent_info
157
+
158
+ def start_download(self):
159
+ """
160
+ Starts downloading the latest added torrent and monitors progress.
161
+ """
162
+ if self.latest_torrent_hash is not None:
163
+ try:
164
+
165
+ # Custom bar for mobile and pc
166
+ if USE_LARGE_BAR:
167
+ bar_format = (
168
+ f"{Colors.YELLOW}[TOR] {Colors.WHITE}({Colors.CYAN}video{Colors.WHITE}): "
169
+ f"{Colors.RED}{{percentage:.2f}}% {Colors.MAGENTA}{{bar}} {Colors.WHITE}[ "
170
+ f"{Colors.YELLOW}{{elapsed}} {Colors.WHITE}< {Colors.CYAN}{{remaining}}{{postfix}} {Colors.WHITE}]"
171
+ )
172
+
173
+ else:
174
+ bar_format = (
175
+ f"{Colors.YELLOW}Proc{Colors.WHITE}: "
176
+ f"{Colors.RED}{{percentage:.2f}}% {Colors.WHITE}| "
177
+ f"{Colors.CYAN}{{remaining}}{{postfix}} {Colors.WHITE}]"
178
+ )
179
+
180
+ progress_bar = tqdm(
181
+ total=100,
182
+ ascii='░▒█',
183
+ bar_format=bar_format,
184
+ unit_scale=True,
185
+ unit_divisor=1024,
186
+ mininterval=0.05
187
+ )
188
+
189
+ with progress_bar as pbar:
190
+ while True:
191
+
192
+ # Get variable from qtorrent
193
+ torrent_info = self.qb.get_torrent(self.latest_torrent_hash)
194
+ self.save_path = torrent_info['save_path']
195
+ self.torrent_name = torrent_info['name']
196
+
197
+ # Fetch important variable
198
+ pieces_have = torrent_info['pieces_have']
199
+ pieces_num = torrent_info['pieces_num']
200
+ progress = (pieces_have / pieces_num) * 100 if pieces_num else 0
201
+ pbar.n = progress
202
+
203
+ download_speed = torrent_info['dl_speed']
204
+ total_size = torrent_info['total_size']
205
+ downloaded_size = torrent_info['total_downloaded']
206
+
207
+ # Format variable
208
+ downloaded_size_str = internet_manager.format_file_size(downloaded_size)
209
+ downloaded_size = downloaded_size_str.split(' ')[0]
210
+
211
+ total_size_str = internet_manager.format_file_size(total_size)
212
+ total_size = total_size_str.split(' ')[0]
213
+ total_size_unit = total_size_str.split(' ')[1]
214
+
215
+ average_internet_str = internet_manager.format_transfer_speed(download_speed)
216
+ average_internet = average_internet_str.split(' ')[0]
217
+ average_internet_unit = average_internet_str.split(' ')[1]
218
+
219
+ # Update the progress bar's postfix
220
+ if USE_LARGE_BAR:
221
+ pbar.set_postfix_str(
222
+ f"{Colors.WHITE}[ {Colors.GREEN}{downloaded_size} {Colors.WHITE}< {Colors.GREEN}{total_size} {Colors.RED}{total_size_unit} "
223
+ f"{Colors.WHITE}| {Colors.CYAN}{average_internet} {Colors.RED}{average_internet_unit}"
224
+ )
225
+ else:
226
+ pbar.set_postfix_str(
227
+ f"{Colors.WHITE}[ {Colors.GREEN}{downloaded_size}{Colors.RED} {total_size} "
228
+ f"{Colors.WHITE}| {Colors.CYAN}{average_internet} {Colors.RED}{average_internet_unit}"
229
+ )
230
+
231
+ pbar.refresh()
232
+ time.sleep(0.2)
233
+
234
+ # Break at the end
235
+ if int(progress) == 100:
236
+ break
237
+
238
+ except KeyboardInterrupt:
239
+ logging.info("Download process interrupted.")
240
+
241
+ def is_file_in_use(self, file_path: str) -> bool:
242
+ """Check if a file is in use by any process."""
243
+ for proc in psutil.process_iter(['open_files']):
244
+ try:
245
+ if any(file_path == f.path for f in proc.info['open_files'] or []):
246
+ return True
247
+ except (psutil.NoSuchProcess, psutil.AccessDenied):
248
+ continue
249
+
250
+ return False
251
+
252
+ def move_downloaded_files(self, destination: str):
253
+ """
254
+ Moves downloaded files of the latest torrent to another location.
255
+
256
+ Parameters:
257
+ - destination (str): Destination directory to move files.
258
+
259
+ Returns:
260
+ - bool: True if files are moved successfully, False otherwise.
261
+ """
262
+ console.print(f"[cyan]Destination folder: [red]{destination}")
263
+
264
+ try:
265
+
266
+ # Ensure the file is not in use
267
+ timeout = 3
268
+ elapsed = 0
269
+ while self.is_file_in_use(self.output_file) and elapsed < timeout:
270
+ time.sleep(1)
271
+ elapsed += 1
272
+
273
+ if elapsed == timeout:
274
+ raise Exception(f"File '{self.output_file}' is in use and could not be moved.")
275
+
276
+ # Ensure destination directory exists
277
+ os.makedirs(destination, exist_ok=True)
278
+
279
+ # Perform the move operation
280
+ try:
281
+ shutil.move(self.output_file, destination)
282
+
283
+ except OSError as e:
284
+ if e.errno == 17: # Cross-disk move error
285
+ # Perform copy and delete manually
286
+ shutil.copy2(self.output_file, destination)
287
+ os.remove(self.output_file)
288
+ else:
289
+ raise
290
+
291
+ # Delete the torrent data
292
+ time.sleep(5)
293
+ self.qb.delete_permanently(self.qb.torrents()[-1]['hash'])
294
+ return True
295
+
296
+ except Exception as e:
297
+ print(f"Error moving file: {e}")
296
298
  return False
@@ -1,5 +1,5 @@
1
- # 23.06.24
2
-
3
- from .HLS.downloader import HLS_Downloader
4
- from .MP4.downloader import MP4_downloader
1
+ # 23.06.24
2
+
3
+ from .HLS.downloader import HLS_Downloader
4
+ from .MP4.downloader import MP4_downloader
5
5
  from .TOR.downloader import TOR_downloader
@@ -1,4 +1,4 @@
1
- # 18.04.24
2
-
3
- from .command import join_video, join_audios, join_subtitle
4
- from .util import print_duration_table, get_video_duration
1
+ # 18.04.24
2
+
3
+ from .command import join_video, join_audios, join_subtitle
4
+ from .util import print_duration_table, get_video_duration