[cleanup] Misc cleanup

This commit is contained in:
pukkandan 2022-07-09 01:07:47 +05:30
parent ca9def714a
commit f2df407165
No known key found for this signature in database
GPG Key ID: 7EEE9E1E817D0A39
19 changed files with 52 additions and 38 deletions

View File

@ -32,7 +32,7 @@ body:
id: description id: description
attributes: attributes:
label: Provide a description that is worded well enough to be understood label: Provide a description that is worded well enough to be understood
description: See [is-the-description-of-the-issue-itself-sufficient](https://github.com/ytdl-org/youtube-dl#is-the-description-of-the-issue-itself-sufficient) description: See [is-the-description-of-the-issue-itself-sufficient](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#is-the-description-of-the-issue-itself-sufficient)
placeholder: Provide any additional information, any suggested solutions, and as much context and examples as possible placeholder: Provide any additional information, any suggested solutions, and as much context and examples as possible
validations: validations:
required: true required: true

View File

@ -44,7 +44,7 @@ body:
id: description id: description
attributes: attributes:
label: Provide a description that is worded well enough to be understood label: Provide a description that is worded well enough to be understood
description: See [is-the-description-of-the-issue-itself-sufficient](https://github.com/ytdl-org/youtube-dl#is-the-description-of-the-issue-itself-sufficient) description: See [is-the-description-of-the-issue-itself-sufficient](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#is-the-description-of-the-issue-itself-sufficient)
placeholder: Provide any additional information, any suggested solutions, and as much context and examples as possible placeholder: Provide any additional information, any suggested solutions, and as much context and examples as possible
validations: validations:
required: true required: true

View File

@ -40,7 +40,7 @@ body:
id: description id: description
attributes: attributes:
label: Provide a description that is worded well enough to be understood label: Provide a description that is worded well enough to be understood
description: See [is-the-description-of-the-issue-itself-sufficient](https://github.com/ytdl-org/youtube-dl#is-the-description-of-the-issue-itself-sufficient) description: See [is-the-description-of-the-issue-itself-sufficient](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#is-the-description-of-the-issue-itself-sufficient)
placeholder: Provide any additional information, any suggested solutions, and as much context and examples as possible placeholder: Provide any additional information, any suggested solutions, and as much context and examples as possible
validations: validations:
required: true required: true

View File

@ -25,7 +25,7 @@ body:
id: description id: description
attributes: attributes:
label: Provide a description that is worded well enough to be understood label: Provide a description that is worded well enough to be understood
description: See [is-the-description-of-the-issue-itself-sufficient](https://github.com/ytdl-org/youtube-dl#is-the-description-of-the-issue-itself-sufficient) description: See [is-the-description-of-the-issue-itself-sufficient](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#is-the-description-of-the-issue-itself-sufficient)
placeholder: Provide any additional information, any suggested solutions, and as much context and examples as possible placeholder: Provide any additional information, any suggested solutions, and as much context and examples as possible
validations: validations:
required: true required: true

View File

@ -23,7 +23,7 @@ body:
id: description id: description
attributes: attributes:
label: Provide a description that is worded well enough to be understood label: Provide a description that is worded well enough to be understood
description: See [is-the-description-of-the-issue-itself-sufficient](https://github.com/ytdl-org/youtube-dl#is-the-description-of-the-issue-itself-sufficient) description: See [is-the-description-of-the-issue-itself-sufficient](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#is-the-description-of-the-issue-itself-sufficient)
placeholder: Provide any additional information, any suggested solutions, and as much context and examples as possible placeholder: Provide any additional information, any suggested solutions, and as much context and examples as possible
validations: validations:
required: true required: true

View File

@ -29,7 +29,7 @@ body:
id: question id: question
attributes: attributes:
label: Please make sure the question is worded well enough to be understood label: Please make sure the question is worded well enough to be understood
description: See [is-the-description-of-the-issue-itself-sufficient](https://github.com/ytdl-org/youtube-dl#is-the-description-of-the-issue-itself-sufficient) description: See [is-the-description-of-the-issue-itself-sufficient](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#is-the-description-of-the-issue-itself-sufficient)
placeholder: Provide any additional information and as much context and examples as possible placeholder: Provide any additional information and as much context and examples as possible
validations: validations:
required: true required: true

View File

@ -32,7 +32,7 @@ body:
id: description id: description
attributes: attributes:
label: Provide a description that is worded well enough to be understood label: Provide a description that is worded well enough to be understood
description: See [is-the-description-of-the-issue-itself-sufficient](https://github.com/ytdl-org/youtube-dl#is-the-description-of-the-issue-itself-sufficient) description: See [is-the-description-of-the-issue-itself-sufficient](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#is-the-description-of-the-issue-itself-sufficient)
placeholder: Provide any additional information, any suggested solutions, and as much context and examples as possible placeholder: Provide any additional information, any suggested solutions, and as much context and examples as possible
validations: validations:
required: true required: true

View File

@ -44,7 +44,7 @@ body:
id: description id: description
attributes: attributes:
label: Provide a description that is worded well enough to be understood label: Provide a description that is worded well enough to be understood
description: See [is-the-description-of-the-issue-itself-sufficient](https://github.com/ytdl-org/youtube-dl#is-the-description-of-the-issue-itself-sufficient) description: See [is-the-description-of-the-issue-itself-sufficient](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#is-the-description-of-the-issue-itself-sufficient)
placeholder: Provide any additional information, any suggested solutions, and as much context and examples as possible placeholder: Provide any additional information, any suggested solutions, and as much context and examples as possible
validations: validations:
required: true required: true

View File

@ -40,7 +40,7 @@ body:
id: description id: description
attributes: attributes:
label: Provide a description that is worded well enough to be understood label: Provide a description that is worded well enough to be understood
description: See [is-the-description-of-the-issue-itself-sufficient](https://github.com/ytdl-org/youtube-dl#is-the-description-of-the-issue-itself-sufficient) description: See [is-the-description-of-the-issue-itself-sufficient](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#is-the-description-of-the-issue-itself-sufficient)
placeholder: Provide any additional information, any suggested solutions, and as much context and examples as possible placeholder: Provide any additional information, any suggested solutions, and as much context and examples as possible
validations: validations:
required: true required: true

View File

@ -25,7 +25,7 @@ body:
id: description id: description
attributes: attributes:
label: Provide a description that is worded well enough to be understood label: Provide a description that is worded well enough to be understood
description: See [is-the-description-of-the-issue-itself-sufficient](https://github.com/ytdl-org/youtube-dl#is-the-description-of-the-issue-itself-sufficient) description: See [is-the-description-of-the-issue-itself-sufficient](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#is-the-description-of-the-issue-itself-sufficient)
placeholder: Provide any additional information, any suggested solutions, and as much context and examples as possible placeholder: Provide any additional information, any suggested solutions, and as much context and examples as possible
validations: validations:
required: true required: true

View File

@ -23,7 +23,7 @@ body:
id: description id: description
attributes: attributes:
label: Provide a description that is worded well enough to be understood label: Provide a description that is worded well enough to be understood
description: See [is-the-description-of-the-issue-itself-sufficient](https://github.com/ytdl-org/youtube-dl#is-the-description-of-the-issue-itself-sufficient) description: See [is-the-description-of-the-issue-itself-sufficient](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#is-the-description-of-the-issue-itself-sufficient)
placeholder: Provide any additional information, any suggested solutions, and as much context and examples as possible placeholder: Provide any additional information, any suggested solutions, and as much context and examples as possible
validations: validations:
required: true required: true

View File

@ -29,7 +29,7 @@ body:
id: question id: question
attributes: attributes:
label: Please make sure the question is worded well enough to be understood label: Please make sure the question is worded well enough to be understood
description: See [is-the-description-of-the-issue-itself-sufficient](https://github.com/ytdl-org/youtube-dl#is-the-description-of-the-issue-itself-sufficient) description: See [is-the-description-of-the-issue-itself-sufficient](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#is-the-description-of-the-issue-itself-sufficient)
placeholder: Provide any additional information and as much context and examples as possible placeholder: Provide any additional information and as much context and examples as possible
validations: validations:
required: true required: true

View File

@ -147,7 +147,7 @@ ### Differences in default behavior
* Some private fields such as filenames are removed by default from the infojson. Use `--no-clean-infojson` or `--compat-options no-clean-infojson` to revert this * Some private fields such as filenames are removed by default from the infojson. Use `--no-clean-infojson` or `--compat-options no-clean-infojson` to revert this
* When `--embed-subs` and `--write-subs` are used together, the subtitles are written to disk and also embedded in the media file. You can use just `--embed-subs` to embed the subs and automatically delete the separate file. See [#630 (comment)](https://github.com/yt-dlp/yt-dlp/issues/630#issuecomment-893659460) for more info. `--compat-options no-keep-subs` can be used to revert this * When `--embed-subs` and `--write-subs` are used together, the subtitles are written to disk and also embedded in the media file. You can use just `--embed-subs` to embed the subs and automatically delete the separate file. See [#630 (comment)](https://github.com/yt-dlp/yt-dlp/issues/630#issuecomment-893659460) for more info. `--compat-options no-keep-subs` can be used to revert this
* `certifi` will be used for SSL root certificates, if installed. If you want to use system certificates (e.g. self-signed), use `--compat-options no-certifi` * `certifi` will be used for SSL root certificates, if installed. If you want to use system certificates (e.g. self-signed), use `--compat-options no-certifi`
* youtube-dl tries to remove some superfluous punctuations from filenames. While this can sometimes be helpfull, it is often undesirable. So yt-dlp tries to keep the fields in the filenames as close to their original values as possible. You can use `--compat-options filename-sanitization` to revert to youtube-dl's behavior * youtube-dl tries to remove some superfluous punctuations from filenames. While this can sometimes be helpful, it is often undesirable. So yt-dlp tries to keep the fields in the filenames as close to their original values as possible. You can use `--compat-options filename-sanitization` to revert to youtube-dl's behavior
For ease of use, a few more compat options are available: For ease of use, a few more compat options are available:
@ -238,7 +238,7 @@ #### Recommended
:---|:--- :---|:---
[yt-dlp](https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp)|Platform-independent [zipimport](https://docs.python.org/3/library/zipimport.html) binary. Needs Python (recommended for **Linux/BSD**) [yt-dlp](https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp)|Platform-independent [zipimport](https://docs.python.org/3/library/zipimport.html) binary. Needs Python (recommended for **Linux/BSD**)
[yt-dlp.exe](https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp.exe)|Windows (Win7 SP1+) standalone x64 binary (recommended for **Windows**) [yt-dlp.exe](https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp.exe)|Windows (Win7 SP1+) standalone x64 binary (recommended for **Windows**)
[yt-dlp_macos](https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp_macos)|MacOS (10.15+) standalone executable (recommended for **MacOS**) [yt-dlp_macos](https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp_macos)|Universal MacOS (10.15+) standalone executable (recommended for **MacOS**)
#### Alternatives #### Alternatives
@ -246,8 +246,8 @@ #### Alternatives
:---|:--- :---|:---
[yt-dlp_x86.exe](https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp_x86.exe)|Windows (Vista SP2+) standalone x86 (32-bit) binary [yt-dlp_x86.exe](https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp_x86.exe)|Windows (Vista SP2+) standalone x86 (32-bit) binary
[yt-dlp_min.exe](https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp_min.exe)|Windows (Win7 SP1+) standalone x64 binary built with `py2exe`<br/> ([Not recommended](#standalone-py2exe-builds-windows)) [yt-dlp_min.exe](https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp_min.exe)|Windows (Win7 SP1+) standalone x64 binary built with `py2exe`<br/> ([Not recommended](#standalone-py2exe-builds-windows))
[yt-dlp_linux](https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp_linux)|UNIX standalone x64 binary [yt-dlp_linux](https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp_linux)|Linux standalone x64 binary
[yt-dlp_linux.zip](https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp_linux.zip)|Unpackaged Unix executable (no auto-update) [yt-dlp_linux.zip](https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp_linux.zip)|Unpackaged Linux executable (no auto-update)
[yt-dlp_win.zip](https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp_win.zip)|Unpackaged Windows executable (no auto-update) [yt-dlp_win.zip](https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp_win.zip)|Unpackaged Windows executable (no auto-update)
[yt-dlp_macos.zip](https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp_macos.zip)|Unpackaged MacOS (10.15+) executable (no auto-update) [yt-dlp_macos.zip](https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp_macos.zip)|Unpackaged MacOS (10.15+) executable (no auto-update)
[yt-dlp_macos_legacy](https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp_macos_legacy)|MacOS (10.9+) standalone x64 executable [yt-dlp_macos_legacy](https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp_macos_legacy)|MacOS (10.9+) standalone x64 executable
@ -305,7 +305,7 @@ #### Deprecated
To use or redistribute the dependencies, you must agree to their respective licensing terms. To use or redistribute the dependencies, you must agree to their respective licensing terms.
The Windows and MacOS standalone release binaries are built with the Python interpreter and the packages marked with **\*** included. The standalone release binaries are built with the Python interpreter and the packages marked with **\*** included.
If you do not have the necessary dependencies for a task you are attempting, yt-dlp will warn you. All the currently available dependencies are visible at the top of the `--verbose` output If you do not have the necessary dependencies for a task you are attempting, yt-dlp will warn you. All the currently available dependencies are visible at the top of the `--verbose` output
@ -414,7 +414,8 @@ ## General Options:
--no-wait-for-video Do not wait for scheduled streams (default) --no-wait-for-video Do not wait for scheduled streams (default)
--mark-watched Mark videos watched (even with --simulate) --mark-watched Mark videos watched (even with --simulate)
--no-mark-watched Do not mark videos watched (default) --no-mark-watched Do not mark videos watched (default)
--no-colors Do not emit color codes in output --no-colors Do not emit color codes in output (Alias:
--no-colours)
--compat-options OPTS Options that can help keep compatibility --compat-options OPTS Options that can help keep compatibility
with youtube-dl or youtube-dlc with youtube-dl or youtube-dlc
configurations by reverting some of the configurations by reverting some of the

View File

@ -1053,6 +1053,7 @@ def test_selection(params, expected_ids, evaluate_all=False):
for v in get_downloaded_info_dicts(params, entries)] for v in get_downloaded_info_dicts(params, entries)]
self.assertEqual(results, list(enumerate(zip(expected_ids, expected_ids))), f'Entries of {name} for {params}') self.assertEqual(results, list(enumerate(zip(expected_ids, expected_ids))), f'Entries of {name} for {params}')
self.assertEqual(sorted(evaluated), expected_eval, f'Evaluation of {name} for {params}') self.assertEqual(sorted(evaluated), expected_eval, f'Evaluation of {name} for {params}')
test_selection({}, INDICES) test_selection({}, INDICES)
test_selection({'playlistend': 20}, INDICES, True) test_selection({'playlistend': 20}, INDICES, True)
test_selection({'playlistend': 2}, INDICES[:2]) test_selection({'playlistend': 2}, INDICES[:2])

View File

@ -3198,8 +3198,8 @@ def ffmpeg_fixup(cndn, msg, cls):
if not postprocessed_by_ffmpeg: if not postprocessed_by_ffmpeg:
ffmpeg_fixup(ext == 'm4a' and info_dict.get('container') == 'm4a_dash', ffmpeg_fixup(ext == 'm4a' and info_dict.get('container') == 'm4a_dash',
'writing DASH m4a. Only some players support this container', 'writing DASH m4a. Only some players support this container',
FFmpegFixupM4aPP) FFmpegFixupM4aPP)
ffmpeg_fixup(downloader == 'hlsnative' and not self.params.get('hls_use_mpegts') ffmpeg_fixup(downloader == 'hlsnative' and not self.params.get('hls_use_mpegts')
or info_dict.get('is_live') and self.params.get('hls_use_mpegts') is None, or info_dict.get('is_live') and self.params.get('hls_use_mpegts') is None,
'Possible MPEG-TS in MP4 container or malformed AAC timestamps', 'Possible MPEG-TS in MP4 container or malformed AAC timestamps',

View File

@ -2,6 +2,7 @@
__license__ = 'Public Domain' __license__ = 'Public Domain'
import collections
import getpass import getpass
import itertools import itertools
import optparse import optparse
@ -516,7 +517,7 @@ def report_deprecation(val, old, new=None):
# Do not unnecessarily download audio # Do not unnecessarily download audio
opts.format = 'bestaudio/best' opts.format = 'bestaudio/best'
if opts.getcomments and opts.writeinfojson is None: if opts.getcomments and opts.writeinfojson is None and not opts.embed_infojson:
# If JSON is not printed anywhere, but comments are requested, save it to file # If JSON is not printed anywhere, but comments are requested, save it to file
if not opts.dumpjson or opts.print_json or opts.dump_single_json: if not opts.dumpjson or opts.print_json or opts.dump_single_json:
opts.writeinfojson = True opts.writeinfojson = True
@ -665,8 +666,11 @@ def get_postprocessors(opts):
} }
ParsedOptions = collections.namedtuple('ParsedOptions', ('parser', 'options', 'urls', 'ydl_opts'))
def parse_options(argv=None): def parse_options(argv=None):
""" @returns (parser, opts, urls, ydl_opts) """ """@returns ParsedOptions(parser, opts, urls, ydl_opts)"""
parser, opts, urls = parseOpts(argv) parser, opts, urls = parseOpts(argv)
urls = get_urls(urls, opts.batchfile, opts.verbose) urls = get_urls(urls, opts.batchfile, opts.verbose)
@ -690,7 +694,7 @@ def parse_options(argv=None):
else opts.audioformat if (opts.extractaudio and opts.audioformat in FFmpegExtractAudioPP.SUPPORTED_EXTS) else opts.audioformat if (opts.extractaudio and opts.audioformat in FFmpegExtractAudioPP.SUPPORTED_EXTS)
else None) else None)
return parser, opts, urls, { return ParsedOptions(parser, opts, urls, {
'usenetrc': opts.usenetrc, 'usenetrc': opts.usenetrc,
'netrc_location': opts.netrc_location, 'netrc_location': opts.netrc_location,
'username': opts.username, 'username': opts.username,
@ -863,7 +867,7 @@ def parse_options(argv=None):
'_warnings': warnings, '_warnings': warnings,
'_deprecation_warnings': deprecation_warnings, '_deprecation_warnings': deprecation_warnings,
'compat_opts': opts.compat_opts, 'compat_opts': opts.compat_opts,
} })
def _real_main(argv=None): def _real_main(argv=None):

View File

@ -428,9 +428,9 @@ def _alias_callback(option, opt_str, value, parser, opts, nargs):
action='store_false', dest='mark_watched', action='store_false', dest='mark_watched',
help='Do not mark videos watched (default)') help='Do not mark videos watched (default)')
general.add_option( general.add_option(
'--no-colors', '--no-colors', '--no-colours',
action='store_true', dest='no_color', default=False, action='store_true', dest='no_color', default=False,
help='Do not emit color codes in output') help='Do not emit color codes in output (Alias: --no-colours)')
general.add_option( general.add_option(
'--compat-options', '--compat-options',
metavar='OPTS', dest='compat_opts', default=set(), type='str', metavar='OPTS', dest='compat_opts', default=set(), type='str',

View File

@ -725,11 +725,10 @@ def add(meta_list, info_list=None):
value = value.replace('\0', '') # nul character cannot be passed in command line value = value.replace('\0', '') # nul character cannot be passed in command line
metadata['common'].update({meta_f: value for meta_f in variadic(meta_list)}) metadata['common'].update({meta_f: value for meta_f in variadic(meta_list)})
# See [1-4] for some info on media metadata/metadata supported # Info on media metadata/metadata supported by ffmpeg:
# by ffmpeg. # https://wiki.multimedia.cx/index.php/FFmpeg_Metadata
# 1. https://kdenlive.org/en/project/adding-meta-data-to-mp4-video/ # https://kdenlive.org/en/project/adding-meta-data-to-mp4-video/
# 2. https://wiki.multimedia.cx/index.php/FFmpeg_Metadata # https://kodi.wiki/view/Video_file_tagging
# 3. https://kodi.wiki/view/Video_file_tagging
add('title', ('track', 'title')) add('title', ('track', 'title'))
add('date', 'upload_date') add('date', 'upload_date')

View File

@ -1908,6 +1908,10 @@ def __contains__(self, date):
def __str__(self): def __str__(self):
return f'{self.start.isoformat()} - {self.end.isoformat()}' return f'{self.start.isoformat()} - {self.end.isoformat()}'
def __eq__(self, other):
return (isinstance(other, DateRange)
and self.start == other.start and self.end == other.end)
def platform_name(): def platform_name():
""" Returns the platform name as a str """ """ Returns the platform name as a str """
@ -2660,7 +2664,7 @@ def exhaust(self):
@staticmethod @staticmethod
def _reverse_index(x): def _reverse_index(x):
return None if x is None else -(x + 1) return None if x is None else ~x
def __getitem__(self, idx): def __getitem__(self, idx):
if isinstance(idx, slice): if isinstance(idx, slice):
@ -3662,21 +3666,26 @@ def _match_func(info_dict, incomplete=False):
return _match_func return _match_func
def download_range_func(chapters, ranges): class download_range_func:
def inner(info_dict, ydl): def __init__(self, chapters, ranges):
self.chapters, self.ranges = chapters, ranges
def __call__(self, info_dict, ydl):
warning = ('There are no chapters matching the regex' if info_dict.get('chapters') warning = ('There are no chapters matching the regex' if info_dict.get('chapters')
else 'Cannot match chapters since chapter information is unavailable') else 'Cannot match chapters since chapter information is unavailable')
for regex in chapters or []: for regex in self.chapters or []:
for i, chapter in enumerate(info_dict.get('chapters') or []): for i, chapter in enumerate(info_dict.get('chapters') or []):
if re.search(regex, chapter['title']): if re.search(regex, chapter['title']):
warning = None warning = None
yield {**chapter, 'index': i} yield {**chapter, 'index': i}
if chapters and warning: if self.chapters and warning:
ydl.to_screen(f'[info] {info_dict["id"]}: {warning}') ydl.to_screen(f'[info] {info_dict["id"]}: {warning}')
yield from ({'start_time': start, 'end_time': end} for start, end in ranges or []) yield from ({'start_time': start, 'end_time': end} for start, end in self.ranges or [])
return inner def __eq__(self, other):
return (isinstance(other, download_range_func)
and self.chapters == other.chapters and self.ranges == other.ranges)
def parse_dfxp_time_expr(time_expr): def parse_dfxp_time_expr(time_expr):