Skip to content

Commit

Permalink
improving CC - no more Ds
Browse files Browse the repository at this point in the history
  • Loading branch information
matijakolaric committed Jul 28, 2022
1 parent be6fc0e commit 643c34e
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 81 deletions.
4 changes: 2 additions & 2 deletions docs/releases.rst
Expand Up @@ -168,8 +168,8 @@ linked to improve clarity.

Most improvements in this release are under the bonnet. The
source code has been reviewed and partly cleaned up, with average
complexity reduced to ``A (3)`` and no block more complex than
``D (30)``. Code style is now validated with
complexity reduced to ``A (3.0)`` and no block more complex than
``C``. Code style is now validated with
`Black <https://black.readthedocs.io/en/stable/>`_.

However, the most important new feature is the generation of
Expand Down
22 changes: 14 additions & 8 deletions music_publisher/admin.py
Expand Up @@ -2094,6 +2094,19 @@ def get_fields(self, request, obj=None):
r"(?<=\n)ISW.{78}(.{14})(.{11}).*?(?=^ISW|^GRT)", re.S | re.M
)

def validate_iswc(self, x, validator, import_iswcs):
tt, work_id, remote_work_id, dat, status, rest = x
if import_iswcs and rest:
header = rest.strip().split("\n")[0]
iswc = header[95:106].strip() or None
if iswc:
try:
validator(iswc)
except ValidationError:
iswc = None
return iswc
return None

def process(self, request, ack_import, file_content, import_iswcs=False):
"""Create appropriate WorkAcknowledgement objects, without duplicates.
Expand All @@ -2120,14 +2133,7 @@ def process(self, request, ack_import, file_content, import_iswcs=False):
pattern = self.RE_ACK_30
for x in re.findall(pattern, file_content):
tt, work_id, remote_work_id, dat, status, rest = x
if import_iswcs and rest:
header = rest.strip().split("\n")[0]
iswc = header[95:106].strip() or None
if iswc:
try:
validator(iswc)
except ValidationError:
iswc = None
iswc = self.validate_iswc(x, validator, import_iswcs)
# work ID is numeric with an optional string
work_id = work_id.strip()
remote_work_id = remote_work_id.strip()
Expand Down
129 changes: 64 additions & 65 deletions music_publisher/data_import.py
Expand Up @@ -164,6 +164,69 @@ def process_writer_value(self, key, key_elements, value):
value = bool(value)
return value, general_agreement

def unflatten_writer_record(self, out_dict, clean_key, key, value):
key_elements = clean_key.split("_", 2)
if len(key_elements) < 3 or key_elements[2] not in self.WRITER_FIELDS:
self.unknown_keys.add(key)
return
value, general_agreement = self.process_writer_value(
key, key_elements, value
)
if general_agreement:
out_dict["writers"][key_elements[1]]["general_agreement"] = True
out_dict["writers"][key_elements[1]][key_elements[2]] = value

def unflatten_record(self, out_dict, key, value):
if value is None:
return
if isinstance(value, str):
value = value.strip()
clean_key = slugify(key).replace("-", "_")
prefix = clean_key.split("_")[0]
if value == "":
return
if clean_key in self.FLAT_FIELDS:
out_dict[clean_key] = value
elif prefix == "alt":
key_elements = clean_key.rsplit("_", 1)
if len(key_elements) < 2 or key_elements[0] != "alt_title":
self.unknown_keys.add(key)
return
out_dict["alt_titles"].append(value)
elif prefix == "writer":
return self.unflatten_writer_record(
out_dict, clean_key, key, value
)
elif prefix == "artist":
key_elements = clean_key.split("_", 2)
if (
len(key_elements) < 3
or key_elements[2] not in self.ARTIST_FIELDS
):
self.unknown_keys.add(key)
return
out_dict["artists"][key_elements[1]][key_elements[2]] = value
elif prefix == "recording":
key_elements = clean_key.split("_", 2)
if (
len(key_elements) < 3
or key_elements[2] not in self.RECORDING_FIELDS
):
self.unknown_keys.add(key)
return
out_dict["recordings"][key_elements[1]][key_elements[2]] = value
elif prefix == "reference":
key_elements = clean_key.split("_", 2)
if (
len(key_elements) < 3
or key_elements[2] not in self.REFERENCE_FIELDS
):
self.unknown_keys.add(key)
return
out_dict["references"][key_elements[1]][key_elements[2]] = value
else:
self.unknown_keys.add(key)

def unflatten(self, in_dict):
"""Create a well-structured dictionary with cleaner values."""
out_dict = {
Expand All @@ -174,71 +237,7 @@ def unflatten(self, in_dict):
"references": defaultdict(OrderedDict),
}
for key, value in in_dict.items():
if value is None:
continue
if isinstance(value, str):
value = value.strip()
clean_key = slugify(key).replace("-", "_")
prefix = clean_key.split("_")[0]
if value == "":
continue
if clean_key in self.FLAT_FIELDS:
out_dict[clean_key] = value
elif prefix == "alt":
key_elements = clean_key.rsplit("_", 1)
if len(key_elements) < 2 or key_elements[0] != "alt_title":
self.unknown_keys.add(key)
continue
out_dict["alt_titles"].append(value)
elif prefix == "writer":
key_elements = clean_key.split("_", 2)
if (
len(key_elements) < 3
or key_elements[2] not in self.WRITER_FIELDS
):
self.unknown_keys.add(key)
continue
value, general_agreement = self.process_writer_value(
key, key_elements, value
)
if general_agreement:
out_dict["writers"][key_elements[1]][
"general_agreement"
] = True
out_dict["writers"][key_elements[1]][key_elements[2]] = value
elif prefix == "artist":
key_elements = clean_key.split("_", 2)
if (
len(key_elements) < 3
or key_elements[2] not in self.ARTIST_FIELDS
):
self.unknown_keys.add(key)
continue
out_dict["artists"][key_elements[1]][key_elements[2]] = value
elif prefix == "recording":
key_elements = clean_key.split("_", 2)
if (
len(key_elements) < 3
or key_elements[2] not in self.RECORDING_FIELDS
):
self.unknown_keys.add(key)
continue
out_dict["recordings"][key_elements[1]][
key_elements[2]
] = value
elif prefix == "reference":
key_elements = clean_key.split("_", 2)
if (
len(key_elements) < 3
or key_elements[2] not in self.REFERENCE_FIELDS
):
self.unknown_keys.add(key)
continue
out_dict["references"][key_elements[1]][
key_elements[2]
] = value
else:
self.unknown_keys.add(key)
self.unflatten_record(out_dict, key, value)
return out_dict

def get_writers(self, writer_dict):
Expand Down
15 changes: 15 additions & 0 deletions music_publisher/forms.py
Expand Up @@ -200,6 +200,13 @@ def clean(self):
and form.cleaned_data["capacity"] not in self.orig_cap
):
needs_extended_capacity = False
self.check_extended_capacity(needs_extended_capacity)
self.check_controlled(controlled)
self.check_has_composer(has_composer)
self.check_total(total)
self.check_modification(is_modification)

def check_extended_capacity(self, needs_extended_capacity):
if needs_extended_capacity:
for form in self.forms:
form.add_error(
Expand All @@ -210,12 +217,16 @@ def clean(self):
"In a modified work, "
"at least one writer must be Arranger, Adaptor or Translator."
)

def check_controlled(self, controlled):
if not controlled:
for form in self.forms:
form.add_error(
"controlled", "At least one writer must be controlled."
)
raise ValidationError("At least one writer must be controlled.")

def check_has_composer(self, has_composer):
if not has_composer:
for form in self.forms:
form.add_error(
Expand All @@ -226,12 +237,16 @@ def clean(self):
raise ValidationError(
"At least one writer must be Composer or Composer&Lyricist."
)

def check_total(self, total):
if not (Decimal(99.98) <= total <= Decimal(100.02)):
for form in self.forms:
form.add_error(
"relative_share", "Sum of manuscript shares must be 100%."
)
raise ValidationError("Sum of manuscript shares must be 100%.")

def check_modification(self, is_modification):
if is_modification:
writer_capacities = {}
for form in self.forms:
Expand Down
17 changes: 11 additions & 6 deletions music_publisher/validators.py
Expand Up @@ -191,12 +191,8 @@ def __call__(self, value):
raise ValidationError("Name contains invalid characters.")


def validate_settings():
"""CWR-compliance validation for settings.
This is used to prevent deployment with invalid settings.
"""

def validate_publisher_settings():
"""CWR-compliance validation for publisher settings."""
if settings.PUBLISHER_NAME:
try:
CWRFieldValidator("name")(settings.PUBLISHER_NAME)
Expand Down Expand Up @@ -231,6 +227,15 @@ def validate_settings():
except ValidationError as e:
raise ImproperlyConfigured("PUBLISHER_IPI_NAME: " + str(e))


def validate_settings():
"""CWR-compliance validation for settings.
This is used to prevent deployment with invalid settings.
"""

validate_publisher_settings()

keys = [s[0] for s in SOCIETIES]
for t in ["PR", "MR", "SR"]:
attr = getattr(settings, "PUBLISHER_SOCIETY_" + t)
Expand Down

0 comments on commit 643c34e

Please sign in to comment.