Skip to content

Commit

Permalink
download hook
Browse files Browse the repository at this point in the history
Rimosso show_progress e rimpiazzato con un hook
  • Loading branch information
MainKronos committed Mar 14, 2022
1 parent 082385f commit 393058b
Show file tree
Hide file tree
Showing 4 changed files with 199 additions and 77 deletions.
14 changes: 11 additions & 3 deletions animeworld/episodio.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,20 +66,28 @@ def links(self) -> List[Server]: # lista dei provider dove sono hostati gli ep

return self.__setServer(tmp, self.number)

def download(self, title: Optional[str]=None, folder: str='', show_progress: bool=True) -> Optional[str]: # Scarica l'episodio con il primo link nella lista
def download(self, title: Optional[str]=None, folder: str='', hook: Callable[[Dict], None] = lambda *args:None) -> Optional[str]: # Scarica l'episodio con il primo link nella lista
"""
Scarica l'episodio dal primo server della lista links.
- `title`: Nome con cui verrà nominato il file scaricato.
- `folder`: Posizione in cui verrà spostato il file scaricato.
- `show_progress`: Mostra la barra di avanzamento.
- `hook`: Funzione che viene richiamata varie volte durante il download; la funzione riceve come argomento un dizionario con le seguenti chiavi:
- `total_bytes`: Byte totali da scaricare.
- `downloaded_bytes`: Byte attualmente scaricati.
- `percentage`: Percentuale del progresso di download.
- `speed`: Velocità di download (byte/s)
- `elapsed`: Tempo trascorso dall'inizio del download.
- `eta`: Tempo stimato rimanente per fine del download.
- `status`: 'downloading' | 'finished'
- `filename`: Nome del file in download.
```
return str # File scaricato
```
"""

return self.links[0].download(title,folder)
return self.links[0].download(title,folder,hook)

# Private
def __setServer(self, links: List[Dict], numero: str) -> List[Server]: # Per ogni link li posizioni nelle rispettive classi
Expand Down
190 changes: 141 additions & 49 deletions animeworld/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import re
import os
from typing import *
from alive_progress import alive_bar
import time

from .globals import HDR, cookies
from .utility import HealthCheck
Expand Down Expand Up @@ -63,13 +63,21 @@ def _sanitize(self, title: str) -> str: # Toglie i caratteri illegali per i file
title = title.replace(x, '')
return title

def download(self, title: Optional[str]=None, folder: str='', show_progress: bool=True) -> Optional[str]:
def download(self, title: Optional[str]=None, folder: str='', hook: Callable[[Dict], None] = lambda *args:None) -> Optional[str]:
"""
Scarica l'episodio.
- `title`: Nome con cui verrà nominato il file scaricato.
- `folder`: Posizione in cui verrà spostato il file scaricato.
- `show_progress`: Mostra la barra di avanzamento.
- `hook`: Funzione che viene richiamata varie volte durante il download; la funzione riceve come argomento un dizionario con le seguenti chiavi:
- `total_bytes`: Byte totali da scaricare.
- `downloaded_bytes`: Byte attualmente scaricati.
- `percentage`: Percentuale del progresso di download.
- `speed`: Velocità di download (byte/s)
- `elapsed`: Tempo trascorso dall'inizio del download.
- `eta`: Tempo stimato rimanente per fine del download.
- `status`: 'downloading' | 'finished'
- `filename`: Nome del file in download.
```
return str # File scaricato
Expand All @@ -78,13 +86,21 @@ def download(self, title: Optional[str]=None, folder: str='', show_progress: boo
raise ServerNotSupported(self.name)

# Protected
def _downloadIn(self, title: str, folder: str, show_progress: bool) -> bool: # Scarica l'episodio
def _downloadIn(self, title: str, folder: str, hook: Callable[[Dict], None]) -> bool: # Scarica l'episodio
"""
Scarica il file utilizzando requests.
- `title`: Nome con cui verrà nominato il file scaricato.
- `folder`: Posizione in cui verrà spostato il file scaricato.
- `show_progress`: Mostra la barra di avanzamento.
- `hook`: Funzione che viene richiamata varie volte durante il download; la funzione riceve come argomento un dizionario con le seguenti chiavi:
- `total_bytes`: Byte totali da scaricare.
- `downloaded_bytes`: Byte attualmente scaricati.
- `percentage`: Percentuale del progresso di download.
- `speed`: Velocità di download (byte/s)
- `elapsed`: Tempo trascorso dall'inizio del download.
- `eta`: Tempo stimato rimanente per fine del download.
- `status`: 'downloading' | 'finished'
- `filename`: Nome del file in download.
```
return bool # File scaricato
Expand All @@ -97,57 +113,101 @@ def _downloadIn(self, title: str, folder: str, show_progress: bool) -> bool: # S
file = f"{title}.{ext}"

total_length = int(r.headers.get('content-length'))
with open(f"{os.path.join(folder,file)}", 'wb') as f, alive_bar(total_length//65536+1, disable = not show_progress, length = 80, monitor = "[{percent:.0%}]", stats ="(ETA: {eta})", stats_end=False) as bar:
for chunk in r.iter_content(chunk_size = 65536):
current_lenght = 0
start = time.time()
step = time.time()

with open(f"{os.path.join(folder,file)}", 'wb') as f:
for chunk in r.iter_content(chunk_size = 524288):
if chunk:
f.write(chunk)
f.flush()
bar()

current_lenght += len(chunk)

hook({
'total_bytes': total_length,
'downloaded_bytes': current_lenght,
'percentage': current_lenght/total_length,
'speed': len(chunk) / (time.time() - step) if (time.time() - step) != 0 else 0,
'elapsed': time.time() - start,
'filename': file,
'eta': ((total_length - current_lenght) / len(chunk)) * (time.time() - step),
'status': 'downloading'
})

step = time.time()

else:
hook({
'total_bytes': total_length,
'downloaded_bytes': total_length,
'percentage': 1,
'speed': 0,
'elapsed': time.time() - start,
'eta': 0,
'status': 'finished'
})

return file # Se il file è stato scaricato correttamente
return None # Se è accaduto qualche imprevisto

# Protected
def _dowloadEx(self, title: str, folder: str, show_progress: bool) -> Optional[str]:
def _dowloadEx(self, title: str, folder: str, hook: Callable[[Dict], None]) -> Optional[str]:
"""
Scarica il file utilizzando yutube_dl.
- `title`: Nome con cui verrà nominato il file scaricato.
- `folder`: Posizione in cui verrà spostato il file scaricato.
- `show_progress`: Mostra la barra di avanzamento.
- `hook`: Funzione che viene richiamata varie volte durante il download; la funzione riceve come argomento un dizionario con le seguenti chiavi:
- `total_bytes`: Byte totali da scaricare.
- `downloaded_bytes`: Byte attualmente scaricati.
- `percentage`: Percentuale del progresso di download.
- `speed`: Velocità di download (byte/s)
- `elapsed`: Tempo trascorso dall'inizio del download.
- `eta`: Tempo stimato rimanente per fine del download.
- `status`: 'downloading' | 'finished'
- `filename`: Nome del file in download.
```
return str # File scaricato
```
"""

with alive_bar(disable = not show_progress, length = 80, monitor = "[{percent:.0%}]", stats ="(ETA: {eta})", stats_end=False, manual=True) as bar:
class MyLogger(object):
def debug(self, msg):
pass
def warning(self, msg):
pass
def error(self, msg):
print(msg)
return False

def my_hook(d):
if d['status'] == 'downloading':
bar(float(d['downloaded_bytes'])/float(d['total_bytes_estimate']))
if d['status'] == 'finished':
return True

ydl_opts = {
'outtmpl': f"{os.path.join(folder,title)}.%(ext)s",
'logger': MyLogger(),
'progress_hooks': [my_hook],
}
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
url = self._getFileLink()
info = ydl.extract_info(url, download=False)
filename = ydl.prepare_filename(info)
ydl.download([url])
return filename
class MyLogger(object):
def debug(self, msg):
pass
def warning(self, msg):
pass
def error(self, msg):
print(msg)
return False

def my_hook(d):
hook({
'total_bytes': int(d['total_bytes_estimate']),
'downloaded_bytes': int(d['downloaded_bytes']),
'percentage': int(d['downloaded_bytes'])/int(d['total_bytes_estimate']),
'speed': float(d['speed']) if d['speed'] is not None else 0,
'elapsed': float(d['elapsed']),
'filename': d['filename'],
'eta': int(d['eta']),
'status': d['status']
})
if d['status'] == 'finished':
return True

ydl_opts = {
'outtmpl': f"{os.path.join(folder,title)}.%(ext)s",
'logger': MyLogger(),
'progress_hooks': [my_hook],
}
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
url = self._getFileLink()
info = ydl.extract_info(url, download=False)
filename = ydl.prepare_filename(info)
ydl.download([url])
return filename


class AnimeWorld_Server(Server):
Expand All @@ -157,21 +217,29 @@ def _getFileLink(self):

return self.link.replace('download-file.php?id=', '')

def download(self, title: Optional[str]=None, folder: str='', show_progress: bool=True) -> bool:
def download(self, title: Optional[str]=None, folder: str='', hook: Callable[[Dict], None] = lambda *args:None) -> bool:
"""
Scarica l'episodio.
- `title`: Nome con cui verrà nominato il file scaricato.
- `folder`: Posizione in cui verrà spostato il file scaricato.
- `show_progress`: Mostra la barra di avanzamento.
- `hook`: Funzione che viene richiamata varie volte durante il download; la funzione riceve come argomento un dizionario con le seguenti chiavi:
- `total_bytes`: Byte totali da scaricare.
- `downloaded_bytes`: Byte attualmente scaricati.
- `percentage`: Percentuale del progresso di download.
- `speed`: Velocità di download (byte/s)
- `elapsed`: Tempo trascorso dall'inizio del download.
- `eta`: Tempo stimato rimanente per fine del download.
- `status`: 'downloading' | 'finished'
- `filename`: Nome del file in download.
```
return bool # File scaricato
```
"""
if title is None: title = self._defTitle
else: title = self._sanitize(title)
return self._downloadIn(title,folder,show_progress)
return self._downloadIn(title,folder,hook)

class VVVVID(Server):
# Protected
Expand All @@ -191,21 +259,29 @@ def _getFileLink(self):
raw = soupeddata.find("a", { "class" : "VVVVID-link" })
return raw.get("href")

def download(self, title: Optional[str]=None, folder: str='', show_progress: bool=True) -> bool:
def download(self, title: Optional[str]=None, folder: str='', hook: Callable[[Dict], None] = lambda *args:None) -> bool:
"""
Scarica l'episodio.
- `title`: Nome con cui verrà nominato il file scaricato.
- `folder`: Posizione in cui verrà spostato il file scaricato.
- `show_progress`: Mostra la barra di avanzamento.
- `hook`: Funzione che viene richiamata varie volte durante il download; la funzione riceve come argomento un dizionario con le seguenti chiavi:
- `total_bytes`: Byte totali da scaricare.
- `downloaded_bytes`: Byte attualmente scaricati.
- `percentage`: Percentuale del progresso di download.
- `speed`: Velocità di download (byte/s)
- `elapsed`: Tempo trascorso dall'inizio del download.
- `eta`: Tempo stimato rimanente per fine del download.
- `status`: 'downloading' | 'finished'
- `filename`: Nome del file in download.
```
return bool # File scaricato
```
"""
if title is None: title = self._defTitle
else: title = self._sanitize(title)
return self._dowloadEx(title,folder,show_progress)
return self._dowloadEx(title,folder,hook)


class YouTube(Server):
Expand All @@ -228,21 +304,29 @@ def _getFileLink(self):

return yutubelink_raw.replace('embed/', 'watch?v=')

def download(self, title: Optional[str]=None, folder: str='', show_progress: bool=True) -> bool:
def download(self, title: Optional[str]=None, folder: str='', hook: Callable[[Dict], None] = lambda *args:None) -> bool:
"""
Scarica l'episodio.
- `title`: Nome con cui verrà nominato il file scaricato.
- `folder`: Posizione in cui verrà spostato il file scaricato.
- `show_progress`: Mostra la barra di avanzamento.
- `hook`: Funzione che viene richiamata varie volte durante il download; la funzione riceve come argomento un dizionario con le seguenti chiavi:
- `total_bytes`: Byte totali da scaricare.
- `downloaded_bytes`: Byte attualmente scaricati.
- `percentage`: Percentuale del progresso di download.
- `speed`: Velocità di download (byte/s)
- `elapsed`: Tempo trascorso dall'inizio del download.
- `eta`: Tempo stimato rimanente per fine del download.
- `status`: 'downloading' | 'finished'
- `filename`: Nome del file in download.
```
return bool # File scaricato
```
"""
if title is None: title = self._defTitle
else: title = self._sanitize(title)
return self._dowloadEx(title,folder,show_progress)
return self._dowloadEx(title,folder,hook)

class Streamtape(Server):
# Protected
Expand All @@ -268,18 +352,26 @@ def _getFileLink(self):

return mp4_link

def download(self, title: Optional[str]=None, folder: str='', show_progress: bool=True) -> bool:
def download(self, title: Optional[str]=None, folder: str='', hook: Callable[[Dict], None] = lambda *args:None) -> bool:
"""
Scarica l'episodio.
- `title`: Nome con cui verrà nominato il file scaricato.
- `folder`: Posizione in cui verrà spostato il file scaricato.
- `show_progress`: Mostra la barra di avanzamento.
- `hook`: Funzione che viene richiamata varie volte durante il download; la funzione riceve come argomento un dizionario con le seguenti chiavi:
- `total_bytes`: Byte totali da scaricare.
- `downloaded_bytes`: Byte attualmente scaricati.
- `percentage`: Percentuale del progresso di download.
- `speed`: Velocità di download (byte/s)
- `elapsed`: Tempo trascorso dall'inizio del download.
- `eta`: Tempo stimato rimanente per fine del download.
- `status`: 'downloading' | 'finished'
- `filename`: Nome del file in download.
```
return bool # File scaricato
```
"""
if title is None: title = self._defTitle
else: title = self._sanitize(title)
return self._downloadIn(title,folder,show_progress)
return self._downloadIn(title,folder,hook)
Loading

0 comments on commit 393058b

Please sign in to comment.