delarte/src/delarte/naming.py
Barbagus 56c1e8468a Split program/rendition/variant/target operations
Significant rewrite after model modification: introducing `*Sources`
objects that encapsulate metadata and fetch information (urls,
protocols). The API (#20) is organized as pipe elements with sources
being what flows through the pipe.
    1. fetch program sources
    2. fetch rendition sources
    3. fetch variant sources
    4. fetch targets
    5. process (download+mux) targets
Some user selection filter or modifiers could then be applied at any
step of the pipe. Our __main__.py is an implementation of that scheme.

Implied modifications include:
 - Later failure on unsupported protocols, used to be in `api`, now in
   `hls`. This offers the possibility to filter and/or support them
   later.
 - Give up honoring the http ranges for mp4 download, stream-download
   them by fixed chunk instead.
 - Cleaning up of the `hls` module moving the main download function to
   __init__ and specific (mp4/vtt) download functions to a new
   `download` module.

On the side modifications include:
 - The progress handler showing downloading rates.
 - The naming utilities providing rendition and variant code insertion.
 - Download parts to working directories and skip unnecessary
   re-downloads on failure.

This was a big change for a single commit... too big of a change maybe.
2023-01-24 08:27:37 +01:00

50 lines
1.2 KiB
Python

# License: GNU AGPL v3: http://www.gnu.org/licenses/
# This file is part of `delarte` (https://git.afpy.org/fcode/delarte.git)
"""Provide contextualized based file naming utility."""
import re
def file_name_builder(
*,
use_id=False,
sep=" - ",
seq_pfx=" - ",
seq_no_pad=False,
add_rendition=False,
add_variant=False
):
"""Create a file namer."""
def sub_sequence_counter(match):
index = match[1]
if not seq_no_pad:
index = (len(match[2]) - len(index)) * "0" + index
return seq_pfx + index
def replace_sequence_counter(s: str) -> str:
return re.sub(r"\s+\((\d+)/(\d+)\)", sub_sequence_counter, s)
def build_file_name(program, rendition, variant):
"""Create a file name."""
if use_id:
return program.id
fields = [replace_sequence_counter(program.title)]
if program.subtitle:
fields.append(replace_sequence_counter(program.subtitle))
if add_rendition:
fields.append(rendition.code)
if add_variant:
fields.append(variant.code)
name = sep.join(fields)
name = re.sub(r'[/:<>"\\|?*]', "", name)
return name
return build_file_name