Current section
Files
Jump to
Current section
Files
lib/dspace/api/community.ex
defmodule DSpace.API.Community do
@moduledoc """
Functions for working with DSpace Communities.
Communities are top-level organizational units containing Collections of Items.
"""
@behaviour DSpace.API.Resource
import DSpace.Utils, only: [is_nonempty_binary: 1, pop_pagination: 1]
alias DSpace.API.Operation
alias DSpace.API.Resource
alias DSpace.API.Search
alias DSpace.API.StreamBuilder
alias DSpace.API.Transform
@ep_core "/api/core/communities"
@ep_core_toplevel @ep_core <> "/search/top"
# Public API
@doc """
Lists collections within a community.
This operation can be streamed.
## Options
* `:page` - Page number (0-based, defaults to 0)
* `:size` - Number of items per page (usually defaults to 20)
"""
@spec list_collections(binary(), keyword()) :: Operation.t()
def list_collections(uuid, options \\ []) when is_nonempty_binary(uuid) do
{pagination, other_options} = pop_pagination(options)
op = %Operation.JSON{
path: @ep_core <> "/" <> uuid <> "/collections",
params: pagination ++ other_options,
transformer:
&Transform.transform_collection(&1,
extract: ["_embedded", "collections"]
)
}
%{op | stream_impl: &StreamBuilder.new(&1, op, &2)}
end
@doc """
Lists subcommunities within a community.
This operation can be streamed.
## Options
* `:page` - Page number (0-based, defaults to 0)
* `:size` - Number of items per page (usually defaults to 20)
"""
@spec list_subcommunities(binary(), keyword()) :: Operation.t()
def list_subcommunities(uuid, options \\ []) when is_nonempty_binary(uuid) do
{pagination, other_options} = pop_pagination(options)
op = %Operation.JSON{
path: @ep_core <> "/" <> uuid <> "/subcommunities",
params: pagination ++ other_options,
transformer:
&Transform.transform_collection(&1,
extract: ["_embedded", "subcommunities"]
)
}
%{op | stream_impl: &StreamBuilder.new(&1, op, &2)}
end
@doc """
Fetches the parent community of a community.
"""
@spec fetch_parent(binary()) :: Operation.t()
def fetch_parent(uuid) when is_nonempty_binary(uuid) do
%Operation.JSON{
path: @ep_core <> "/" <> uuid <> "/parentCommunity",
expected_status: [200, 204]
}
end
@doc """
Lists top-level communities (communities without a parent).
This operation can be streamed.
## Options
* `:page` - Page number (0-based, defaults to 0)
* `:size` - Number of items per page (usually defaults to 20)
"""
@spec list_toplevel(keyword()) :: Operation.t()
def list_toplevel(options \\ []) do
{pagination, other_options} = pop_pagination(options)
op = %Operation.JSON{
path: @ep_core_toplevel,
params: pagination ++ other_options,
transformer:
&Transform.transform_collection(&1,
extract: ["_embedded", "communities"]
)
}
%{op | stream_impl: &StreamBuilder.new(&1, op, &2)}
end
# Callbacks
@doc """
Fetches a single community by UUID.
"""
@impl Resource
@spec fetch(binary(), keyword()) :: Operation.t()
def fetch(uuid, _options \\ []) when is_nonempty_binary(uuid) do
%Operation.JSON{path: @ep_core <> "/" <> uuid}
end
@doc """
Finds communities using Discovery search.
This operation can be streamed.
## Parameters
* `options` - Search options, see `DSpace.API.Search.query/1` for details
## Examples
# Find all communities
Community.find([])
# Find all communities with filters
Community.find(filters: [%{filter: "subject", operator: "contains", value: "science"}])
# Simple community search with text query
Community.find(query: "research community")
# Search with additional filters
Community.find(query: "library", filters: [%{filter: "subject", operator: "contains", value: "science"}])
# Search within a specific parent community
Community.find(query: "academic", scope: "parent-community-uuid")
"""
@impl Resource
@spec find(keyword()) :: Operation.t()
def find(options \\ []) when is_list(options) do
search_options =
options
|> Keyword.put(:dsoType, "Community")
# The CRIS fork disables communities and collections in the default configuration
|> Keyword.put(:configuration, "communityOrCollection")
Search.query(search_options)
end
@doc """
Lists all communities from the repository.
This operation can be streamed.
## Options
* `:page` - Page number (0-based, defaults to 0)
* `:size` - Number of items per page (usually defaults to 20)
"""
@impl Resource
@spec list(keyword()) :: Operation.t()
def list(options \\ []) do
{pagination, other_options} = pop_pagination(options)
op = %Operation.JSON{
path: @ep_core,
params: pagination ++ other_options,
transformer:
&Transform.transform_collection(&1,
extract: ["_embedded", "communities"]
)
}
%{op | stream_impl: &StreamBuilder.new(&1, op, &2)}
end
@doc """
Creates a new community.
Communities can be top-level or subcommunities with a parent.
## Options
* `:parent` - UUID of the parent community
"""
@impl Resource
@spec create(map(), keyword()) :: Operation.t()
def create(community, options \\ []) when is_map(community) do
params = maybe_add_parent([], options[:parent])
%Operation.JSON{
path: @ep_core,
http_method: :post,
params: params,
data: community
}
end
@doc """
Updates an existing community.
"""
@impl Resource
@spec update(binary(), list(), keyword()) :: Operation.t()
def update(uuid, updates, _options \\ []) when is_nonempty_binary(uuid) and is_list(updates) do
%Operation.JSON{
path: @ep_core <> "/" <> uuid,
http_method: :patch,
data: updates
}
end
@doc """
Replaces an existing community.
"""
@impl Resource
@spec replace(binary(), map(), keyword()) :: Operation.t()
def replace(uuid, community, _options \\ []) when is_nonempty_binary(uuid) and is_map(community) do
%Operation.JSON{
path: @ep_core <> "/" <> uuid,
http_method: :put,
data: community
}
end
@doc """
Deletes a community.
"""
@impl Resource
@spec delete(binary(), keyword()) :: Operation.t()
def delete(uuid, _options \\ []) when is_nonempty_binary(uuid) do
%Operation.JSON{
path: @ep_core <> "/" <> uuid,
http_method: :delete,
transformer: fn _ -> :ok end
}
end
# Private helpers
defp maybe_add_parent(params, nil), do: params
defp maybe_add_parent(params, parent_uuid) when is_nonempty_binary(parent_uuid) do
[{:parent, parent_uuid} | params]
end
end