Skip to content
This repository was archived by the owner on Nov 29, 2024. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
venv
.idea
HDRezkaAPI/__pycache__
*.mp4
*.mp4
*.json
38 changes: 38 additions & 0 deletions HDRezkaAPI/NEWdOWN.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import sys
import os
import requests
from tqdm import tqdm
# from .history import History
from concurrent.futures import ThreadPoolExecutor

def download_file(download_data):
if download_data['stream_url']:
print(download_data['file_name'])
fullpath = os.path.join(os.path.curdir, download_data['file_name'])

# Send HEAD request to get file size
response = requests.head(download_data['stream_url'])
total_size = int(response.headers.get('content-length', 0))

# Download the file using GET request
with requests.get(download_data['stream_url'], stream=True) as r:
with open(fullpath, "wb") as f, tqdm(
unit="B",
unit_scale=True,
unit_divisor=1024,
total=total_size,
file=sys.stdout,
desc=download_data['file_name']
) as progress:
for chunk in r.iter_content(chunk_size=1024*4):
if chunk:
datasize = f.write(chunk)
progress.update(datasize)

data = {
"stream_url": "https://stream.voidboost.cc/6fac7ad9ce36bdd25731bbca2a92e3c7:2024042219:QXlQUFEyYnNlVzBZOExha1Z0YVdHYUV3NVVrTXhGU2VYaXY0ZFBtLzhmL2lYcHprMVFJbXJKM0ZhS0VsMGtyMXcrOHJKSkg3Syt2djRsWEhYL1oyS2c9PQ==/1/3/5/0/1/1/7kqf9.mp4",

'file_name': 'test.mp4'

}
download_file(data)
1 change: 1 addition & 0 deletions HDRezkaAPI/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from .search import Search
from .movie_info import MovieInfo
from .history import History
from .download import *
164 changes: 109 additions & 55 deletions HDRezkaAPI/download.py
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import sys
from os import path
from bs4 import BeautifulSoup
import os
from .request import Request
from .get_stream import GetStream
from .history import History
from tqdm import tqdm


Expand All @@ -22,80 +22,111 @@ class EpisodeNumberIsOutOfRange(Error):


class Download:
def __init__(self, download_data):
def __init__(self, download_data, quality):
self.data = download_data
self.quality = quality
self.url = download_data['url']
response = Request().get(self.url)
self.soup = BeautifulSoup(response.content, 'html.parser')
self.favs = self.soup.find('input', id='ctrl_favs').get('value')
self.name = download_data['url'].split('/')[-1].split('.')[0]

if self.data['translations_list']:
self.translator_id = self.__get_translation()
if download_data.get("seasons_episodes_count") == 0:
# If there are no seasons and episodes
print("select again:")
self.translator_id = self.__get_translation()
else:
self.translator_id = self.__detect_translation()


def download_all_serial(self):
correct_season = False
seasons_count = self.data['seasons_count']
while not correct_season:
try:
if History().status == 'run' and History().run_season !="":
season = History().run_season
self.download_seasons(season, seasons_count +1)
else:
for season in range(1, seasons_count + 1):
self.download_season(season)
correct_season = True
except EpisodeNumberIsOutOfRange:
print('Неверный диапазон эпизодов!')
print('Скачивание успешно завершено!')

def download_seasons(self, start, end):
for season in range(start, end + 1):
if season < 1 or season > self.data['seasons_count']:
continue
self.download_season(season)

def download_season(self, season):
if season < 1 or season > self.data['seasons_count']:
# TODO Make new custom exception for incorrect season number and realize it
return

episodes_list = self.soup.find(
'ul', id=f'simple-episodes-list-{season}')
episodes_count = len(episodes_list.findAll('li'))
episodes_count = self.data['seasons_episodes_count'][season]
History().run_season = season

if self.data['translations_list']:
translator_id = self.__get_translation()
if History().status == 'run' and History().run_episode !="":
start = History( ).run_episode
else:
translator_id = self.__detect_translation()
start = 1

for i in range(1, episodes_count + 1):
self.download_episode(season, i, translator_id, True)
for i in range(start, episodes_count + 1):
self.download_episode(season, i)

def download_episodes(self, season, start, end):
def download_episodes(self, season, start):
print(season)
end = self.data['seasons_episodes_count'][season]
if season < 1 or season > self.data['seasons_count']:
# TODO Make new custom exception for incorrect season number and realize it
return

episodes_list = self.soup.find(
'ul', id=f'simple-episodes-list-{season}')
episodes_count = len(episodes_list.findAll('li'))
episodes_count = self.data['seasons_episodes_count'][season]


if end > episodes_count or start < 0:
raise EpisodeNumberIsOutOfRange

if self.data['translations_list']:
translator_id = self.__get_translation()
else:
translator_id = self.__detect_translation()

for i in range(start, end + 1):
self.download_episode(season, i, translator_id, True)
self.download_episode(season, i)

def download_episode(self, season, episode, translator_id=None, multi_download=False):
def download_episode(self, season, episode):
if self.data['type'] == 'movie':
return
if season > self.data['seasons_count']:
return

if not multi_download:
if self.data['translations_list']:
translator_id = self.__get_translation()
else:
translator_id = self.__detect_translation()

if episode < 1 or episode > self.data['seasons_episodes_count'][season]:
raise IncorrectEpisodeNumberException

data = {
'id': self.data['data-id'],
'translator_id': translator_id,
'favs': self.favs,
'translator_id': self.translator_id,
# 'favs': self.favs,
'season': season,
'episode': episode,
'action': 'get_stream'
'action': 'get_stream',
'quality': self.quality
}

print(episode)
History().run_episode = episode

stream_url = GetStream().get_series_stream(data)
file_name = f"{self.data['name']} {season}s{episode}e.mp4"
downloaded_folder = f"../{self.name}"
# downloaded_folder = self.name
os.makedirs(downloaded_folder, exist_ok=True)

season = str(season).zfill(2)
episode = str(episode).zfill(2)
file_name = f"{downloaded_folder}/s{season}e{episode}-{self.quality}.mp4"

download_data = {
'stream_url': stream_url,
'file_name': file_name,

}

self.__download(download_data)
Expand All @@ -105,26 +136,27 @@ def download_movie(self):
return

data = {
'url': self.url
'url': self.url,
'quality': self.quality
}

stream_url = GetStream().get_movie_stream(data)
# file_name = f"{self.data['name']}.mp4"
# TODO Fix file name bug
file_name = f"test.mp4"

download_data = {
'stream_url': stream_url,
'file_name': file_name,
'file_name': self.name,
}

self.__download(download_data)

@staticmethod
def __download(download_data):
def __download( download_data):
if download_data['stream_url']:

fullpath = path.join(path.curdir, download_data['file_name'])
print (download_data['file_name'])
print (download_data['stream_url'])
History().status = "run"
fullpath = os.path.join(os.path.curdir, download_data['file_name'])

with Request().get(download_data['stream_url'], stream=True) as r, open(fullpath, "wb") as f, tqdm(
unit="B",
Expand All @@ -134,25 +166,47 @@ def __download(download_data):
file=sys.stdout,
desc=download_data['file_name']
) as progress:
for chunk in r.iter_content(chunk_size=4096):
for chunk in r.iter_content(chunk_size=1024*4):
if chunk:
datasize = f.write(chunk)
progress.update(datasize)
History().run_episode = History().run_episode + 1


def convert_to_pls(self):
file_name = self.filee.name
self.filee.close()
with open(file_name, 'r') as f:
url_list = [line.strip() for line in f]
with open(f"{self.name}.pls", 'w') as f:
f.write("[playlist]\n")
for i, url in enumerate(url_list):
f.write(f"File{i+1}={url}\n")
f.write(f"Title{i+1}=Track {i+1}\n")
print(f'Pls len: {len(url_list)}')
print(self.download_data['allepisodes'])
f.write(f"NumberOfEntries={len(url_list)}\n")
f.write("Version=2\n")

def __get_translation(self) -> int:
for i, translation in zip(range(1, len(self.data['translations_list'])), self.data['translations_list']):
print(f'{i} - {translation["name"]}')
translation_id = self.data['translations_list'][int(
input("Введите номер озвучки: ")) - 1]['id']
if History().status == 'run':
translation_id = History().translator_id
else:
for i, translation in zip(range(1, len(self.data['translations_list'])), self.data['translations_list']):
print(f'{i} - {translation["name"]}')
translation_id = self.data['translations_list'][int(
input("Введите номер озвучки: ")) - 1]['id']
History().translator_id = translation_id

return translation_id

def __detect_translation(self):
if self.data['type'] == 'movie':
event_type = 'initCDNMoviesEvents'
else:
event_type = 'initCDNSeriesEvents'
# def __detect_translation(self):
# if self.data['type'] == 'movie':
# event_type = 'initCDNMoviesEvents'
# else:
# event_type = 'initCDNSeriesEvents'

tmp = str(self.soup).split(f"sof.tv.{event_type}")[-1].split("{")[0]
translator_id = tmp.split(",")[1].strip()
# tmp = str(self.soup).split(f"sof.tv.{event_type}")[-1].split("{")[0]
# translator_id = tmp.split(",")[1].strip()

return translator_id
# return translator_id
30 changes: 26 additions & 4 deletions HDRezkaAPI/get_stream.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ def get_series_stream(self, data):
'Попробуйте скачать используя VPN!')
exit(0)
arr = self.decode_url(r['url'], separator="//_//").split(",")
# TODO Make quality select
stream_url = arr[-1][arr[-1].find("or") + 3:len(arr[-1])]
stream_url = self.quality_select(arr, data['quality'])
decoded = True
except (UnicodeDecodeError, BinasciiError):
print('Decoding error, trying again!')
Expand All @@ -50,13 +49,36 @@ def get_movie_stream(self, data):
try:
arr = self.decode_url(encoded_stream_url,
separator="\/\/_\/\/").split(",")
# TODO Make quality select
stream_url = arr[-1][arr[-1].find("or") + 3:len(arr[-1])]
# stream_url = arr[-1][arr[-1].find("or") + 3:len(arr[-1])]
stream_url = self.quality_select(arr, data['quality'])
decoded = True
except (UnicodeDecodeError, BinasciiError):
print('Decoding error, trying again!')

return stream_url

@staticmethod
def quality_select(stream_list, quality):
resolutions_and_urls = []
for item in stream_list:
resolution, url = item.split("]")
if url.endswith(".mp4"):
resolutions_and_urls.append((resolution + "]", url.split(" or ")[1]))

selected_index = -2
if len(quality) > 2:
for index, item in enumerate(stream_list):
if quality in item:
selected_index = index
break

# if selected_index == -1:
# raise ValueError("Quality not found or invalid")

stream_url = resolutions_and_urls[selected_index][1]
print(resolutions_and_urls[selected_index][0], "\n")
return stream_url


@staticmethod
def decode_url(data, separator):
Expand Down
Loading