17 Commits

Author SHA1 Message Date
Jamie Hardt
a176d3b1f5 Update README.md
Added link to Quickstart
2022-11-06 14:20:02 -08:00
Jamie Hardt
8a6f5e755b Update QUICKSTART.md 2022-11-06 14:17:07 -08:00
Jamie Hardt
b4fef4b13f Update QUICKSTART.md 2022-11-06 14:00:39 -08:00
Jamie Hardt
6fc7f26e9c Some documentation 2022-11-06 13:59:56 -08:00
Jamie Hardt
09b3f9349b Update HOWTO.md 2022-11-06 13:25:52 -08:00
Jamie Hardt
f6ee807ede Create HOWTO.md 2022-11-06 13:19:30 -08:00
Jamie Hardt
f114012d4a Attempt at some online documentation 2022-11-06 13:05:15 -08:00
Jamie Hardt
c03b3dfb8d Merge branch 'master' of https://github.com/iluvcapra/ptulsconv 2022-11-06 12:27:26 -08:00
Jamie Hardt
d2da8f1cb0 Update __init__.py
Version 1.2.0
2022-11-06 12:26:53 -08:00
Jamie Hardt
10c0e4f038 Fixed regex statements in parser
This clears up a bunch of `DeprecationWarning`s in pytest
2022-11-06 12:25:25 -08:00
Jamie Hardt
6703184f8f Update pythonpublish.yml 2022-11-06 12:07:27 -08:00
Jamie Hardt
1c11e4d570 Update python-package.yml 2022-11-06 12:07:01 -08:00
Jamie Hardt
94317c288f Update python-package.yml 2022-11-06 12:05:08 -08:00
Jamie Hardt
9e374df367 Update pythonpublish.yml
Updated setup-python action
2022-11-06 12:03:02 -08:00
Jamie Hardt
fc2e823116 Merge branch 'master' of https://github.com/iluvcapra/ptulsconv 2022-11-06 11:54:03 -08:00
Jamie Hardt
fbc7531374 Include version string in all outputs 2022-11-06 11:54:00 -08:00
Jamie Hardt
1fb17b13ea Update pythonpublish.yml
Updated to API key publishing method instead of username-password, which is deprecated.
2022-11-06 11:15:53 -08:00
9 changed files with 225 additions and 18 deletions

View File

@@ -19,9 +19,9 @@ jobs:
python-version: [3.7, 3.8, 3.9, "3.10"] python-version: [3.7, 3.8, 3.9, "3.10"]
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2.5.0
- name: Set up Python ${{ matrix.python-version }} - name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2 uses: actions/setup-python@v4.3.0
with: with:
python-version: ${{ matrix.python-version }} python-version: ${{ matrix.python-version }}
- name: Install dependencies - name: Install dependencies

View File

@@ -8,9 +8,9 @@ jobs:
deploy: deploy:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v1 - uses: actions/checkout@v2.5.0
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v1 uses: actions/setup-python@v4.3.0
with: with:
python-version: '3.x' python-version: '3.x'
- name: Install dependencies - name: Install dependencies
@@ -22,8 +22,8 @@ jobs:
pip install parsimonious pip install parsimonious
- name: Build and publish - name: Build and publish
env: env:
TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }} TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} TWINE_PASSWORD: ${{ secrets.PYPI_UPLOAD_API_KEY }}
run: | run: |
python setup.py sdist bdist_wheel python setup.py sdist bdist_wheel
twine upload dist/* twine upload dist/*

View File

@@ -10,6 +10,10 @@
Read Pro Tools text exports and generate PDF reports, JSON output. Read Pro Tools text exports and generate PDF reports, JSON output.
## Quick Start
For a quick overview of how to cue ADR with `ptulsconv`, check out the [Quickstart](doc/QUICKSTART.md).
## Theory of Operation ## Theory of Operation

92
doc/HOWTO.md Normal file
View File

@@ -0,0 +1,92 @@
# How To Use `ptulsconv`
## Theory of Operation
[Avid Pro Tools][avp] exports a tab-delimited text file organized in multiple
parts with an uneven syntax that usually can't "drop in" to other tools like
Excel or Filemaker. `ptulsconv` will accept a text export from Pro Tools and,
by default, create a set of PDF reports useful for ADR reporting.
## Tagging
### Fields in Clip Names
Track names, track comments, and clip names can also contain meta-tags, or
"fields," to add additional columns to the CSV output. Thus, if a clip has the
name:
`Fireworks explosion {note=Replace for final} $V=1 [FX] [DESIGN]`
The row output for this clip will contain columns for the values:
|...| Clip Name| note | V | FX | DESIGN | ...|
|---|------------|------|---|----|--------|----|
|...| Fireworks explosion| Replace for final | 1 | FX | DESIGN | ... |
These fields can be defined in the clip name in three ways:
* `$NAME=VALUE` creates a field named `NAME` with a one-word value `VALUE`.
* `{NAME=VALUE}` creates a field named `NAME` with the value `VALUE`. `VALUE`
in this case may contain spaces or any chartacter up to the closing bracket.
* `[NAME]` creates a field named `NAME` with a value `NAME`. This can be used
to create a boolean-valued field; in the CSV output, clips with the field
will have it, and clips without will have the column with an empty value.
For example, if two clips are named:
`"Squad fifty-one, what is your status?" [FUTZ] {Ch=Dispatcher} [ADR]`
`"We are ten-eight at Rampart Hospital." {Ch=Gage} [ADR]`
The output will contain the range:
|...| PT.Clip.Name| Ch | FUTZ | ADR | ...|
|---|------------|------|---|----|-----|
|...| "Squad fifty-one, what is your status?"| Dispatcher | FUTZ | ADR | ... |
|...| "We are ten-eight at Rampart Hospital."| Gage | | ADR | ... |
### Fields in Track Names and Markers
Fields set in track names, and in track comments, will be applied to *each*
clip on that track. If a track comment contains the text `{Dept=Foley}` for
example, every clip on that track will have a "Foley" value in a "Dept" column.
Likewise, fields set on the session name will apply to all clips in the session.
Fields set in markers, and in marker comments, will be applied to all clips
whose finish is *after* that marker. Fields in markers are applied cumulatively
from breakfast to dinner in the session. The latest marker applying to a clip has
precedence, so if one marker comes after the other, but both define a field, the
value in the later marker
An important note here is that, always, fields set on the clip name have the
highest precedence. If a field is set in a clip name, the same field set on the
track, the value set on the clip will prevail.
### Using `@` to Apply Fields to a Span of Clips
A clip name beginning with "@" will not be included in the CSV output, but its
fields will be applied to clips within its time range on lower tracks.
If track 1 has a clip named `@ {Sc=1- The House}`, any clips beginning within
that range on lower tracks will have a field `Sc` with that value.
### Using `&` to Combine Clips
A clip name beginning with `&` will have its parsed clip name appended to the
preceding cue, and the fields of following cues will be applied, earlier 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 time of the last clip will
become the finish time of the row.
## What is `ptulsconv` Useful For?
The main purpose of `ptulsconv` is to read a Pro Tools text export and convert
it into PDFs useful for ADR recording.
## Is it useful for anything else?

86
doc/QUICKSTART.md Normal file
View File

@@ -0,0 +1,86 @@
# Quick Start for ADR Spotting and Reporting with `ptulsconv`
## Step 1: Use Pro Tools to spot ADR Lines
`ptulsconv` can be used to spot ADR lines similarly to other programs.
1. Create a new Pro Tools session, name this session after your project.
1. Create new tracks, one for each character. Name each track after a
character.
1. On each track, create a clip group (or edit in some audio) at the time you
would like an ADR line to appear in the report. Name the clip after the
dialogue you are replacing at that time.
## Step 2: Add More Information to Your Spots
Clips, tracks and markers in your session can contain additional information
to make your ADR reports more complete and useful. You add this information
with *tagging*.
- Every ADR clip must have a unique cue number. After the name of each clip,
add the letters "$QN=" and then a unique number (any combination of letters
or numbers that don't contain a space). You can type these yourself or add
them with batch-renaming when you're done spotting.
- ADR spots should usually have a reason indicated, so you can remember exactly
why you're replacing a particular line. Do this by adding the the text "{R="
to your clip names after the prompt and then some short text describing the
reason, and then a closing "}". You can type anything, including spaces.
- If a line is a TV cover line, you can add the text "[TV]" to the end.
So for example, some ADR spot's clip name might look like:
"Get to the ladder! {R=Noise} $QN=J1001"
"Forget your feelings! {R=TV Cover} $QN=J1002 [TV]"
These tags can appear in any order.
- You can add the name of an actor to a character's track, so this information
will appear on your reports. In the track name, or in the track comments,
type "{Actor=xxx}" replacing the xxx with the actor's name.
- Characters need to have a number (perhaps from the cast list) to express how
they should be collated. Add "$CN=xxx" with a unique number to each track (or
the track's comments.)
- Set the scene for each line with markers. Create a marker at the beginning of
a scene and make it's name "{Sc=xxx}", replacing the xxx with the scene
number and name.
Many tags are available to express different details of each line, like
priority, time budget, picture version and reel, notes etc. charater or the
project, find them by running `ptulsconv` with the `--show-available-tags`
option.
## Step 3: Export Relevant Tracks from Pro Tools as a Text File
Export the file as a UTF-8 and be sure to include clips and markers. Export
using the Timecode time format.
Do not export crossfades.
## Step 4: Run `ptulsconv` on the Text Export
In your Terminal, run the following command:
ptulsconv path/to/your/TEXT_EXPORT.txt
`ptulsconv` will create a folder named "Title_CURRENT_DATE", and within that
folder it will create several PDFs and folders:
- "TITLE ADR Report" 📄 a PDF tabular report of every ADR line you've spotted.
- "TITLE Continuity" 📄 a PDF listing every scene you have indicated and its
timecode.
- "TITLE Line Count" 📄 a PDF tabular report giving line counts by reel, and the
time budget per character and reel (if provided in the tagging).
- "CSV/" a folder containing CSV documents of all spotted ADR, groupd by
character and reel.
- "Director Logs/" 📁 a folder containing PDF tabular reports, like the overall
report except groupd by character.
- "Supervisor Logs/" 📁 a folder containing PDF reports, one page per line,
designed for note taking during a session, particularly on an iPad.
- "Talent Scripts/" 📁 a folder containing PDF scripts or sides, with the timecode
and prompts for each line, grouped by character but with most other
information suppressed.

View File

@@ -1,5 +1,6 @@
from ptulsconv.docparser.ptuls_grammar import protools_text_export_grammar from ptulsconv.docparser.ptuls_grammar import protools_text_export_grammar
__version__ = '1.0.0' __version__ = '1.0.4'
__author__ = 'Jamie Hardt' __author__ = 'Jamie Hardt'
__license__ = 'MIT' __license__ = 'MIT'
__copyright__ = "%s %s (c) 2022 %s. All rights reserved." % (__name__, __version__, __author__)

View File

@@ -2,7 +2,7 @@ from optparse import OptionParser, OptionGroup
import datetime import datetime
import sys import sys
from ptulsconv import __name__, __version__, __author__ from ptulsconv import __name__, __version__, __author__,__copyright__
from ptulsconv.commands import convert from ptulsconv.commands import convert
from ptulsconv.reporting import print_status_style, print_banner_style, print_section_header_style, print_fatal_error from ptulsconv.reporting import print_status_style, print_banner_style, print_section_header_style, print_fatal_error
@@ -23,6 +23,18 @@ def dump_field_map(output=sys.stdout):
TagMapping.print_rules(ADRLine, output=output) TagMapping.print_rules(ADRLine, output=output)
def dump_formats():
print_section_header_style("`raw` format:")
sys.stderr.write("A JSON document of the parsed Pro Tools export.\n")
print_section_header_style("`tagged` Format:")
sys.stderr.write("A JSON document containing one record for each clip, with\n"
"all tags parsed and all tagging rules applied. \n")
print_section_header_style("`doc` format:")
sys.stderr.write("Creates a directory with folders for different types\n"
"of ADR reports.\n\n")
def main(): def main():
"""Entry point for the command-line invocation""" """Entry point for the command-line invocation"""
parser = OptionParser() parser = OptionParser()
@@ -50,6 +62,13 @@ def main():
description='Print useful information and exit without processing ' description='Print useful information and exit without processing '
'input files.') 'input files.')
informational_options.add_option('--show-formats',
dest='show_formats',
action='store_true',
default=False,
help='Display helpful information about the '
'available output formats.')
informational_options.add_option('--show-available-tags', informational_options.add_option('--show-available-tags',
dest='show_tags', dest='show_tags',
action='store_true', action='store_true',
@@ -59,9 +78,10 @@ def main():
parser.add_option_group(informational_options) parser.add_option_group(informational_options)
print_banner_style(__copyright__)
(options, args) = parser.parse_args(sys.argv) (options, args) = parser.parse_args(sys.argv)
print_banner_style("%s %s (c) 2022 %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()))
@@ -70,6 +90,10 @@ def main():
dump_field_map() dump_field_map()
sys.exit(0) sys.exit(0)
elif options.show_formats:
dump_formats()
sys.exit(0)
if len(args) < 2: if len(args) < 2:
print_fatal_error("Error: No input file") print_fatal_error("Error: No input file")
parser.print_help(sys.stderr) parser.print_help(sys.stderr)

View File

@@ -67,8 +67,8 @@ protools_text_export_grammar = Grammar(
fs = "\t" fs = "\t"
rs = "\n" rs = "\n"
block_ending = rs rs block_ending = rs rs
string_value = ~"[^\t\n]*" string_value = ~r"[^\t\n]*"
integer_value = ~"\d+" integer_value = ~r"\d+"
float_value = ~"\d+(\.\d+)?" float_value = ~r"\d+(\.\d+)?"
isp = ~"[^\d\t\n]*" isp = ~r"[^\d\t\n]*"
""") """)

View File

@@ -18,11 +18,11 @@ tag_grammar = Grammar(
key_tag = "[" key "]" word_sep? key_tag = "[" key "]" word_sep?
short_tag = "$" key "=" word word_sep? short_tag = "$" key "=" word word_sep?
full_text_tag = "{" key "=" value "}" word_sep? full_text_tag = "{" key "=" value "}" word_sep?
key = ~"[A-Za-z][A-Za-z0-9_]*" key = ~r"[A-Za-z][A-Za-z0-9_]*"
value = ~"[^}]+" value = ~r"[^}]+"
tag_junk = word word_sep? tag_junk = word word_sep?
word = ~"[^ \[\{\$][^ ]*" word = ~r"[^ \[\{\$][^ ]*"
word_sep = ~" +" word_sep = ~r" +"
modifier = ("@" / "&") word_sep? modifier = ("@" / "&") word_sep?
""" """
) )