Skip to content

Commit

Permalink
Add ability to access files locally
Browse files Browse the repository at this point in the history
In addition to the `docker cp` and `scp` methods already available, this
commit includes the ability to access files like sample data when it's
simply available in the local filesystem.
  • Loading branch information
sevein committed Oct 20, 2018
1 parent f3632fc commit 74ce110
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 8 deletions.
35 changes: 35 additions & 0 deletions amuser/am_localfs_ability.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
"""Archivematica LocalFS Ability
This module contains the ``ArchivematicaLocalFSAbility`` class, which encodes
the ability to transfer files when they're locally available.
"""

import logging
import os

from . import base


logger = logging.getLogger('amuser.localfs')


class ArchivematicaLocalFSAbility(base.Base):
"""Archivematica LocalFS Ability: the ability of an Archivematica user to
access files in the application environment when they're local.
"""

def read_server_file(self, server_file_path):
"""Return the local path to the file/dir requested.
If needed in the future, it should be possible to have a map of
transformations provided by the user running ``behave`` when the
assets are available in different lcoations, e.g.:
>>> for prefix, replacement in self.local_dirs_mapping:
>>> if server_file_path.startswith(prefix):
>>> return os.path.join(
>>> replacement, server_file_path[
>>> len(prefix):].lstrip("/"))
>>> return server_file_path
"""
return server_file_path
2 changes: 2 additions & 0 deletions amuser/amuser.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from . import am_api_ability
from . import am_browser_ability
from . import am_docker_ability
from . import am_localfs_ability
from . import am_ssh_ability
from . import am_mets_ability
from . import base
Expand Down Expand Up @@ -39,6 +40,7 @@ def __init__(self, **kwargs):
**kwargs)
self.docker = am_docker_ability.ArchivematicaDockerAbility(
**kwargs)
self.localfs = am_localfs_ability.ArchivematicaLocalFSAbility(**kwargs)
self.api = am_api_ability.ArchivematicaAPIAbility(**kwargs)
self.mets = am_mets_ability.ArchivematicaMETSAbility(**kwargs)

Expand Down
5 changes: 5 additions & 0 deletions docs/developer-documentation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,11 @@ ones.
``ssh`` calls.
- ``.docker``: the docker ability that spawns subprocesses to make calls to
``docker`` or ``docker-compose``.
- ``.localfs``: the localfs ability that makes posible to retrieve files
when ``docker cp`` or ``scp`` are not available, e.g. when ``behave`` can
be executed in the same machine where Archivematica is installed or inside
a container with access to the needed assets like it is done in the
Archivematica development environment based in Docker Compose.
- ``.api``: the API ability that uses Python's Requests library to make API
requests to Archivematica endpoints.
- ``.mets``: the METS ability that can parse Archivematica METS files and
Expand Down
18 changes: 13 additions & 5 deletions features/steps/aip_encryption_steps.py
Original file line number Diff line number Diff line change
Expand Up @@ -419,9 +419,12 @@ def step_impl(context):
if getattr(context.am_user.docker, 'docker_compose_path', None):
dip_local_path = context.am_user.docker.cp_server_file_to_local(
path_on_disk)
else:
elif context.am_user.ssh_accessible:
dip_local_path = context.am_user.ssh.scp_server_file_to_local(
path_on_disk)
else:
dip_local_path = context.am_user.localfs.read_server_file(
path_on_disk)
if dip_local_path is None:
logger.info(
'Unable to copy file %s from the server to the local file'
Expand Down Expand Up @@ -451,9 +454,12 @@ def step_impl(context, aips_store_path):
if getattr(context.am_user.docker, 'docker_compose_path', None):
aip_local_path = context.am_user.docker.cp_server_file_to_local(
aip_server_path)
else:
elif context.am_user.ssh_accessible:
aip_local_path = context.am_user.ssh.scp_server_file_to_local(
aip_server_path)
else:
aip_local_path = context.am_user.localfs.read_server_file(
aip_server_path)
if aip_local_path is None:
logger.info(
'Unable to copy file %s from the server to the local file'
Expand Down Expand Up @@ -574,12 +580,14 @@ def get_aip_is_encrypted(context, aip_description):
file_el = doc.find('mets:fileSec/mets:fileGrp/mets:file', ns)
flocat_el = file_el.find('mets:FLocat', ns)
xlink_href = flocat_el.get('{' + ns['xlink'] + '}href')
# Use `scp` or `docker cp` to copy the AIP on the server to a local
# directory.
# Copy the AIP on the server to a local directory.
if getattr(context.am_user.docker, 'docker_compose_path', None):
aip_local_path = context.am_user.docker.cp_server_file_to_local(xlink_href)
else:
elif context.am_user.ssh_accessible:
aip_local_path = context.am_user.ssh.scp_server_file_to_local(xlink_href)
else:
aip_local_path = context.am_user.localfs.read_server_file(
xlink_href)
if aip_local_path is None:
logger.warning(
'Unable to copy file %s from the server to the local file'
Expand Down
11 changes: 8 additions & 3 deletions features/steps/uuids_for_directories_steps.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,18 @@ def step_impl(context, dir_path):
if getattr(context.am_user.docker, 'docker_compose_path', None):
local_path = context.am_user.docker.cp_server_file_to_local(
dir_path)
else:
elif context.am_user.ssh_accessible:
local_path = context.am_user.ssh.scp_server_file_to_local(
dir_path)
else:
local_path = context.am_user.localfs.read_server_file(dir_path)
else:
if getattr(context.am_user.docker, 'docker_compose_path', None):
local_path = context.am_user.docker.cp_server_dir_to_local(dir_path)
else:
elif context.am_user.ssh_accessible:
local_path = context.am_user.ssh.scp_server_dir_to_local(dir_path)
else:
local_path = context.am_user.localfs.read_server_file(dir_path)
if local_path is None:
msg = (
'Unable to copy item {} from the server to the local file'
Expand All @@ -58,7 +62,8 @@ def step_impl(context, dir_path):
dir_local_path = local_path
if dir_is_zipped:
dir_local_path = utils.unzip(local_path)
assert os.path.isdir(dir_local_path)
assert os.path.isdir(dir_local_path), \
"%s is not a directory" % dir_local_path
non_root_paths = []
non_root_file_paths = []
empty_dirs = []
Expand Down

0 comments on commit 74ce110

Please sign in to comment.