music_publisher Package

This app is targeted at single original publishers, publishing original musical works. It holds data on musical works, including alternate titles, songwriters, performing artists, first recordings, music library and albums. It allows data imports and exports.

Multiple writers, both controlled and uncontrolled, are covered, with minor limitations, but data on other publishers (other original publishers, administrators and sub-publishers) can not be entered.

A special US situation where an original publisher may have one entity for every of the three PROs is also covered.

music_publisher.apps module

class music_publisher.apps.MusicPublisherConfig(app_name, app_module)

Bases: django.apps.config.AppConfig

Configuration for Music Publisher app.

label

app label

Type:str
name

app name

Type:str
verbose_name

app verbose name

Type:str

music_publisher.base module

Contains base (abstract) classes used in models

class music_publisher.base.TitleBase(*args, **kwargs)

Bases: django.db.models.base.Model

Abstract class for all classes that have a title.

title

Title, used in work title, alternate title, etc.

Type:django.db.models.CharField
class music_publisher.base.PersonBase(*args, **kwargs)

Bases: django.db.models.base.Model

Base class for all classes that contain people with first and last name.

first_name

First Name

Type:django.db.models.CharField
last_name

Last Name

Type:django.db.models.CharField
class music_publisher.base.IPIBase(*args, **kwargs)

Bases: django.db.models.base.Model

Abstract base for all objects containing IPI numbers.

generally_controlled

General agreement (renamed in verbose_name)

Type:django.db.models.BooleanField
ipi_base

IPI Base Number

Type:django.db.models.CharField
ipi_name

IPI Name Number

Type:django.db.models.CharField
pr_society

Performing Rights Society Code

Type:django.db.models.CharField
publisher_fee

Publisher Fee

Type:django.db.models.DecimalField
saan

Society-assigned agreement number, in this context it is used for general agreements, for specific agreements use models.WriterInWork.saan.

Type:django.db.models.CharField
_can_be_controlled

used to determine if there is enough data for a writer to be controlled.

Type:django.db.models.BooleanField
generally_controlled

flags if a writer is generally controlled (in all works)

Type:django.db.models.BooleanField
publisher_fee

this field is used in calculating publishing fees

Type:django.db.models.DecimalField
clean_fields(*args, **kwargs)

Data cleanup, allowing various import formats to be converted into consistently formatted data.

clean(enforce_ipi_name=True, enforce_pr_society=True, enforce_saan=True, enforce_publisher_fee=True, error_msg='Unsufficient data for a controlled writer, required fields are: Last Name, Performing Rights Society, IPI Name #.')

Clean with a lot of arguments.

In DMP they come from settings, but in other solutions that use this code, these values may be set dynamically.

Parameters:
  • enforce_ipi_name (bool, optional) – Makes IPI Name # required if controlled
  • enforce_pr_society (bool, optional) – Makes PR Society code required if controlled
  • enforce_saan (bool, optional) – Makes SAAN required if controlled
  • enforce_publisher_fee (bool, optional) – Makes Publisher fee required if controlled
  • error_msg (str, optional) – Error Message to show if required fields are not filled out

music_publisher.models module

Concrete models.

They mostly inherit classes from base.

music_publisher.models.normalize_dict(full_dict, inner_dict, key, code_key='code')

Normalize a dictionary

Parameters:
  • full_dict (dict) – Complete dictionary
  • inner_dict (dict) – Dictionary that holds denormaliyed data
  • key (str) – Key for full_dict where the data from inner_dict goes
  • code_key (str, optional) – Description
Returns:

the key under which the data was normalized

Return type:

str

class music_publisher.models.Artist(*args, **kwargs)

Bases: music_publisher.base.PersonBase, django.db.models.base.Model

Performing artists.

isni

International Standard Name Identifier

Type:django.db.models.CharField
clean_fields(*args, **kwargs)

ISNI cleanup

get_dict()

Get the object in an internal dictionary format

Returns:internal dict format
Return type:dict
artist_id

Artist identifier

Returns:Artist ID
Return type:str
exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

class music_publisher.models.Label(*args, **kwargs)

Bases: django.db.models.base.Model

Music Label.

name

Label Name

Type:django.db.models.CharField
label_id

Label identifier

Returns:Label ID
Return type:str
get_dict()

Get the object in an internal dictionary format

Returns:internal dict format
Return type:dict
exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

class music_publisher.models.Library(*args, **kwargs)

Bases: django.db.models.base.Model

Music Library.

name

Library Name

Type:django.db.models.CharField
library_id

Library identifier

Returns:Library ID
Return type:str
get_dict()

Get the object in an internal dictionary format

Returns:internal dict format
Return type:dict
exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

class music_publisher.models.Release(*args, **kwargs)

Bases: django.db.models.base.Model

Music Release (album / other product)

cd_identifier

CD Identifier, used when origin is library

Type:django.db.models.CharField
ean

EAN code

Type:django.db.models.CharField
library

Foreign key to models.Library

Type:django.db.models.ForeignKey
recordings

M2M to models.Recording through models.Track

Type:django.db.models.ManyToManyField
release_date

Date of the release

Type:django.db.models.DateField
release_label

Foreign key to models.Label

Type:django.db.models.ForeignKey
release_title

Title of the release

Type:django.db.models.CharField
release_id

Release identifier.

Returns:Release ID
Return type:str
get_dict()

Get the object in an internal dictionary format

Returns:internal dict format
Return type:dict
exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

class music_publisher.models.LibraryReleaseManager

Bases: django.db.models.manager.Manager

Manager for a proxy class models.LibraryRelease

get_queryset()

Return only library releases

Returns:Queryset with instances of models.LibraryRelease
Return type:django.db.models.query.QuerySet
class music_publisher.models.LibraryRelease(*args, **kwargs)

Bases: music_publisher.models.Release

Proxy class for Library Releases (AKA Library CDs)

objects

Database Manager

Type:LibraryReleaseManager
clean()

Make sure that release title is required if one of the other “non-library” fields is present.

Raises:ValidationError – If not ccompliant.
get_origin_dict()

Get the object in an internal dictionary format.

This is used for work origin, not release data.

Returns:internal dict format
Return type:dict
exception DoesNotExist

Bases: music_publisher.models.DoesNotExist

exception MultipleObjectsReturned

Bases: music_publisher.models.MultipleObjectsReturned

class music_publisher.models.CommercialReleaseManager

Bases: django.db.models.manager.Manager

Manager for a proxy class models.CommercialRelease

get_queryset()

Return only commercial releases

Returns:Queryset with instances of models.CommercialRelease
Return type:django.db.models.query.QuerySet
class music_publisher.models.CommercialRelease(*args, **kwargs)

Bases: music_publisher.models.Release

Proxy class for Commercial Releases

objects

Database Manager

Type:CommercialReleaseManager
exception DoesNotExist

Bases: music_publisher.models.DoesNotExist

exception MultipleObjectsReturned

Bases: music_publisher.models.MultipleObjectsReturned

class music_publisher.models.Writer(*args, **kwargs)

Bases: music_publisher.base.PersonBase, music_publisher.base.IPIBase, django.db.models.base.Model

Base class for writers, the second most important top-level class.

clean(*args, **kwargs)
Parameters:
  • args
  • kwargs
Returns:

Return type:

writer_id

return: :rtype:

get_dict()

Create a data structure that can be serialized as JSON.

Returns:JSON-serializable data structure
Return type:dict
exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

class music_publisher.models.Work(*args, **kwargs)

Bases: music_publisher.base.TitleBase

Concrete class, with references to foreign objects.

artists

Artists performing the work

Type:django.db.models.ManyToManyField
last_change

when the last change was made to this object or any of the child objects, basically used in filtering

Type:django.db.models.DateTimeField
writers

Writers who created the work

Type:django.db.models.ManyToManyField
work_id

Create Work ID used in registrations

Returns:Internal Work ID
Return type:str
is_modification()
Returns:
Return type:
clean_fields(*args, **kwargs)

Deal with various ways ISWC is written.

get_publishers_dict()

Create data structure for the publisher.

Returns:JSON-serializable data structure
Return type:dict
static normalize_affiliation(j, aff)

Normalize publisher affiliations.

This refers to organizations, affiliation types and territories.

static normalize_publisher_affiliations(j)

Normalize publisher affiliations.

This refers to organizations, affiliation types and territories.

get_dict(normalize=True)

Create a data structure that can be serialized as JSON.

Normalize the structure if required.

Returns:JSON-serializable data structure
Return type:dict
exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

class music_publisher.models.AlternateTitle(*args, **kwargs)

Bases: music_publisher.base.TitleBase

Concrete class for alternate titles.

work

Foreign key to Work model

Type:django.db.models.ForeignKey
get_dict()

Create a data structure that can be serialized as JSON.

Returns:JSON-serializable data structure
Return type:dict
exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

class music_publisher.models.ArtistInWork(*args, **kwargs)

Bases: django.db.models.base.Model

Artist performing the work (live in CWR 3).

artist

FK to Artist

Type:django.db.models.ForeignKey
work

FK to Work

Type:django.db.models.ForeignKey
get_dict()
Returns:
Return type:
exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

class music_publisher.models.WriterInWork(*args, **kwargs)

Bases: django.db.models.base.Model

Writers who created this work.

At least one writer in work must be controlled. Sum of relative shares must be (roughly) 100%. Capacity is limited to roles for original writers.

capacity

Role of the writer in this work

Type:django.db.models.CharField
controlled

A complete mistery field

Type:django.db.models.BooleanField
publisher_fee

Percentage of royalties kept by publisher

Type:django.db.models.DecimalField
relative_share

Initial split among writers, prior to publishing

Type:django.db.models.DecimalField
saan

Society-assigned agreement number between the writer and the original publisher, please note that this field is for SPECIFIC agreements, for a general agreement, use base.IPIBase.saan

Type:django.db.models.CharField
work

FK to Work

Type:django.db.models.ForeignKey
writer

FK to Writer

Type:django.db.models.ForeignKey
clean_fields(*args, **kwargs)

Turn SAAN into uppercase.

Parameters:
  • *args – passing through
  • **kwargs – passing through
Returns:

Description

Return type:

TYPE

clean()

Make sure that controlled writers have all the required data.

Also check that writers that are not controlled do not have data that can not apply to them.

get_dict()

Create a data structure that can be serialized as JSON.

Returns:JSON-serializable data structure
Return type:dict
exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

class music_publisher.models.Recording(*args, **kwargs)

Bases: django.db.models.base.Model

Holds data on first recording.

Note that the CWR 2.x limitation of just one REC record per work has been removed in the specs, but some societies still complain about it, so only a single instance is allowed.

duration

Recording Duration

Type:django.db.models.TimeField
isrc

International Standard Recording Code

Type:django.db.models.CharField
record_label

Record Label

Type:django.db.models.CharField
release_date

Recording Release Date

Type:django.db.models.DateField
clean_fields(*args, **kwargs)
Parameters:
  • args
  • kwargs
Returns:

Return type:

complete_recording_title

return: :rtype:

complete_version_title

return: :rtype:

recording_id

Create Recording ID used in registrations

Returns:Internal Recording ID
Return type:str
get_dict(with_releases=False)

Create a data structure that can be serialized as JSON.

Returns:JSON-serializable data structure
Return type:dict
exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

class music_publisher.models.Track(id, recording, release, cut_number)

Bases: django.db.models.base.Model

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

class music_publisher.models.CWRExport(*args, **kwargs)

Bases: django.db.models.base.Model

Export in CWR format.

Common Works Registration format is a standard format for registration of musical works world-wide. As of November 2018, version 2.1r7 is used everywhere, while some societies accept 2.2 as well, it adds no benefits in this context. Version 3.0 is in draft.

nwr_rev

Choice field where user can select which version and type of CWR it is.

Type:django.db.models.CharField
filename30

Return proper CWR 3.0 filename.

Format is: CWYYnnnnSUB_REP_VM - m - r.EXT

Returns:CWR file name
Return type:str
filename21

Return proper CWR 2.1 filename.

Returns:CWR file name
Return type:str
get_record(key, record)

Create CWR record (row) from the key and dict.

Parameters:
  • key (str) – type of record
  • record (dict) – field values
Returns:

CWR record (row)

Return type:

str

get_transaction_record(key, record)

Create CWR transaction record (row) from the key and dict.

This methods adds transaction and record sequences.

Parameters:
  • key (str) – type of record
  • record (dict) – field values
Returns:

CWR record (row)

Return type:

str

yield_lines()

Yield CWR transaction records (rows/lines) for works

Parameters:works (query) – models.Work query
Yields:str – CWR record (row/line)
create_cwr()

Create CWR and save.

exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

class music_publisher.models.WorkAcknowledgement(*args, **kwargs)

Bases: django.db.models.base.Model

Acknowledgement of work registration.

date

Acknowledgement date

Type:django.db.models.DateField
remote_work_id

Remote work ID

Type:django.db.models.CharField
society_code

3-digit society code

Type:django.db.models.CharField
status

2-letter status code

Type:django.db.models.CharField
TRANSACTION_STATUS_CHOICES

choices for status

Type:tuple
work

FK to Work

Type:django.db.models.ForeignKey
get_dict()
Returns:
Return type:
exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

class music_publisher.models.ACKImport(*args, **kwargs)

Bases: django.db.models.base.Model

CWR acknowledgement file import.

date

Acknowledgement date

Type:django.db.models.DateField
date

Acknowledgement date

Type:django.db.models.DateField
filename

Description

Type:django.db.models.CharField
report

Basically a log

Type:django.db.models.CharField
society_code

3-digit society code, please note that choices is not set.

Type:models.CharField
society_name

Society name, used if society code is missing.

Type:models.CharField
exception DoesNotExist

Bases: django.core.exceptions.ObjectDoesNotExist

exception MultipleObjectsReturned

Bases: django.core.exceptions.MultipleObjectsReturned

music_publisher.admin module

class music_publisher.admin.MusicPublisherAdmin(model, admin_site)

Bases: django.contrib.admin.options.ModelAdmin

class music_publisher.admin.ArtistInWorkInline(parent_model, admin_site)

Bases: django.contrib.admin.options.TabularInline

Inline interface for models.ArtistInWork.

model

alias of music_publisher.models.ArtistInWork

class music_publisher.admin.RecordingInline(parent_model, admin_site)

Bases: django.contrib.admin.options.StackedInline

Inline interface for models.Recording, used in WorkAdmin and ArtistAdmin.

model

alias of music_publisher.models.Recording

class music_publisher.admin.ArtistAdmin(model, admin_site)

Bases: music_publisher.admin.MusicPublisherAdmin

Admin interface for models.Artist.

last_or_band(obj)

Placeholder for models.Artist.last_name.

save_model(request, obj, form, *args, **kwargs)

Save, then update last_change of the corresponding works.

get_queryset(request)

Optimized queryset for changelist view.

work_count(obj)

Return the work count from the database field, or count them. (dealing with legacy)

recording_count(obj)

Return the work count from the database field, or count them. (dealing with legacy)

class music_publisher.admin.LabelAdmin(model, admin_site)

Bases: music_publisher.admin.MusicPublisherAdmin

get_queryset(request)

Optimized queryset for changelist view.

commercialrelease_count(obj)

Return the work count from the database field, or count them. (dealing with legacy)

libraryrelease_count(obj)

Return the work count from the database field, or count them. (dealing with legacy)

recording_count(obj)

Return the work count from the database field, or count them. (dealing with legacy)

save_model(request, obj, form, *args, **kwargs)

Save, then update last_change of the corresponding works.

class music_publisher.admin.LibraryAdmin(model, admin_site)

Bases: music_publisher.admin.MusicPublisherAdmin

get_queryset(request)

Optimized queryset for changelist view.

libraryrelease_count(obj)

Return the work count from the database field, or count them. (dealing with legacy)

work_count(obj)

Return the work count from the database field, or count them. (dealing with legacy)

save_model(request, obj, form, *args, **kwargs)

Save, then update last_change of the corresponding works.

class music_publisher.admin.TrackInline(parent_model, admin_site)

Bases: django.contrib.admin.options.TabularInline

model

alias of music_publisher.models.Track

class music_publisher.admin.ReleaseAdmin(model, admin_site)

Bases: music_publisher.admin.MusicPublisherAdmin

Admin interface for models.Release.

has_module_permission(request)

Return True if the given request has any permission in the given app label.

Can be overridden by the user in subclasses. In such case it should return True if the given request has permission to view the module on the admin index page and access the module’s index page. Overriding it does not restrict access to the add, change or delete views. Use ModelAdmin.has_(add|change|delete)_permission for that.

has_add_permission(request)

Return True if the given request has permission to add an object. Can be overridden by the user in subclasses.

has_change_permission(request, obj=None)

Return True if the given request has permission to change the given Django model instance, the default implementation doesn’t examine the obj parameter.

Can be overridden by the user in subclasses. In such case it should return True if the given request has permission to change the obj model instance. If obj is None, this should return True if the given request has permission to change any object of the given type.

has_delete_permission(request, obj=None)

Return True if the given request has permission to change the given Django model instance, the default implementation doesn’t examine the obj parameter.

Can be overridden by the user in subclasses. In such case it should return True if the given request has permission to delete the obj model instance. If obj is None, this should return True if the given request has permission to delete any object of the given type.

has_view_permission(request, obj=None)

Return True if the given request has permission to view the given Django model instance. The default implementation doesn’t examine the obj parameter.

If overridden by the user in subclasses, it should return True if the given request has permission to view the obj model instance. If obj is None, it should return True if the request has permission to view any object of the given type.

class music_publisher.admin.LibraryReleaseForm(*args, **kwargs)

Bases: django.forms.models.ModelForm

class music_publisher.admin.LibraryReleaseAdmin(model, admin_site)

Bases: music_publisher.admin.MusicPublisherAdmin

Admin interface for models.AlbumCD.

form

alias of LibraryReleaseForm

get_inline_instances(request, obj=None)

Limit inlines in popups.

save_model(request, obj, form, *args, **kwargs)

Save, then update last_change of the corresponding works.

get_queryset(request)

Optimized queryset for changelist view.

work_count(obj)

Return the work count from the database field, or count them. (dealing with legacy)

track_count(obj)

Return the work count from the database field, or count them. (dealing with legacy)

class music_publisher.admin.CommercialReleaseAdmin(model, admin_site)

Bases: music_publisher.admin.MusicPublisherAdmin

Admin interface for models.AlbumCD.

get_inline_instances(request, obj=None)

Limit inlines in popups.

get_queryset(request)

Optimized queryset for changelist view.

track_count(obj)

Return the work count from the database field, or count them. (dealing with legacy)

class music_publisher.admin.WriterAdmin(model, admin_site)

Bases: music_publisher.admin.MusicPublisherAdmin

Interface for models.Writer.

save_model(request, obj, form, *args, **kwargs)

Perform normal save_model, then update last_change of all connected works.

get_queryset(request)

Optimized queryset for changelist view.

work_count(obj)

Return the work count from the database field, or count them. (dealing with legacy)

class music_publisher.admin.AlternateTitleFormSet(data=None, files=None, instance=None, save_as_new=False, prefix=None, queryset=None, **kwargs)

Bases: django.forms.models.BaseInlineFormSet

Formset for AlternateTitleInline.

clean()
Performs these checks:
if suffix is used, then validates the total length
Returns:None
Raises:ValidationError
class music_publisher.admin.AlternateTitleInline(parent_model, admin_site)

Bases: django.contrib.admin.options.TabularInline

Inline interface for models.AlternateTitle.

model

alias of music_publisher.models.AlternateTitle

formset

alias of AlternateTitleFormSet

class music_publisher.admin.WriterInWorkFormSet(data=None, files=None, instance=None, save_as_new=False, prefix=None, queryset=None, **kwargs)

Bases: django.forms.models.BaseInlineFormSet

Formset for WriterInWorkInline.

clean()
Performs these checks:
at least one writer must be controlled, at least one writer music be Composer or Composer&Lyricist sum of relative shares must be ~100%
Returns:None
Raises:ValidationError
class music_publisher.admin.WriterInWorkInline(parent_model, admin_site)

Bases: django.contrib.admin.options.TabularInline

Inline interface for models.WriterInWork.

model

alias of music_publisher.models.WriterInWork

formset

alias of WriterInWorkFormSet

class music_publisher.admin.WorkAcknowledgementInline(parent_model, admin_site)

Bases: django.contrib.admin.options.TabularInline

Inline interface for models.WorkAcknowledgement, used in WorkAdmin.

Please note that normal users should only have a ‘view’ permission.

model

alias of music_publisher.models.WorkAcknowledgement

class music_publisher.admin.WorkForm(*args, **kwargs)

Bases: django.forms.models.ModelForm

class music_publisher.admin.WorkAdmin(model, admin_site)

Bases: music_publisher.admin.MusicPublisherAdmin

Admin interface for models.Work.

This is by far the most important part of the interface.

actions

batch actions used: create_cwr(), create_json()

Type:tuple
inlines

inlines used in change view: AlternateTitleInline, WriterInWorkInline, RecordingInline, ArtistInWorkInline, WorkAcknowledgementInline,

Type:tuple
form

alias of WorkForm

writer_last_names(obj)

This is a standard way how writers are shown in other apps.

percentage_controlled(obj)

Controlled percentage (sum of relative shares for controlled writers)

Please note that writers in work are already included in the queryset for other reasons, so no overhead except summing.

cwr_export_count(obj)

Return the count of CWR exports with the link to the filtered changelist view for CWRExportAdmin.

recording_count(obj)

Return the count of CWR exports with the link to the filtered changelist view for CWRExportAdmin.

get_queryset(request)

Optimized queryset for changelist view.

class InCWRListFilter(request, params, model, model_admin)

Bases: django.contrib.admin.filters.SimpleListFilter

Custom list filter if work is included in any of CWR files.

lookups(request, model_admin)

Simple Yes/No filter

queryset(request, queryset)

Filter if in any of CWR files.

class ACKSocietyListFilter(request, params, model, model_admin)

Bases: django.contrib.admin.filters.SimpleListFilter

Custom list filter of societies from ACK files.

lookups(request, model_admin)

Simple Yes/No filter

queryset(request, queryset)

Filter on society sending ACKs.

class ACKStatusListFilter(request, params, model, model_admin)

Bases: django.contrib.admin.filters.SimpleListFilter

Custom list filter on ACK status.

lookups(request, model_admin)

Simple Yes/No filter

queryset(request, queryset)

Filter on ACK status.

class HasISWCListFilter(request, params, model, model_admin)

Bases: django.contrib.admin.filters.SimpleListFilter

Custom list filter on the presence of ISWC.

lookups(request, model_admin)

Simple Yes/No filter

queryset(request, queryset)

Filter on presence of iswc.

class HasRecordingListFilter(request, params, model, model_admin)

Bases: django.contrib.admin.filters.SimpleListFilter

Custom list filter on the presence of first recording.

lookups(request, model_admin)

Simple Yes/No filter

queryset(request, queryset)

Filter on presence of models.Recording.

get_search_results(request, queryset, search_term)

Deal with the situation term is work ID.

save_model(request, obj, form, *args, **kwargs)

Given a model instance save it to the database.

create_cwr(request, qs)

Batch action that redirects to the add view for CWRExportAdmin with selected works.

create_json(request, qs, normalize=False)

Batch action that downloads a JSON file containing selected works.

Returns:JSON file with selected works
Return type:JsonResponse
get_actions(request)

Custom action disabling the default delete_selected.

get_inline_instances(request, obj=None)

Limit inlines in popups.

class music_publisher.admin.RecordingAdmin(model, admin_site)

Bases: music_publisher.admin.MusicPublisherAdmin

class HasISRCListFilter(request, params, model, model_admin)

Bases: django.contrib.admin.filters.SimpleListFilter

Custom list filter on the presence of ISRC.

lookups(request, model_admin)

Simple Yes/No filter

queryset(request, queryset)

Filter on presence of iswc.

get_queryset(request)

Optimized query regarding work name

class music_publisher.admin.CWRExportAdmin(model, admin_site)

Bases: django.contrib.admin.options.ModelAdmin

Admin interface for models.CWRExport.

work_count(obj)

Return the work count from the database field, or count them. (dealing with legacy)

get_preview(obj)

Get CWR preview.

If you are using highlighing, then override this method.

get_queryset(request)

Optimized query with count of works in the export.

get_readonly_fields(request, obj=None)

Read-only fields differ if CWR has been completed.

get_fields(request, obj=None)

Shown fields differ if CWR has been completed.

has_delete_permission(request, obj=None)

If CWR has been created, it can no longer be deleted, as it may have been sent. This may change once the delivery is automated.

get_form(request, obj=None, **kwargs)

Return a Form class for use in the admin add view. This is used by add_view and change_view.

add_view(request, form_url='', extra_context=None, work_ids=None)

Added work_ids as default for wizard from WorkAdmin.create_cwr().

change_view(request, object_id, form_url='', extra_context=None)

Normal change view with two sub-views defined by GET parameters:

Parameters:
  • preview – that returns the preview of CWR file,
  • download – that downloads the CWR file.

save_model() passes the main object, which is needed to fetch CWR from the external service, but only after related objects are saved.

class music_publisher.admin.ACKImportForm(data=None, files=None, auto_id='id_%s', prefix=None, initial=None, error_class=<class 'django.forms.utils.ErrorList'>, label_suffix=None, empty_permitted=False, instance=None, use_required_attribute=None, renderer=None)

Bases: django.forms.models.ModelForm

Form used for CWR acknowledgement imports.

acknowledgement_file

Field for file upload

Type:FileField
clean()

Perform usual clean, then process the file, returning the content field as if it was the TextField.

class music_publisher.admin.ACKImportAdmin(model, admin_site)

Bases: django.contrib.admin.options.ModelAdmin

Admin interface for models.ACKImport.

get_form(request, obj=None, **kwargs)

Returns a custom form for new objects, default one for changes.

get_fields(request, obj=None)

Return different fields for add vs change.

process(request, society_code, file_content)

Create appropriate WorkAcknowledgement objects, without duplicates.

Big part of this code should be moved to the model, left here because messaging is simpler.

save_model(request, obj, form, change)

Custom save_model, it ignores changes, validates the form for new instances, if valid, it processes the file and, upon success, calls super().save_model.

has_delete_permission(request, obj=None, *args, **kwargs)

Deleting ACK imports is a really bad idea.

music_publisher.tests module

Tests for music_publisher.

Please note that all these tests are functional (integration) tests, not unit tests.

music_publisher.tests.CONTENT

CWR ACK file contents

Type:str
class music_publisher.tests.ConstTest(methodName='runTest')

Bases: django.test.testcases.SimpleTestCase

class music_publisher.tests.CWRTemplatesTest(methodName='runTest')

Bases: django.test.testcases.SimpleTestCase

class music_publisher.tests.ValidatorsTest(methodName='runTest')

Bases: django.test.testcases.SimpleTestCase

class music_publisher.tests.ModelsSimpleTest(methodName='runTest')

Bases: django.test.testcases.TransactionTestCase

class music_publisher.tests.IntegrationTest(methodName='runTest')

Bases: django.test.testcases.TransactionTestCase

All integration tests in a single class.

setUp()

Set up the initial data.

get(path, re_post=None)

A helper method that simulates opening of view and then simulates manual changes and save.

test_admin_login()

Basic navigation tests.