music-metadata-cwr2 19
Music Metedata - CWR2.x support
Requires Python: >=3.7

# Common Works Registration 2.x
## CWR 2.x parsing, validation and generation

This library can be used for managing CWR 2.x files.
CWR generation is not implemented yet.

## Basic usage
```python
from cwr2.music_metadata.music_metadata.cwr2 import Cwr2File
# The above import works from the repository folder
# For production, pip install cwr2, then use:
# from music_metadata.cwr2.file import Cwr2File 

# Open the file, process HDR and TRL
cwr_file = Cwr2File(open('/path/to/file', 'rb'))

# Loop through groups
for group in cwr_file.get_groups():

    # Loop through transactions
    for transaction in group.get_transactions():

        # Loop through records
        for record in transaction.records:
            print(record.to_html())
```

Note that the actual conversion to JSON is not part of the repo,
as this heavily relies on implementation. See the next section.

## `watch.py`
This script watches for added/changed files in a folder (not recursive) and
performs a conversion from CWR to JSON. It uses 
[inotify](https://pypi.org/project/inotify/) for change detection, which is
a feature of the Linux kernel. It also has a custom JSON encoder.

The intended way to use this script is to be started by `supervisor` on Linux,
together with `sftpd` with chroot jail. A good recipe can be found here:
https://www.techrepublic.com/article/how-to-use-sftp-with-a-chroot-jail/
You want to run the scripts with following flags:

```shell script
python watch.py in_folder out_folder --mute-errors --use-temp-file
```
`--mute-errors` will create a JSON file, even if it is completely unparsable 
(e.g. JPEG) and have a single `error` entry.

`--use-temp-file` will create the JSON file in a temporary location and then
it will be moved to the final location once it is finished, to prevent opening
an incomplete file by an inpatient user.

This script is also a practical working example of how to use the library. 

If you need to extend the script with some kind of a hook, the bottom
of `Watcher.process_event` would be a good option for it.


## Web Wrapper

There are two other examples in https://github.com/musicmetadata/web-wrapper,
use the `private` branch, which has this repo in requirements. 
One is a web-based conversion tool, the other is a visual validator.

Web wrapper can be tested at https://web-wrapper.matijakolaric.com, though it
may not be the latest version.


## About Validation

During the parsing process, data is also validated. In Dictionary (JSON) 
output, each field has a boolean 'valid' field. If a field is not valid, then 
there is also an 'error' field with an explanation.

There is also an error field for each transaction (work registration), and a
list of errors for invalid transactions.

The file is also marked as valid or invalid. And there is a list with file 
errors.

CWR actually also has record-level and group-level errors. However, in this 
context, they are integrated in one of the aforementioned levels.


### File validity

Please note that the **file validity** is shown at the bottom of the Dictionary
(JSON) output. This is because the whole file has to be parsed to determine 
the file validity.

If a CWR file is marked invalid, this means that there is a serious issue with its
structure, that the generating software is basically broken, and 
splitting it into groups and transactions is not reliable.

However, it can happen that the file is invalid and all transactions are
valid. Not just marked valid, really valid. But it takes an experienced
human to make that call.

The advice would be not to import invalid files.


### Transaction and field validity

A **valid transaction** can have **invalid fields**. Basically, invalid fields in a 
valid transaction should be ignored - set to the default value, which in this
library is `None` for all fields, `null` in the JSON output.
In that case, a society "accepts with changes", or at least it should.

However, valuable information might be lost, especially regarding
commas in name fields, explained later. 

If a **transaction is invalid**, then there is something wrong. It does not 
have to be related to one particular field. For example, a transaction for an 
original work must have a writer with one of the roles: Adaptor, Arranger, 
Translator. So, it is a lack of data that can make a registration invalid.

A very common error is a **comma in a name**. CWR has a strict
rule which characters are allowed in which fields, and name fields can not
have commas. Some societies will reject this, while some will
simply remove commas from names, and some just dont care.



If the dilemma is whether to deal with this during the import or during the 
export, the answer is "it depends". As always.