Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 40 additions & 10 deletions churchtools_api/songs.py
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ def delete_song(self, song_id: int) -> bool:

return True

def contains_song_tag(self, song_id: int, song_tag_name: int) -> bool:
def contains_song_tag(self, song_id: int, song_tag_name: str) -> bool:
"""Helper which checks if a specific song_tag_id is present on a song.

Arguments:
Expand All @@ -317,13 +317,12 @@ def contains_song_tag(self, song_id: int, song_tag_name: int) -> bool:
tags = self.get_tag(domain_type="song", domain_id=song_id, rtype="name_dict")
return song_tag_name in tags

def get_songs_by_tag(self, song_tag_name: int) -> list[dict]:
def get_songs_by_tag(self, song_tag_name: str) -> list[dict]:
"""Helper which returns all songs that contain have a specific tag.

Arguments:
song_tag_name: ChurchTools site specific song_tag_id which should be used
OR
song_tag_id
song_tag_name: name of a song tag that is used
in respective ChurchTools instace

Returns:
list of songs
Expand Down Expand Up @@ -367,7 +366,7 @@ def get_song_arrangement(
return next(
arrangement
for arrangement in song["arrangements"]
if song["arrangements"][0]["isDefault"]
if arrangement["isDefault"]
)

def create_song_arrangement(self, song_id: int, arrangement_name: str) -> int:
Expand Down Expand Up @@ -425,6 +424,10 @@ def edit_song_arrangement(
beat: (str) e.g. 4/4.
duration: (int) lenght in full seconds.
note: (str) more detailed explanation text.
source_id: (int) id of the source as defined in masterdata
source_name_short: (str) short name of source - will be mapped to source_id
source_name: (str) full name of source - will be mapped to source_id
source_reference: (str) source reference e.g. number within source.

Returns:
if changes were applied successful
Expand All @@ -434,16 +437,20 @@ def edit_song_arrangement(
existing_arrangement = self.get_song_arrangement(
song_id=song_id, arrangement_id=arrangement_id
)

if isinstance(kwargs.get("source_id"), int):
source_id = kwargs.get("source_id")
elif isinstance(kwargs.get("source_id"), str):
source_id = self.lookup_song_source_as_id(shortname=kwargs.get("source_id"))
elif isinstance(kwargs.get("source_name_short"), str):
source_id = self.lookup_song_source_as_id(
shortname=kwargs.get("source_name_short")
)
elif isinstance(kwargs.get("source_name"), str):
source_id = self.lookup_song_source_as_id(
longname=kwargs.get("source_name")
)
else:
source_id = self.lookup_song_source_as_id(
shortname=existing_arrangement["sourceName"]
)

data = {
"name": kwargs.get("name", existing_arrangement["name"]),
"key": kwargs.get("key", existing_arrangement["key"]),
Expand All @@ -453,6 +460,10 @@ def edit_song_arrangement(
"description": kwargs.get(
"description", existing_arrangement["description"]
),
"sourceId": source_id,
"sourceReference": kwargs.get(
"source_reference", existing_arrangement["sourceReference"]
),
}
response = self.session.put(url=url, json=data)
if response.status_code != requests.codes.ok:
Expand All @@ -479,3 +490,22 @@ def delete_song_arrangement(self, song_id: int, arrangement_id: int) -> bool:
return False

return True

def set_default_arrangement(self, song_id: int, arrangement_id: int) -> bool:
"""Modify which arrangement is labeled as default for one song.

Args:
song_id: the number of the song to modify
arrangement_id: the arrangement id within the song to delete

Returns:
if deleted successfull
"""
url = f"{self.domain}/api/songs/{song_id}/arrangements/{arrangement_id}/default"

response = self.session.patch(url=url)
if response.status_code != requests.codes.no_content:
logger.error(response)
return False

return True
4 changes: 2 additions & 2 deletions churchtools_api/tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,8 @@ def remove_tag(self, domain_type: str, domain_id: str, tag_name: str) -> bool:
return True

def get_tag(
self, domain_type: str, domain_id: str, rtype: str = "original"
) -> list[dict]:
self, domain_type: str, domain_id: int, rtype: str = "original"
) -> list[dict] | None:
"""Retrieves the readable tags of one single object.

Args:
Expand Down
61 changes: 45 additions & 16 deletions tests/test_churchtools_api_songs.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def test_get_songs(self) -> None:
depend on the target system!
the hard coded sample exists on ELKW1610.KRZ.TOOLS
"""
SAMPLE_SONG = {"id":2034,"name":"sample"}
SAMPLE_SONG = {"id": 2034, "name": "sample"}

songs = self.api.get_songs()
LENGTH_OF_DEFAULT_PAGINATION = 50
Expand Down Expand Up @@ -332,15 +332,24 @@ def test_create_edit_delete_song_arrangement(self) -> None:
SAMPLE_ARRANGEMENT_NAME2 = "TEST_BEZEICHNUNG"
SAMPLE_PARAMS = {
"name": SAMPLE_ARRANGEMENT_NAME2,
"sourceName": next(iter(SAMPLE_SOURCE.values())),
"sourceReference": "source_ref",
"key": "F",
"tempo": 50,
"beat": "beat",
"duration": 60,
"description": "note",
}
key_map = {
"sourceReference": "source_reference",
"sourceName": "source_name_short",
}
formatted_params = {key_map.get(k, k): v for k, v in SAMPLE_PARAMS.items()}

was_applied = self.api.edit_song_arrangement(
song_id=SAMPLE_SONG_ID, arrangement_id=arrangement_id, **SAMPLE_PARAMS
song_id=SAMPLE_SONG_ID, arrangement_id=arrangement_id, **formatted_params
)

assert was_applied
created_arrangement = self.api.get_song_arrangement(
song_id=SAMPLE_SONG_ID, arrangement_id=arrangement_id
Expand All @@ -351,22 +360,42 @@ def test_create_edit_delete_song_arrangement(self) -> None:
for expected_key, expected_value in SAMPLE_PARAMS.items()
)

# edit2 - source as key id
SAMPLE_PARAMS_SHORT = {
"source_id": int(next(iter(SAMPLE_SOURCE.keys()))),
}
was_applied = self.api.edit_song_arrangement(
song_id=SAMPLE_SONG_ID, arrangement_id=arrangement_id, **SAMPLE_PARAMS_SHORT
)
assert was_applied
created_arrangement = self.api.get_song_arrangement(
song_id=SAMPLE_SONG_ID, arrangement_id=arrangement_id
)
assert created_arrangement["sourceName"] == next(iter(SAMPLE_SOURCE.values()))
assert created_arrangement["duration"] == SAMPLE_PARAMS["duration"]

# delete
was_deleted = self.api.delete_song_arrangement(
song_id=SAMPLE_SONG_ID, arrangement_id=arrangement_id
)
assert was_deleted

def test_set_default_arrangement(self) -> None:
"""Test method to modify default arrangement.

IMPORTANT - This test method and the parameters used depend on target system!
the hard coded sample exists on ELKW1610.KRZ.TOOLS
"""
SAMPLE_SONG_ID = 408
SAMPLE_DEFAULT_ARRANGEMENT_ID = 5272
SAMPLE_OTHER_ARRANGEMENT_ID = 5374

# check pre-existing default situation
assert (
self.api.get_song_arrangement(song_id=SAMPLE_SONG_ID)["id"]
== SAMPLE_DEFAULT_ARRANGEMENT_ID
)

# change default
was_changed = self.api.set_default_arrangement(
song_id=SAMPLE_SONG_ID, arrangement_id=SAMPLE_OTHER_ARRANGEMENT_ID
)
assert was_changed

# check modified default situation
assert (
self.api.get_song_arrangement(song_id=SAMPLE_SONG_ID)["id"]
== SAMPLE_OTHER_ARRANGEMENT_ID
)

# reset to original default situation
was_reset = self.api.set_default_arrangement(
song_id=SAMPLE_SONG_ID, arrangement_id=SAMPLE_DEFAULT_ARRANGEMENT_ID
)
assert was_reset
Loading