diff --git a/src/MCPClient/lib/clientScripts/check_for_access_directory.py b/src/MCPClient/lib/clientScripts/check_for_access_directory.py index 44a17f0f74..27f926dc2c 100755 --- a/src/MCPClient/lib/clientScripts/check_for_access_directory.py +++ b/src/MCPClient/lib/clientScripts/check_for_access_directory.py @@ -35,7 +35,7 @@ from fileOperations import rename -def something( +def main( job, SIPDirectory, accessDirectory, @@ -45,11 +45,10 @@ def something( date, copy=False, ): - # exitCode = 435 exitCode = 179 job.pyprint(SIPDirectory) # For every file, & directory Try to find the matching file & directory in the objects directory - for path, dirs, files in os.walk(accessDirectory): + for path, _, files in os.walk(accessDirectory): for file in files: accessPath = os.path.join(path, file) objectPath = accessPath.replace(accessDirectory, objectsDirectory, 1) @@ -78,7 +77,7 @@ def something( for objectUUID, objectPath in files.values_list( "uuid", "currentlocation" ): - objectExtension = objectPath.replace(objectNameLike, "", 1) + objectExtension = objectPath.decode().replace(objectNameLike, "", 1) job.pyprint( objectName[objectNameExtensionIndex + 1 :], objectExtension, @@ -173,7 +172,7 @@ def call(jobs): except: job.pyprint("error creating DIP directory") - exitCode = something( + exitCode = main( job, SIPDirectory, accessDirectory, diff --git a/src/MCPClient/tests/test_check_for_access_directory.py b/src/MCPClient/tests/test_check_for_access_directory.py new file mode 100644 index 0000000000..01e84db0b0 --- /dev/null +++ b/src/MCPClient/tests/test_check_for_access_directory.py @@ -0,0 +1,121 @@ +import check_for_access_directory +import pytest +from django.utils import timezone +from job import Job +from main.models import Event +from main.models import File +from main.models import SIP + + +@pytest.mark.django_db +def test_main(mocker, tmp_path): + job = mocker.Mock(spec=Job) + date = timezone.now() + + sip_directory = tmp_path / "sip" + sip_directory.mkdir() + + sip = SIP.objects.create(currentpath=sip_directory.as_posix()) + + access_directory = tmp_path / "access" + access_directory.mkdir() + (access_directory / "file1.txt").touch() + (access_directory / "file2.txt").touch() + + objects_directory = tmp_path / "objects" + objects_directory.mkdir() + (objects_directory / "file1.txt").touch() + (objects_directory / "file2.txt").touch() + (objects_directory / "file3.txt").touch() + + dip_directory = tmp_path / "dip" + dip_directory.mkdir() + (dip_directory / "objects").mkdir() + + # Add access files to the database. + File.objects.create( + sip=sip, + originallocation=(access_directory / "file1.txt").as_posix().encode(), + currentlocation=(access_directory / "file1.txt").as_posix().encode(), + ) + File.objects.create( + sip=sip, + originallocation=(access_directory / "file2.txt").as_posix().encode(), + currentlocation=(access_directory / "file2.txt").as_posix().encode(), + ) + assert ( + File.objects.filter( + sip=sip, + currentlocation__startswith=access_directory.as_posix(), + ).count() + == 2 + ) + + # Add objects files to the database. + File.objects.create( + sip=sip, + originallocation=(objects_directory / "file1.txt").as_posix().encode(), + currentlocation=(objects_directory / "file1.txt").as_posix().encode(), + ) + File.objects.create( + sip=sip, + originallocation=(objects_directory / "file2.txt").as_posix().encode(), + currentlocation=(objects_directory / "file2.txt").as_posix().encode(), + ) + File.objects.create( + sip=sip, + originallocation=(objects_directory / "file3.txt").as_posix().encode(), + currentlocation=(objects_directory / "file3.txt").as_posix().encode(), + ) + + # The DIP objects directory is initially empty. + assert ( + File.objects.filter( + sip=sip, + currentlocation__startswith=(dip_directory / "objects").as_posix(), + ).count() + == 0 + ) + + # And there are no PREMIS "movement" events. + assert Event.objects.filter(event_type="movement").count() == 0 + + result = check_for_access_directory.main( + job, + sip_directory.as_posix(), + access_directory.as_posix(), + objects_directory.as_posix(), + dip_directory.as_posix(), + str(sip.uuid), + date, + ) + + # Files have been moved from the access directory to the DIP objects directory. + assert ( + File.objects.filter( + sip=sip, + currentlocation__startswith=access_directory.as_posix(), + ).count() + == 0 + ) + assert ( + File.objects.filter( + sip=sip, + currentlocation__startswith=(dip_directory / "objects").as_posix(), + currentlocation__endswith=".txt", + ).count() + == 2 + ) + + # And PREMIS "movement" events are created accordingly. + assert ( + Event.objects.filter( + event_type="movement", + event_outcome_detail__startswith=f'moved from="{access_directory.as_posix()}', + event_outcome_detail__contains=f'moved to="{(dip_directory / "objects").as_posix()}', + event_datetime__date=date, + ).count() + == 2 + ) + + assert result == 179 diff --git a/src/archivematicaCommon/lib/fileOperations.py b/src/archivematicaCommon/lib/fileOperations.py index 261def7d72..96566233a1 100644 --- a/src/archivematicaCommon/lib/fileOperations.py +++ b/src/archivematicaCommon/lib/fileOperations.py @@ -266,7 +266,7 @@ def updateFileLocation( To suppress creation of an event, pass the createEvent keyword argument (for example, if the file moved due to the renaming of a parent directory and not the file itself). """ if not fileUUID or fileUUID == "None": - kwargs = {"removedtime__isnull": True, "currentlocation": src} + kwargs = {"removedtime__isnull": True, "currentlocation": src.encode()} if sipUUID: kwargs["sip_id"] = sipUUID diff --git a/src/dashboard/src/main/models.py b/src/dashboard/src/main/models.py index 66c2c589a8..221818e9c7 100644 --- a/src/dashboard/src/main/models.py +++ b/src/dashboard/src/main/models.py @@ -759,8 +759,8 @@ def __str__(self): _("File %(uuid)s:%(originallocation)s now at %(currentlocation)s") % { "uuid": self.uuid, - "originallocation": self.originallocation, - "currentlocation": self.currentlocation, + "originallocation": self.originallocation.decode(), + "currentlocation": self.currentlocation.decode(), } ) @@ -812,8 +812,8 @@ def __str__(self): _("Directory %(uuid)s: %(originallocation)s now at %(currentlocation)s") % { "uuid": self.uuid, - "originallocation": self.originallocation, - "currentlocation": self.currentlocation, + "originallocation": self.originallocation.decode(), + "currentlocation": self.currentlocation.decode(), } )