FILE_FLAGS: dict[FlagName, FlagsInt] = {
FlagName('do not sync'): FlagsInt(1 << 62)
}
-ONE_MILLION = 1000 * 1000
+MILLION = 1000 * 1000
+MEGA = 1024 * 1024
def ensure_expected_dirs(expected_dirs: list[Path]) -> None:
self.yt_id = yt_id
self.duration_ms = (
duration_ms if duration_ms >= 0
- else int(ONE_MILLION * Decimal(
+ else int(MILLION * Decimal(
ffprobe(self.full_path)['format']['duration'])))
self.last_update = last_update if last_update else _now_string()
self._hash_on_last_update = hash(self)
"""If file at .full_path, return its megabytes size, else -1."""
if not self.full_path.is_file():
return -1
- return self.full_path.stat().st_size / (1024 * 1024)
+ return self.full_path.stat().st_size / MEGA
def duration(self, short: bool = False) -> str:
"""Return human-friendly formatting of .duration_ms."""
if self.duration_ms < 0:
return '?'
- seconds_str = f'{_readable_seconds(self.duration_ms // ONE_MILLION)}'
- milliseconds_str = f'{self.duration_ms // ONE_MILLION}'.rjust(6, '0')
+ seconds_str = f'{_readable_seconds(self.duration_ms // MILLION)}'
+ milliseconds_str = f'{self.duration_ms // MILLION}'.rjust(6, '0')
return seconds_str if short else f'{seconds_str}.{milliseconds_str}'
@property
def _download_next(self) -> None:
if self._to_download:
+ downloaded_before: int = 0
+ estimated_total: int = 0
+ estimated_total_mb: float
+
+ def hook(d) -> None:
+ nonlocal downloaded_before
+ if d['status'] in {'downloading', 'finished'}:
+ downloaded_i = d['downloaded_bytes']
+ downloaded_mb = (downloaded_i + downloaded_before) / MEGA
+ msg = f'{int(100 * downloaded_mb/estimated_total_mb)}%: '\
+ f'{downloaded_mb:5.1f}/{estimated_total_mb:.1f}'
+ self._update_status(video_id, f'downloading: {msg} MB')
+ if d['status'] == 'finished':
+ downloaded_before += downloaded_i
+
video_id = self._to_download.pop(0)
- with YoutubeDL(YT_DL_PARAMS) as ydl:
- self._update_status(video_id, 'downloading')
- ydl.download([f'{YOUTUBE_URL_PREFIX}{video_id}'])
+ url = f'{YOUTUBE_URL_PREFIX}{video_id}'
+ with YoutubeDL(YT_DL_PARAMS | {'progress_hooks': [hook]}) as ydl:
+ info = ydl.sanitize_info(ydl.extract_info(url, download=False))
+ for requested in info['requested_formats']:
+ estimated_total += requested['filesize_approx']
+ estimated_total_mb = estimated_total / MEGA
+ ydl.download(url)
self._sync_db()
def start_thread(self) -> None: