Skip to content

Commit

Permalink
SongBeamerQS #7 and #6 Download SNG if local file does not exist
Browse files Browse the repository at this point in the history
moved api out of read_baiersbronn_ct_songs to generalize and refactored to get_ct_songs_as_df
and stubs for tests related to #13 #14 #15
  • Loading branch information
bensteUEM committed Jan 30, 2023
1 parent 8ccc33d commit 2367811
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 1 deletion.
60 changes: 59 additions & 1 deletion TestMain.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import logging
import os
import unittest

import pandas
Expand All @@ -8,7 +9,7 @@
import SNG_DEFAULTS
from main import check_ct_song_categories_exist_as_folder, parse_sng_from_directory, read_baiersbronn_songs_to_df, \
generate_songbook_column, get_ct_songs_as_df, validate_ct_songs_exist_locally_by_name_and_category, \
clean_all_songs
clean_all_songs, download_missing_online_songs


class TestSNG(unittest.TestCase):
Expand Down Expand Up @@ -132,3 +133,60 @@ def test_emptied_song(self):
'FJ3', ['238 Der Herr segne dich.sng'])
self.assertIn('Refrain', songs_temp[0].content.keys())
songs_temp = read_baiersbronn_songs_to_df()

def test_add_id_to_local_song_if_available_in_ct(self): # TODO #13
self.assertFalse(True, 'Not Implemented')

def test_download_missing_online_songs(self):
"""
ELKW1610.krz.tools specific test case for the named function (using 2 specific song IDs)
deletes EG 002 if exists locally
Reads one local sng file (EG 001)
tries to detect that EG002 from CT is missing
downloads the file
checks if download success
deletes file
:return:
"""

songs_temp = []
dirname = 'testData/'
dirprefix = 'TEST'

test2name = '002 Er ist die rechte Freudensonn.sng'
test2path = dirname + '/EG Lieder/' + test2name

exists = os.path.exists(test2path)
if exists:
os.remove(test2path)

songs = parse_sng_from_directory(dirname, dirprefix)

for key, value in SNG_DEFAULTS.KnownFolderWithPrefix.items():
dirname = './testData/' + key
if not os.path.exists(dirname):
continue
dirprefix = value
songs_temp.extend(parse_sng_from_directory(dirname, dirprefix))

df_sng_test = pd.DataFrame(songs_temp, columns=["SngFile"])
for index, value in df_sng_test['SngFile'].items():
df_sng_test.loc[(index, 'filename')] = value.filename
df_sng_test.loc[(index, 'path')] = value.path

api = ChurchToolsApi('https://elkw1610.krz.tools')
ct_songs = [api.get_songs(song_id=762), api.get_songs(song_id=1113)]
df_ct_test = pd.json_normalize(ct_songs)

result = download_missing_online_songs(df_sng_test, df_ct_test, api)
self.assertTrue(result)

exists = os.path.exists(test2path)
self.assertTrue(exists)
os.remove(test2path)

def test_upload_new_local_songs_and_generate_ct_id(self): # TODO #15
self.assertFalse(True, 'Not Implemented')

def test_upload_local_songs_by_id(self):
self.assertFalse(True, 'Not Implemented') # TODO #14
41 changes: 41 additions & 0 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,47 @@ def add_id_to_local_song_if_available_in_ct(df_sng, df_ct):
overwrite_id_by_name_cat[~missing_files]['SngFile_x'].apply(lambda x: x.write_file())


def download_missing_online_songs(df_sng, df_ct, ct_api_reference):
"""
Function which will check which songs are missing (by ID) and tries to download them to the respective folders
It is highly recommended to execute add_id_to_local_song_if_available_in_ct() and
upload_new_local_songs_and_generate_ct_id() before in order to try to match all songs local and avoid duplicates
:param df_sng: DataFrame with all local files
:param df_ct: DataFrame with all online files
:param ct_api_reference: direct access to ChurchTools API instance
:return: Success message
:rtype: bool
"""

compare = validate_ct_songs_exist_locally_by_id(df_ct, df_sng)
song_path = compare[compare['path'].notnull()].iloc[0]['path']
collection_path = "/".join(song_path.split('/')[:-1])

ids = compare[compare['SngFile'].apply(lambda x: not isinstance(x, SngFile))]['id']

is_successful = True
for id in ids:
song = ct_api_reference.get_songs(song_id=id)
logging.debug('Downloading CT song id={} "{}" ({})'.format(id, song['name'], song['category']))

default_arrangement_id = [item['id'] for item in song['arrangements'] if item['isDefault'] is True][0]
category_name = song['category']['name']
file_path_in_collection = os.sep.join([collection_path, category_name]) # TODO #7 check if filename exists
filename = '{}.sng'.format(song['name'])

result = ct_api_reference.file_download(filename=filename,
domain_type='song_arrangement',
domain_identifier=default_arrangement_id,
path_for_download=file_path_in_collection)
if result:
logging.debug('Downloaded {} into {} from CT IT {}'.format(filename, file_path_in_collection, id))
else:
logging.debug('Failed to download {} into {} from CT IT {}'.format(filename, file_path_in_collection, id))
is_successful |= result

return is_successful


def upload_new_local_songs_and_generate_ct_id(df_sng, df_ct, default_tag_id=52):
"""
Helper Function which creates new ChurchTools Songs for all SNG Files from dataframe which don't have a song ID
Expand Down

0 comments on commit 2367811

Please sign in to comment.