mirror of
https://github.com/iluvcapra/ptulsconv.git
synced 2025-12-31 17:00:46 +00:00
Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
22edecdbbf | ||
|
|
7c8a74aed9 | ||
|
|
96a4cdb612 | ||
|
|
8720087bb2 | ||
|
|
f734aae227 | ||
|
|
17e9c77ed7 | ||
|
|
fc7dde8fd6 | ||
|
|
3021721299 | ||
|
|
cf9be9abf1 | ||
|
|
73936510cd | ||
|
|
d118554443 | ||
|
|
22c205d638 | ||
|
|
36ac320b44 | ||
|
|
6fe0ff4314 | ||
|
|
a23119eb8c | ||
|
|
af29318a0c |
29
.github/workflows/pythonpublish.yml
vendored
Normal file
29
.github/workflows/pythonpublish.yml
vendored
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
name: Upload Python Package
|
||||||
|
|
||||||
|
on:
|
||||||
|
release:
|
||||||
|
types: [created]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
deploy:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v1
|
||||||
|
- name: Set up Python
|
||||||
|
uses: actions/setup-python@v1
|
||||||
|
with:
|
||||||
|
python-version: '3.x'
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
python -m pip install --upgrade pip
|
||||||
|
pip install setuptools wheel twine
|
||||||
|
- name: Install parsimonious
|
||||||
|
run: |
|
||||||
|
pip install parsimonious
|
||||||
|
- name: Build and publish
|
||||||
|
env:
|
||||||
|
TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
|
||||||
|
TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
|
||||||
|
run: |
|
||||||
|
python setup.py sdist bdist_wheel
|
||||||
|
twine upload dist/*
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
language: python
|
language: python
|
||||||
python:
|
python:
|
||||||
- "3.7"
|
- "3.7"
|
||||||
|
- "3.8
|
||||||
script:
|
script:
|
||||||
- "python -m unittest discover tests"
|
- "python -m unittest discover tests"
|
||||||
install:
|
install:
|
||||||
|
|||||||
@@ -110,8 +110,3 @@ A clip name beginning with "&" will have its parsed clip name appended to the pr
|
|||||||
cues will be applied (later clips having precedence). The clips need not be touching, and the clips will be combined
|
cues will be applied (later clips having precedence). The clips need not be touching, and the clips will be combined
|
||||||
into a single row of the output. The start time of the first clip will become the start time of the row, and the finish
|
into a single row of the output. The start time of the first clip will become the start time of the row, and the finish
|
||||||
time of the last clip will become the finish time of the row.
|
time of the last clip will become the finish time of the row.
|
||||||
|
|
||||||
## Other Projects
|
|
||||||
|
|
||||||
This project is under construction. Look at [Pro Tools Text](https://github.com/iluvcapra/ProToolsText)
|
|
||||||
for a working solution at this time.
|
|
||||||
|
|||||||
@@ -2,6 +2,6 @@ from .ptuls_grammar import protools_text_export_grammar
|
|||||||
from .ptuls_parser_visitor import DictionaryParserVisitor
|
from .ptuls_parser_visitor import DictionaryParserVisitor
|
||||||
from .transformations import TimecodeInterpreter
|
from .transformations import TimecodeInterpreter
|
||||||
|
|
||||||
__version__ = '0.1.0'
|
__version__ = '0.3.3'
|
||||||
__author__ = 'Jamie Hardt'
|
__author__ = 'Jamie Hardt'
|
||||||
__license__ = 'MIT'
|
__license__ = 'MIT'
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
from ptulsconv.commands import convert, dump_field_map
|
from ptulsconv.commands import convert, dump_field_map
|
||||||
from ptulsconv import __version__, __author__
|
from ptulsconv import __name__, __version__, __author__
|
||||||
from optparse import OptionParser
|
from optparse import OptionParser, OptionGroup
|
||||||
from .reporting import print_status_style, print_banner_style, print_section_header_style, print_fatal_error
|
from .reporting import print_status_style, print_banner_style, print_section_header_style, print_fatal_error
|
||||||
import datetime
|
import datetime
|
||||||
import sys
|
import sys
|
||||||
@@ -8,6 +8,7 @@ import sys
|
|||||||
def main():
|
def main():
|
||||||
parser = OptionParser()
|
parser = OptionParser()
|
||||||
parser.usage = "ptulsconv TEXT_EXPORT.txt"
|
parser.usage = "ptulsconv TEXT_EXPORT.txt"
|
||||||
|
|
||||||
parser.add_option('-i', dest='in_time', help="Don't output events occurring before this timecode, and offset"
|
parser.add_option('-i', dest='in_time', help="Don't output events occurring before this timecode, and offset"
|
||||||
" all events relative to this timecode.", metavar='TC')
|
" all events relative to this timecode.", metavar='TC')
|
||||||
parser.add_option('-o', dest='out_time', help="Don't output events occurring after this timecode.", metavar='TC')
|
parser.add_option('-o', dest='out_time', help="Don't output events occurring after this timecode.", metavar='TC')
|
||||||
@@ -16,13 +17,13 @@ def main():
|
|||||||
parser.add_option('-m', '--include-muted', default=False, action='store_true', dest='include_muted',
|
parser.add_option('-m', '--include-muted', default=False, action='store_true', dest='include_muted',
|
||||||
help='Read muted clips.')
|
help='Read muted clips.')
|
||||||
|
|
||||||
parser.add_option('--show-tags', dest='show_tags',
|
parser.add_option('--show-available-tags', dest='show_tags',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
default=False, help='Display tag mappings for the FMP XML output style and exit.')
|
default=False, help='Display tag mappings for the FMP XML output style and exit.')
|
||||||
|
|
||||||
(options, args) = parser.parse_args(sys.argv)
|
(options, args) = parser.parse_args(sys.argv)
|
||||||
|
|
||||||
print_banner_style("ptulsconv %s (c) 2019 %s. All rights reserved." % (__version__, __author__))
|
print_banner_style("%s %s (c) 2019 %s. All rights reserved." % (__name__, __version__, __author__))
|
||||||
|
|
||||||
print_section_header_style("Startup")
|
print_section_header_style("Startup")
|
||||||
print_status_style("This run started %s" % (datetime.datetime.now().isoformat() ) )
|
print_status_style("This run started %s" % (datetime.datetime.now().isoformat() ) )
|
||||||
|
|||||||
@@ -191,8 +191,11 @@ class TagInterpreter(Transformation):
|
|||||||
assert len(transformed) > 0, "First clip is in '&'-Append mode, fatal error."
|
assert len(transformed) > 0, "First clip is in '&'-Append mode, fatal error."
|
||||||
|
|
||||||
transformed[-1].update(clip_tags['tags'])
|
transformed[-1].update(clip_tags['tags'])
|
||||||
transformed[-1]['event_name'] = transformed[-1]['event_name'] + " " + clip_tags['line']
|
transformed[-1]['PT.Clip.Name'] = transformed[-1]['PT.Clip.Name'] + " " + clip_tags['line']
|
||||||
transformed[-1]['PT.Clip.End_Frames'] = clip['end_time_decoded']['frame_count']
|
transformed[-1]['PT.Clip.Finish_Frames'] = clip['end_time_decoded']['frame_count']
|
||||||
|
transformed[-1]['PT.Clip.Finish'] = clip['end_time']
|
||||||
|
transformed[-1]['PT.Clip.Finish_Seconds'] = clip['end_time_decoded']['frame_count'] / input_dict['header'][
|
||||||
|
'timecode_format']
|
||||||
|
|
||||||
elif clip_tags['mode'] == 'Timespan':
|
elif clip_tags['mode'] == 'Timespan':
|
||||||
rule = dict(start_time=clip_start,
|
rule = dict(start_time=clip_start,
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
#!/bin/zsh
|
|
||||||
python3 setup.py build
|
|
||||||
python3 setup.py sdist bdist_wheel
|
|
||||||
python3 -m twine upload --repository-url https://upload.pypi.org/legacy/ dist/*
|
|
||||||
3
setup.py
3
setup.py
@@ -24,12 +24,13 @@ setup(name='ptulsconv',
|
|||||||
'Topic :: Multimedia',
|
'Topic :: Multimedia',
|
||||||
'Topic :: Multimedia :: Sound/Audio',
|
'Topic :: Multimedia :: Sound/Audio',
|
||||||
"Programming Language :: Python :: 3.7",
|
"Programming Language :: Python :: 3.7",
|
||||||
|
"Programming Language :: Python :: 3.8",
|
||||||
"Development Status :: 4 - Beta",
|
"Development Status :: 4 - Beta",
|
||||||
"Topic :: Text Processing :: Filters",
|
"Topic :: Text Processing :: Filters",
|
||||||
"Topic :: Text Processing :: Markup :: XML"],
|
"Topic :: Text Processing :: Markup :: XML"],
|
||||||
packages=['ptulsconv'],
|
packages=['ptulsconv'],
|
||||||
keywords='text-processing parsers film tv editing editorial',
|
keywords='text-processing parsers film tv editing editorial',
|
||||||
install_requires=['parsimonious','tqdm'],
|
install_requires=['parsimonious', 'tqdm'],
|
||||||
entry_points={
|
entry_points={
|
||||||
'console_scripts': [
|
'console_scripts': [
|
||||||
'ptulsconv = ptulsconv.__main__:main'
|
'ptulsconv = ptulsconv.__main__:main'
|
||||||
|
|||||||
BIN
tests/export_cases/Tag Tests/Tag Tests.ptx
Normal file
BIN
tests/export_cases/Tag Tests/Tag Tests.ptx
Normal file
Binary file not shown.
100
tests/export_cases/Tag Tests/Tag Tests.txt
Normal file
100
tests/export_cases/Tag Tests/Tag Tests.txt
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
SESSION NAME: Tag Tests
|
||||||
|
SAMPLE RATE: 48000.000000
|
||||||
|
BIT DEPTH: 24-bit
|
||||||
|
SESSION START TIMECODE: 01:00:00:00
|
||||||
|
TIMECODE FORMAT: 23.976 Frame
|
||||||
|
# OF AUDIO TRACKS: 8
|
||||||
|
# OF AUDIO CLIPS: 0
|
||||||
|
# OF AUDIO FILES: 0
|
||||||
|
|
||||||
|
|
||||||
|
P L U G - I N S L I S T I N G
|
||||||
|
MANUFACTURER PLUG-IN NAME VERSION FORMAT STEMS NUMBER OF INSTANCES
|
||||||
|
|
||||||
|
|
||||||
|
T R A C K L I S T I N G
|
||||||
|
TRACK NAME: Audio 1
|
||||||
|
COMMENTS:
|
||||||
|
USER DELAY: 0 Samples
|
||||||
|
STATE:
|
||||||
|
PLUG-INS:
|
||||||
|
CHANNEL EVENT CLIP NAME START TIME END TIME DURATION STATE
|
||||||
|
1 1 Clip Name {X=300} 01:00:00:00 01:00:05:03 00:00:05:03 Unmuted
|
||||||
|
|
||||||
|
|
||||||
|
TRACK NAME: Audio 2 $A=1
|
||||||
|
COMMENTS:
|
||||||
|
USER DELAY: 0 Samples
|
||||||
|
STATE:
|
||||||
|
PLUG-INS:
|
||||||
|
CHANNEL EVENT CLIP NAME START TIME END TIME DURATION STATE
|
||||||
|
1 1 Lorem ipsum {X=301} 01:00:00:00 01:00:05:03 00:00:05:03 Unmuted
|
||||||
|
1 2 Dolor sic amet {X=302} 01:00:10:00 01:00:20:00 00:00:10:00 Unmuted
|
||||||
|
1 3 & the rain in spain [ABC] 01:00:20:00 01:00:25:00 00:00:05:00 Unmuted
|
||||||
|
|
||||||
|
|
||||||
|
TRACK NAME: Audio 3 $A=2
|
||||||
|
COMMENTS: {B=100}
|
||||||
|
USER DELAY: 0 Samples
|
||||||
|
STATE:
|
||||||
|
PLUG-INS:
|
||||||
|
CHANNEL EVENT CLIP NAME START TIME END TIME DURATION STATE
|
||||||
|
1 1 A 01:00:15:00 01:00:25:00 00:00:10:00 Unmuted
|
||||||
|
1 2 & B 01:00:25:00 01:00:35:00 00:00:10:00 Unmuted
|
||||||
|
1 3 & C 01:00:35:00 01:00:45:00 00:00:10:00 Unmuted
|
||||||
|
|
||||||
|
|
||||||
|
TRACK NAME: Audio 4 $A=3
|
||||||
|
COMMENTS: $A=4
|
||||||
|
USER DELAY: 0 Samples
|
||||||
|
STATE:
|
||||||
|
PLUG-INS:
|
||||||
|
CHANNEL EVENT CLIP NAME START TIME END TIME DURATION STATE
|
||||||
|
1 1 Silver Bridge 01:00:00:00 01:00:05:00 00:00:05:00 Unmuted
|
||||||
|
|
||||||
|
|
||||||
|
TRACK NAME: Audio 5
|
||||||
|
COMMENTS:
|
||||||
|
USER DELAY: 0 Samples
|
||||||
|
STATE:
|
||||||
|
PLUG-INS:
|
||||||
|
CHANNEL EVENT CLIP NAME START TIME END TIME DURATION STATE
|
||||||
|
1 1 @ {D=100} 01:00:00:00 01:00:10:00 00:00:10:00 Unmuted
|
||||||
|
1 2 @ {D=101} 01:00:10:00 01:00:20:00 00:00:10:00 Unmuted
|
||||||
|
1 3 @ {D=102} 01:00:20:00 01:00:30:00 00:00:10:00 Unmuted
|
||||||
|
|
||||||
|
|
||||||
|
TRACK NAME: Audio 6
|
||||||
|
COMMENTS:
|
||||||
|
USER DELAY: 0 Samples
|
||||||
|
STATE:
|
||||||
|
PLUG-INS:
|
||||||
|
CHANNEL EVENT CLIP NAME START TIME END TIME DURATION STATE
|
||||||
|
1 1 Region 02 01:00:02:00 01:00:03:00 00:00:01:00 Unmuted
|
||||||
|
1 2 Region 12 01:00:12:00 01:00:13:00 00:00:01:00 Unmuted
|
||||||
|
1 3 Region 22 01:00:22:00 01:00:23:00 00:00:01:00 Unmuted
|
||||||
|
|
||||||
|
|
||||||
|
TRACK NAME: Audio 7
|
||||||
|
COMMENTS:
|
||||||
|
USER DELAY: 0 Samples
|
||||||
|
STATE:
|
||||||
|
PLUG-INS:
|
||||||
|
CHANNEL EVENT CLIP NAME START TIME END TIME DURATION STATE
|
||||||
|
1 1 @ {D=200} {E=101} 01:00:00:00 01:00:10:00 00:00:10:00 Unmuted
|
||||||
|
|
||||||
|
|
||||||
|
TRACK NAME: Audio 8
|
||||||
|
COMMENTS:
|
||||||
|
USER DELAY: 0 Samples
|
||||||
|
STATE:
|
||||||
|
PLUG-INS:
|
||||||
|
CHANNEL EVENT CLIP NAME START TIME END TIME DURATION STATE
|
||||||
|
1 1 Region 04 01:00:04:00 01:00:05:00 00:00:01:00 Unmuted
|
||||||
|
|
||||||
|
|
||||||
|
M A R K E R S L I S T I N G
|
||||||
|
# LOCATION TIME REFERENCE UNITS NAME COMMENTS
|
||||||
|
3 01:00:05:00 240240 Samples Marker $M=0
|
||||||
|
1 01:00:10:00 480480 Samples $M=1
|
||||||
|
2 01:00:22:00 1057056 Samples $M=2
|
||||||
92
tests/test_tagging.py
Normal file
92
tests/test_tagging.py
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
import unittest
|
||||||
|
import ptulsconv
|
||||||
|
import os.path
|
||||||
|
|
||||||
|
class TaggingIntegratedTests(unittest.TestCase):
|
||||||
|
|
||||||
|
path = os.path.dirname(__file__) + '/export_cases/Tag Tests/Tag Tests.txt'
|
||||||
|
|
||||||
|
def test_event_list(self):
|
||||||
|
with open(self.path, 'r') as f:
|
||||||
|
visitor = ptulsconv.DictionaryParserVisitor()
|
||||||
|
result = ptulsconv.protools_text_export_grammar.parse(f.read())
|
||||||
|
parsed: dict = visitor.visit(result)
|
||||||
|
|
||||||
|
tcxform = ptulsconv.transformations.TimecodeInterpreter()
|
||||||
|
tagxform = ptulsconv.transformations.TagInterpreter(show_progress=False,
|
||||||
|
ignore_muted=True,
|
||||||
|
log_output=False)
|
||||||
|
|
||||||
|
parsed = tcxform.transform(parsed)
|
||||||
|
parsed = tagxform.transform(parsed)
|
||||||
|
|
||||||
|
self.assertEqual(9, len(parsed['events']))
|
||||||
|
self.assertEqual("Clip Name", parsed['events'][0]['PT.Clip.Name'])
|
||||||
|
self.assertEqual("Lorem ipsum" , parsed['events'][1]['PT.Clip.Name'])
|
||||||
|
self.assertEqual("Dolor sic amet the rain in spain" , parsed['events'][2]['PT.Clip.Name'])
|
||||||
|
self.assertEqual("A B C" , parsed['events'][3]['PT.Clip.Name'])
|
||||||
|
self.assertEqual("Silver Bridge" , parsed['events'][4]['PT.Clip.Name'])
|
||||||
|
self.assertEqual("Region 02" , parsed['events'][5]['PT.Clip.Name'])
|
||||||
|
self.assertEqual("Region 12" , parsed['events'][6]['PT.Clip.Name'])
|
||||||
|
self.assertEqual("Region 22" , parsed['events'][7]['PT.Clip.Name'])
|
||||||
|
self.assertEqual("Region 04" , parsed['events'][8]['PT.Clip.Name'])
|
||||||
|
|
||||||
|
def test_append(self):
|
||||||
|
with open(self.path, 'r') as f:
|
||||||
|
visitor = ptulsconv.DictionaryParserVisitor()
|
||||||
|
result = ptulsconv.protools_text_export_grammar.parse(f.read())
|
||||||
|
parsed: dict = visitor.visit(result)
|
||||||
|
|
||||||
|
tcxform = ptulsconv.transformations.TimecodeInterpreter()
|
||||||
|
tagxform = ptulsconv.transformations.TagInterpreter(show_progress=False,
|
||||||
|
ignore_muted=True,
|
||||||
|
log_output=False)
|
||||||
|
|
||||||
|
parsed = tcxform.transform(parsed)
|
||||||
|
parsed = tagxform.transform(parsed)
|
||||||
|
|
||||||
|
self.assertTrue(len(parsed['events']) > 2)
|
||||||
|
|
||||||
|
self.assertEqual("Dolor sic amet the rain in spain",
|
||||||
|
parsed['events'][2]['PT.Clip.Name'])
|
||||||
|
|
||||||
|
self.assertTrue("01:00:10:00", parsed['events'][2]['PT.Clip.Start'])
|
||||||
|
self.assertTrue("01:00:25:00", parsed['events'][2]['PT.Clip.Finish'])
|
||||||
|
self.assertTrue(240, parsed['events'][2]['PT.Clip.Start_Frames'])
|
||||||
|
self.assertTrue(600, parsed['events'][2]['PT.Clip.Finish_Frames'])
|
||||||
|
|
||||||
|
self.assertIn('X', parsed['events'][2].keys())
|
||||||
|
self.assertIn('ABC', parsed['events'][2].keys())
|
||||||
|
self.assertIn('A', parsed['events'][2].keys())
|
||||||
|
self.assertEqual('302', parsed['events'][2]['X'])
|
||||||
|
self.assertEqual('ABC', parsed['events'][2]['ABC'])
|
||||||
|
self.assertEqual('1', parsed['events'][2]['A'])
|
||||||
|
|
||||||
|
def test_successive_appends(self):
|
||||||
|
with open(self.path, 'r') as f:
|
||||||
|
visitor = ptulsconv.DictionaryParserVisitor()
|
||||||
|
result = ptulsconv.protools_text_export_grammar.parse(f.read())
|
||||||
|
parsed: dict = visitor.visit(result)
|
||||||
|
|
||||||
|
tcxform = ptulsconv.transformations.TimecodeInterpreter()
|
||||||
|
tagxform = ptulsconv.transformations.TagInterpreter(show_progress=False,
|
||||||
|
ignore_muted=True,
|
||||||
|
log_output=False)
|
||||||
|
|
||||||
|
parsed = tcxform.transform(parsed)
|
||||||
|
parsed = tagxform.transform(parsed)
|
||||||
|
|
||||||
|
self.assertTrue(len(parsed['events']) > 3)
|
||||||
|
|
||||||
|
self.assertEqual("A B C",
|
||||||
|
parsed['events'][3]['PT.Clip.Name'])
|
||||||
|
|
||||||
|
self.assertTrue("01:00:15:00", parsed['events'][3]['PT.Clip.Start'])
|
||||||
|
self.assertTrue("01:00:45:00", parsed['events'][3]['PT.Clip.Finish'])
|
||||||
|
self.assertTrue(80, parsed['events'][3]['PT.Clip.Start_Frames'])
|
||||||
|
self.assertTrue(1080, parsed['events'][3]['PT.Clip.Finish_Frames'])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
||||||
Reference in New Issue
Block a user