33 Commits

Author SHA1 Message Date
Jamie Hardt
ec42ee1d3d Update pythonpublish.yml
Added a Report to mastadon action
2022-11-20 12:22:39 -08:00
Jamie Hardt
bba4d67641 Streamlined requirements
Separated reqs into project and docs venvs
2022-11-20 12:12:24 -08:00
Jamie Hardt
4bc7f94198 Twiddle 2022-11-18 22:44:20 -08:00
Jamie Hardt
14eb8df496 Delete .idea directory 2022-11-16 21:15:53 -08:00
Jamie Hardt
a3aee8e785 Update LICENSE 2022-11-16 21:14:10 -08:00
Jamie Hardt
9e9b6b512b Update README.md 2022-11-16 20:57:03 -08:00
Jamie Hardt
a3365c113d Update metadata.py 2022-11-16 20:44:52 -08:00
Jamie Hardt
fbf4d72915 Added a punch of type annotations
For documentation
2022-11-16 20:40:07 -08:00
Jamie Hardt
90f273cf99 Merge branch 'master' of https://github.com/iluvcapra/wavinfo 2022-11-16 20:37:39 -08:00
Jamie Hardt
bec3d98ee7 Added some type annotations for doc help 2022-11-16 20:23:35 -08:00
Jamie Hardt
a87bc71755 Update .readthedocs.yaml 2022-11-16 20:05:26 -08:00
Jamie Hardt
4817e7eb49 Update .readthedocs.yaml 2022-11-16 20:04:35 -08:00
Jamie Hardt
07832f7133 Merge branch 'master' of https://github.com/iluvcapra/wavinfo 2022-11-16 20:02:45 -08:00
Jamie Hardt
f3d03296d5 source 2022-11-16 20:02:24 -08:00
Jamie Hardt
9496912b15 Update .readthedocs.yaml 2022-11-16 19:57:49 -08:00
Jamie Hardt
1077b49ce0 Update .readthedocs.yaml 2022-11-16 19:54:50 -08:00
Jamie Hardt
90042d57b2 Reorg doc files 2022-11-16 19:49:59 -08:00
Jamie Hardt
f12d7dfea0 Merge branch 'master' of https://github.com/iluvcapra/wavinfo 2022-11-16 19:49:44 -08:00
Jamie Hardt
c2327568a8 Tweaked docs/conf 2022-11-16 19:42:23 -08:00
Jamie Hardt
722df48f9b Added docs/source dir 2022-11-16 19:41:31 -08:00
Jamie Hardt
17c0357364 Moved sources to new folder 2022-11-16 19:41:10 -08:00
Jamie Hardt
7e88c46d54 Update conf.py 2022-11-16 19:39:09 -08:00
Jamie Hardt
df90c67a73 Update conf.py 2022-11-16 19:33:01 -08:00
Jamie Hardt
cc107bf65d Update .readthedocs.yaml 2022-11-16 19:31:36 -08:00
Jamie Hardt
f9c68e0995 Update .readthedocs.yaml 2022-11-16 19:31:03 -08:00
Jamie Hardt
a98dd2668a Update conf.py 2022-11-16 19:29:47 -08:00
Jamie Hardt
d8ff4ed63b Update .readthedocs.yaml 2022-11-16 19:28:36 -08:00
Jamie Hardt
084c3d7ae5 Create .readthedocs.yaml 2022-11-16 19:26:47 -08:00
Jamie Hardt
e69b71e989 Merge branch 'release' 2022-11-16 19:17:25 -08:00
Jamie Hardt
6fe6126f3a Updated docs 2022-11-16 19:15:51 -08:00
Jamie Hardt
e57c76a722 Update README.md 2022-11-15 11:35:59 -08:00
Jamie Hardt
e40a2c5471 Update pythonpublish.yml 2022-11-15 11:29:47 -08:00
Jamie Hardt
dec6180744 Update pythonpublish.yml 2022-11-15 11:27:34 -08:00
25 changed files with 177 additions and 274 deletions

View File

@@ -2,7 +2,7 @@ name: Upload Python Package
on:
release:
types: [created]
types: [published]
jobs:
deploy:
@@ -20,7 +20,17 @@ jobs:
- name: Build and publish
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
TWINE_PASSWORD: ${{ secrets.PYPI_APIKEY }}
run: |
python setup.py sdist bdist_wheel
twine upload dist/*
- name: Report to Mastodon
uses: cbrgm/mastodon-github-action@v1.0.1
with:
message: |
I just released a new version of wavinfo, my library for reading WAVE file metadata!
${{ github.server_url }}/${{ github.repository }}
env:
MASTODON_URL: ${{ secrets.MASTODON_URL }}
MASTODON_ACCESS_TOKEN: ${{ secrets.MASTODON_ACCESS_TOKEN }}

1
.gitignore vendored
View File

@@ -89,6 +89,7 @@ venv/
ENV/
env.bak/
venv.bak/
docs_venv/
# Spyder project settings
.spyderproject

7
.idea/misc.xml generated
View File

@@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.7 (wavinfo)" project-jdk-type="Python SDK" />
<component name="PyPackaging">
<option name="earlyReleasesAsUpgrades" value="true" />
</component>
</project>

10
.idea/wavinfo.iml generated
View File

@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/venv" />
</content>
<orderEntry type="jdk" jdkName="Python 3.7 (wavinfo)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

107
.idea/workspace.xml generated
View File

@@ -1,107 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ChangeListManager">
<list default="true" id="fb29ad56-fffe-478f-9c0e-1718aa04342e" name="Default Changelist" comment="">
<change beforePath="$PROJECT_DIR$/.idea/dictionaries/jamiehardt.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/dictionaries/jamiehardt.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/misc.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/misc.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/wavinfo.iml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/wavinfo.iml" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="FavoritesManager">
<favorites_list name="wavinfo" />
</component>
<component name="FileTemplateManagerImpl">
<option name="RECENT_TEMPLATES">
<list>
<option value="Python Script" />
</list>
</option>
</component>
<component name="Git.Settings">
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
<option name="UPDATE_TYPE" value="MERGE" />
</component>
<component name="ProjectId" id="1VtfP9ukGK4GNIXS2m0hRLG9d7w" />
<component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
<option name="showMembers" value="true" />
</component>
<component name="PropertiesComponent">
<property name="RunOnceActivity.ShowReadmeOnStart" value="true" />
<property name="TODO_SCOPE" value="Project Files" />
<property name="last_opened_file_path" value="$PROJECT_DIR$" />
<property name="settings.editor.selected.configurable" value="com.jetbrains.python.configuration.PyActiveSdkModuleConfigurable" />
</component>
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="project-level" UseSingleDictionary="true" transferred="true" />
<component name="SvnConfiguration">
<configuration />
</component>
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="fb29ad56-fffe-478f-9c0e-1718aa04342e" name="Default Changelist" comment="" />
<created>1578077284420</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1578077284420</updated>
</task>
<servers />
</component>
<component name="Vcs.Log.History.Properties">
<option name="COLUMN_ORDER">
<list>
<option value="0" />
<option value="2" />
<option value="3" />
<option value="1" />
</list>
</option>
</component>
<component name="Vcs.Log.Tabs.Properties">
<option name="TAB_STATES">
<map>
<entry key="MAIN">
<value>
<State />
</value>
</entry>
</map>
</option>
<option name="oldMeFiltersMigrated" value="true" />
</component>
<component name="WindowStateProjectService">
<state x="655" y="287" key="#com.intellij.openapi.updateSettings.impl.PluginUpdateInfoDialog" timestamp="1598547965709">
<screen x="0" y="0" width="1920" height="1080" />
</state>
<state x="655" y="287" key="#com.intellij.openapi.updateSettings.impl.PluginUpdateInfoDialog/1920.0.1920.1080/0.0.1920.1080/3840.0.1920.1080@0.0.1920.1080" timestamp="1598547965709" />
<state x="0" y="0" key="#com.intellij.refactoring.rename.AutomaticRenamingDialog" timestamp="1598555737671">
<screen x="0" y="0" width="1920" height="1080" />
</state>
<state x="0" y="0" key="#com.intellij.refactoring.rename.AutomaticRenamingDialog/1920.0.1920.1080/0.0.1920.1080/3840.0.1920.1080@0.0.1920.1080" timestamp="1598555737671" />
<state x="476" y="183" key="SettingsEditor" timestamp="1598548365517">
<screen x="0" y="0" width="1920" height="1080" />
</state>
<state x="476" y="183" key="SettingsEditor/1920.0.1920.1080/0.0.1920.1080/3840.0.1920.1080@0.0.1920.1080" timestamp="1598548365517" />
<state x="114" y="123" width="1706" height="842" key="com.intellij.history.integration.ui.views.FileHistoryDialog" timestamp="1597689482054">
<screen x="0" y="0" width="1920" height="1080" />
</state>
<state x="114" y="123" width="1706" height="842" key="com.intellij.history.integration.ui.views.FileHistoryDialog/1920.0.1920.1080/0.0.1920.1080/3840.0.1920.1080@0.0.1920.1080" timestamp="1597689482054" />
<state x="577" y="376" key="com.intellij.ide.util.TipDialog" timestamp="1601767353495">
<screen x="0" y="0" width="1920" height="1080" />
</state>
<state x="577" y="376" key="com.intellij.ide.util.TipDialog/1920.0.1920.1080/0.0.1920.1080/3840.0.1920.1080@0.0.1920.1080" timestamp="1598550975228" />
<state x="577" y="376" key="com.intellij.ide.util.TipDialog/1920.0.1920.1080/0.0.1920.1080@0.0.1920.1080" timestamp="1601767353495" />
<state x="772" y="468" key="com.intellij.openapi.vcs.update.UpdateOrStatusOptionsDialogupdate-v2" timestamp="1598547948993">
<screen x="0" y="0" width="1920" height="1080" />
</state>
<state x="772" y="468" key="com.intellij.openapi.vcs.update.UpdateOrStatusOptionsDialogupdate-v2/1920.0.1920.1080/0.0.1920.1080/3840.0.1920.1080@0.0.1920.1080" timestamp="1598547948993" />
<state x="632" y="254" width="670" height="676" key="search.everywhere.popup" timestamp="1598554315633">
<screen x="0" y="0" width="1920" height="1080" />
</state>
<state x="632" y="254" width="670" height="676" key="search.everywhere.popup/1920.0.1920.1080/0.0.1920.1080/3840.0.1920.1080@0.0.1920.1080" timestamp="1598554315633" />
</component>
</project>

29
.readthedocs.yaml Normal file
View File

@@ -0,0 +1,29 @@
# .readthedocs.yaml
# Read the Docs configuration file
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
# Required
version: 2
# Set the version of Python and other tools you might need
build:
os: ubuntu-20.04
tools:
python: "3.10"
# You can also specify other tool versions:
# nodejs: "16"
# rust: "1.55"
# golang: "1.17"
# Build documentation in the docs/ directory with Sphinx
sphinx:
configuration: docs/source/conf.py
#If using Sphinx, optionally build your docs in additional formats such as PDF
formats:
- pdf
#Optionally declare the Python requirements required to build your docs
python:
install:
- requirements: requirements.txt

3
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,3 @@
{
"esbonio.sphinx.confDir": ""
}

View File

@@ -1,6 +1,6 @@
MIT License
Copyright (c) 2020 Jamie Hardt
Copyright (c) 2022 Jamie Hardt
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@@ -1,7 +1,5 @@
[![Documentation Status](https://readthedocs.org/projects/wavinfo/badge/?version=latest)](https://wavinfo.readthedocs.io/en/latest/?badge=latest) ![](https://img.shields.io/github/license/iluvcapra/wavinfo.svg) ![](https://img.shields.io/pypi/pyversions/wavinfo.svg) [![](https://img.shields.io/pypi/v/wavinfo.svg)](https://pypi.org/project/wavinfo/) ![](https://img.shields.io/pypi/wheel/wavinfo.svg)
![Lint and Test](https://github.com/iluvcapra/wavinfo/actions/workflows/python-package.yml/badge.svg)
<!-- ![Test](https://github.com/iluvcapra/wavinfo/workflows/Upload%20Python%20Package/badge.svg) -->
[![Lint and Test](https://github.com/iluvcapra/wavinfo/actions/workflows/python-package.yml/badge.svg)](https://github.com/iluvcapra/wavinfo/actions/workflows/python-package.yml)
# wavinfo

View File

@@ -4,7 +4,7 @@
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
SOURCEDIR = .
SOURCEDIR = source
BUILDDIR = _build
# Put it first so that "make" without argument is like "make help".
@@ -16,4 +16,4 @@ help:
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

View File

@@ -1,35 +0,0 @@
@ECHO OFF
pushd %~dp0
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set SOURCEDIR=.
set BUILDDIR=_build
if "%1" == "" goto help
%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.http://sphinx-doc.org/
exit /b 1
)
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
goto end
:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
:end
popd

25
docs/requirements.txt Normal file
View File

@@ -0,0 +1,25 @@
alabaster==0.7.12
Babel==2.11.0
certifi==2022.9.24
charset-normalizer==2.1.1
docutils==0.17.1
idna==3.4
imagesize==1.4.1
Jinja2==3.1.2
lxml==4.9.1
MarkupSafe==2.1.1
packaging==21.3
Pygments==2.13.0
pyparsing==3.0.9
pytz==2022.6
requests==2.28.1
snowballstemmer==2.2.0
Sphinx==5.3.0
sphinx-rtd-theme==1.1.1
sphinxcontrib-applehelp==1.0.2
sphinxcontrib-devhelp==1.0.2
sphinxcontrib-htmlhelp==2.0.0
sphinxcontrib-jsmath==1.0.1
sphinxcontrib-qthelp==1.0.3
sphinxcontrib-serializinghtml==1.1.5
urllib3==1.26.12

18
docs/source/classes.rst Normal file
View File

@@ -0,0 +1,18 @@
Other wavinfo Classes
===============
.. autoclass:: wavinfo.wave_reader.WavInfoReader
:members:
.. automethod:: __init__
.. autoclass:: wavinfo.wave_reader.WavAudioFormat
:members:
.. autoclass:: wavinfo.wave_reader.WavDataDescriptor
:members:

View File

@@ -14,19 +14,21 @@
#
import os
import sys
sys.path.insert(0, os.path.abspath('..'))
sys.path.insert(0, os.path.abspath('../..'))
sys.path.insert(0, os.path.abspath("../../.."))
print(sys.path)
# -- Project information -----------------------------------------------------
project = u'wavinfo'
copyright = u'2019, Jamie Hardt'
copyright = u'2022, Jamie Hardt'
author = u'Jamie Hardt'
# The short X.Y version
version = u''
# The full version, including alpha/beta/rc tags
release = u'v1.1'
release = u'v1.7.1'
# -- General configuration ---------------------------------------------------
@@ -61,7 +63,7 @@ master_doc = 'index'
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = None
language = 'en'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.

View File

@@ -6,30 +6,15 @@
Welcome to wavinfo's documentation!
===================================
.. module:: wavinfo
.. autoclass:: WavInfoReader
:members:
.. automethod:: __init__
.. autoclass:: wavinfo.wave_reader.WavAudioFormat
:members:
.. autoclass:: wavinfo.wave_reader.WavDataDescriptor
:members:
.. toctree::
:maxdepth: 2
:caption: Notes:
:caption: Notes
metadata_scopes/bext.rst
metadata_scopes/ixml.rst
metadata_scopes/info.rst
classes
Indices and tables

View File

@@ -1,11 +1,6 @@
Broadcast WAV Extension
=======================
.. module:: wavinfo
.. autoclass:: wavinfo.wave_bext_reader.WavBextReader
:members:
Notes
-----
@@ -63,3 +58,14 @@ Result:
Originator Time: 12:40:00
Time Reference: 2190940753
A=PCM,F=48000,W=24,M=stereo,R=48000,T=2 Ch
Class Reference
---------------
.. module:: wavinfo
.. autoclass:: wavinfo.wave_bext_reader.WavBextReader
:members:

View File

@@ -1,14 +1,6 @@
INFO Metadata
=============
.. module:: wavinfo
.. autoclass:: wavinfo.wave_info_reader.WavInfoChunkReader
:members:
Notes
-----
@@ -28,5 +20,14 @@ music library software.
print("INFO Comment:", bullet.info.comment)
Class Reference
---------------
.. module:: wavinfo
.. autoclass:: wavinfo.wave_info_reader.WavInfoChunkReader
:members:

View File

@@ -1,13 +1,6 @@
iXML Production Recorder Metadata
=================================
.. module:: wavinfo
.. autoclass:: wavinfo.wave_ixml_reader.WavIXMLFormat
:members:
Notes
-----
iXML allows an XML document to be embedded in a WAV file.
@@ -41,4 +34,12 @@ Result:
iXML File Family UID: USSDVGR1112089007124001008206300
Class Reference
---------------
.. module:: wavinfo
.. autoclass:: wavinfo.wave_ixml_reader.WavIXMLFormat
:members:

View File

@@ -1,6 +1,6 @@
"""
Wavinfo
"""
__version__ = '1.7.0'
__version__ = '1.7.2'
__author__ = 'Jamie Hardt <jamiehardt@gmail.com>'
__license__ = "MIT"

View File

@@ -1,19 +1 @@
attrs==21.4.0
ear==2.1.0
enum34==1.1.10
exceptiongroup==1.0.4
iniconfig==1.1.1
lxml==4.9.1
multipledispatch==0.6.0
numpy==1.23.3
packaging==21.3
pluggy==1.0.0
pyparsing==3.0.9
pytest==7.2.0
ruamel.yaml==0.17.21
ruamel.yaml.clib==0.2.6
scipy==1.9.1
six==1.16.0
style==1.1.0
tomli==2.0.1
update==0.0.1

View File

@@ -30,7 +30,7 @@ setup(name='wavinfo',
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10"],
keywords='waveform metadata audio ebu smpte avi library film tv editing editorial',
install_requires=['lxml', 'ear'],
install_requires=['lxml'],
entry_points={
'console_scripts': [
'wavinfo = wavinfo.__main__:main'

View File

@@ -1,5 +1,3 @@
from typing import Union
import binascii
from functools import reduce
@@ -13,7 +11,7 @@ class UMIDParser:
This implementation is based on SMPTE ST 330:2011
"""
def __init__(self, raw_umid: bytearray):
def __init__(self, raw_umid: bytes):
self.raw_umid = raw_umid
#
# @property

View File

@@ -1,7 +1,7 @@
import struct
import binascii
from .umid_parser import UMIDParser
from typing import Optional
class WavBextReader:
def __init__(self, bext_data, encoding):
@@ -16,44 +16,44 @@ class WavBextReader:
rest_starts = struct.calcsize(packstring)
unpacked = struct.unpack(packstring, bext_data[:rest_starts])
def sanitize_bytes(b):
def sanitize_bytes(b : bytes) -> str:
first_null = next((index for index, byte in enumerate(b) if byte == 0), None)
trimmed = b if first_null is None else b[:first_null]
decoded = trimmed.decode(encoding)
return decoded
#: Description. A free-text field up to 256 characters long.
self.description = sanitize_bytes(unpacked[0])
self.description : str = sanitize_bytes(unpacked[0])
#: Originator. Usually the name of the encoding application, sometimes
#: a artist name.
self.originator = sanitize_bytes(unpacked[1])
self.originator : str = sanitize_bytes(unpacked[1])
#: A unique identifier for the file, a serial number.
self.originator_ref = sanitize_bytes(unpacked[2])
self.originator_ref : str = sanitize_bytes(unpacked[2])
#: Date of the recording, in the format YYY-MM-DD
self.originator_date = sanitize_bytes(unpacked[3])
self.originator_date : str = sanitize_bytes(unpacked[3])
#: Time of the recording, in the format HH:MM:SS.
self.originator_time = sanitize_bytes(unpacked[4])
self.originator_time : str = sanitize_bytes(unpacked[4])
#: The sample offset of the start of the file relative to an
#: epoch, usually midnight the day of the recording.
self.time_reference = unpacked[5]
self.time_reference : int = unpacked[5]
#: A variable-length text field containing a list of processes and
#: and conversions performed on the file.
self.coding_history = sanitize_bytes(bext_data[rest_starts:])
self.coding_history : str = sanitize_bytes(bext_data[rest_starts:])
#: BEXT version.
self.version = unpacked[6]
self.version : int = unpacked[6]
#: SMPTE 330M UMID of this audio file, 64 bytes are allocated though the UMID
#: may only be 32 bytes long.
self.umid = None
self.umid : Optional[bytes] = None
#: EBU R128 Integrated loudness, in LUFS.
self.loudness_value = None
self.loudness_value : Optional[float] = None
#: EBU R128 Loudness rante, in LUFS.
self.loudness_range = None
self.loudness_range : Optional[float] = None
#: True peak level, in dBFS TP
self.max_true_peak = None
self.max_true_peak : Optional[float] = None
#: EBU R128 Maximum momentary loudness, in LUFS
self.max_momentary_loudness = None
self.max_momentary_loudness : Optional[float] = None
#: EBU R128 Maximum short-term loudness, in LUFS.
self.max_shortterm_loudness = None
self.max_shortterm_loudness : Optional[float] = None
if self.version > 0:
self.umid = unpacked[7]

View File

@@ -1,5 +1,6 @@
from .riff_parser import parse_chunk, ListChunkDescriptor
from typing import Optional
class WavInfoChunkReader:
@@ -14,40 +15,40 @@ class WavInfoChunkReader:
self.info_chunk = next((chunk for chunk in list_chunks if chunk.signature == b'INFO'), None)
#: 'ICOP' Copyright
self.copyright = self._get_field(f, b'ICOP')
self.copyright : Optional[str] = self._get_field(f, b'ICOP')
#: 'IPRD' Product
self.product = self._get_field(f, b'IPRD')
self.album = self.product
self.product : Optional[str]= self._get_field(f, b'IPRD')
self.album : Optional[str] = self.product
#: 'IGNR' Genre
self.genre = self._get_field(f, b'IGNR')
self.genre : Optional[str] = self._get_field(f, b'IGNR')
#: 'ISBJ' Supject
self.subject = self._get_field(f, b'ISBJ')
self.subject : Optional[str] = self._get_field(f, b'ISBJ')
#: 'IART' Artist, composer, author
self.artist = self._get_field(f, b'IART')
self.artist : Optional[str] = self._get_field(f, b'IART')
#: 'ICMT' Comment
self.comment = self._get_field(f, b'ICMT')
self.comment : Optional[str] = self._get_field(f, b'ICMT')
#: 'ISFT' Software, encoding application
self.software = self._get_field(f, b'ISFT')
self.software : Optional[str] = self._get_field(f, b'ISFT')
#: 'ICRD' Created date
self.created_date = self._get_field(f, b'ICRD')
self.created_date : Optional[str] = self._get_field(f, b'ICRD')
#: 'IENG' Engineer
self.engineer = self._get_field(f, b'IENG')
self.engineer : Optional[str] = self._get_field(f, b'IENG')
#: 'ITCH' Technician
self.technician = self._get_field(f, b'ITCH')
self.technician : Optional[str] = self._get_field(f, b'ITCH')
#: 'IKEY' Keywords, keyword list
self.keywords = self._get_field(f, b'IKEY')
self.keywords : Optional[str] = self._get_field(f, b'IKEY')
#: 'INAM' Name, title
self.title = self._get_field(f, b'INAM')
self.title : Optional[str] = self._get_field(f, b'INAM')
#: 'ISRC' Source
self.source = self._get_field(f, b'ISRC')
self.source : Optional[str] = self._get_field(f, b'ISRC')
#: 'TAPE' Tape
self.tape = self._get_field(f, b'TAPE')
self.tape : Optional[str] = self._get_field(f, b'TAPE')
#: 'IARL' Archival Location
self.archival_location = self._get_field(f, b'IARL')
self.archival_location : Optional[str] = self._get_field(f, b'IARL')
#: 'ICSM' Commissioned
self.commissioned = self._get_field(f, b'ICMS')
self.commissioned : Optional[str] = self._get_field(f, b'ICMS')
def _get_field(self, f, field_ident):
def _get_field(self, f, field_ident) -> Optional[str]:
search = next(((chunk.start, chunk.length) for chunk in self.info_chunk.children if chunk.ident == field_ident),
None)

View File

@@ -1,7 +1,7 @@
from lxml import etree as ET
import io
from collections import namedtuple
from typing import Optional
IXMLTrack = namedtuple('IXMLTrack', ['channel_index', 'interleave_index', 'name', 'function'])
@@ -20,10 +20,12 @@ class WavIXMLFormat:
parser = ET.XMLParser(recover=True)
self.parsed = ET.parse(xml_bytes, parser=parser)
def _get_text_value(self, xpath):
def _get_text_value(self, xpath) -> Optional[str]:
e = self.parsed.find("./" + xpath)
if e is not None:
return e.text
else:
return None
@property
def raw_xml(self):
@@ -46,35 +48,35 @@ class WavIXMLFormat:
function=track.xpath('string(FUNCTION/text())'))
@property
def project(self):
def project(self) -> Optional[str]:
"""
The project/film name entered for the recording.
"""
return self._get_text_value("PROJECT")
@property
def scene(self):
def scene(self) -> Optional[str]:
"""
Scene/slate.
"""
return self._get_text_value("SCENE")
@property
def take(self):
def take(self) -> Optional[str]:
"""
Take number.
"""
return self._get_text_value("TAKE")
@property
def tape(self):
def tape(self) -> Optional[str]:
"""
Tape name.
"""
return self._get_text_value("TAPE")
@property
def family_uid(self):
def family_uid(self) -> Optional[str]:
"""
The globally-unique ID for this file family. This may be in the format
of a GUID, or an EBU Rec 9 source identifier, or some other dumb number.
@@ -82,7 +84,7 @@ class WavIXMLFormat:
return self._get_text_value("FILE_SET/FAMILY_UID")
@property
def family_name(self):
def family_name(self) -> Optional[str]:
"""
The name of this file's file family.
"""