chore: refactored mcp.ex
This commit is contained in:
112
lib/bds/mcp/resources.ex
Normal file
112
lib/bds/mcp/resources.ex
Normal file
@@ -0,0 +1,112 @@
|
||||
defmodule BDS.MCP.Resources do
|
||||
@moduledoc false
|
||||
|
||||
alias BDS.MCP.ProposalStore
|
||||
alias BDS.MCP.Queries
|
||||
alias BDS.MCP.Util
|
||||
alias BDS.Media.Media, as: MediaAsset
|
||||
alias BDS.Metadata
|
||||
alias BDS.Posts.Post
|
||||
alias BDS.Repo
|
||||
alias BDS.Search
|
||||
alias BDS.Tags
|
||||
|
||||
@typedoc "Resource descriptor returned by `list/0`."
|
||||
@type descriptor :: %{name: String.t(), uri: String.t()}
|
||||
|
||||
@spec list() :: [descriptor()]
|
||||
def list do
|
||||
[
|
||||
%{name: "posts", uri: "bds://posts"},
|
||||
%{name: "media", uri: "bds://media"},
|
||||
%{name: "tags", uri: "bds://tags"},
|
||||
%{name: "categories", uri: "bds://categories"}
|
||||
]
|
||||
end
|
||||
|
||||
@spec read(String.t()) :: {:ok, term()} | {:error, term()}
|
||||
def read(uri) when is_binary(uri) do
|
||||
ProposalStore.ensure_started()
|
||||
|
||||
case URI.parse(uri) do
|
||||
%URI{scheme: "bds", host: "posts", path: nil} -> {:ok, posts_resource(0)}
|
||||
%URI{scheme: "bds", host: "media", path: nil} -> {:ok, media_resource(0)}
|
||||
%URI{scheme: "bds", host: "tags", path: nil} -> {:ok, tags_resource()}
|
||||
%URI{scheme: "bds", host: "categories", path: nil} -> {:ok, categories_resource()}
|
||||
%URI{scheme: "bds", host: "posts", path: "/" <> id} -> read_post_resource(id)
|
||||
%URI{scheme: "bds", host: "media", path: "/" <> id} -> read_media_resource(id)
|
||||
_other -> {:error, :not_found}
|
||||
end
|
||||
end
|
||||
|
||||
defp posts_resource(offset) do
|
||||
project = Queries.active_project!()
|
||||
page_size = Queries.page_size()
|
||||
{:ok, result} = Search.search_posts(project.id, "", %{offset: offset, limit: page_size})
|
||||
|
||||
%{
|
||||
"items" => Enum.map(result.posts, &Queries.post_summary/1),
|
||||
"total" => result.total,
|
||||
"offset" => result.offset,
|
||||
"limit" => result.limit,
|
||||
"has_more" => result.offset + result.limit < result.total
|
||||
}
|
||||
end
|
||||
|
||||
defp media_resource(offset) do
|
||||
project = Queries.active_project!()
|
||||
page_size = Queries.page_size()
|
||||
{:ok, result} = Search.search_media(project.id, "", %{offset: offset, limit: page_size})
|
||||
|
||||
%{
|
||||
"items" => Enum.map(result.media, &Util.sanitize/1),
|
||||
"total" => result.total,
|
||||
"offset" => result.offset,
|
||||
"limit" => result.limit,
|
||||
"has_more" => result.offset + result.limit < result.total
|
||||
}
|
||||
end
|
||||
|
||||
defp tags_resource do
|
||||
project = Queries.active_project!()
|
||||
tags = Tags.list_tags(project.id)
|
||||
|
||||
%{
|
||||
"items" =>
|
||||
Enum.map(tags, fn tag ->
|
||||
%{
|
||||
"id" => tag.id,
|
||||
"name" => tag.name,
|
||||
"color" => tag.color,
|
||||
"post_count" => Queries.tag_post_count(project.id, tag.name)
|
||||
}
|
||||
end)
|
||||
}
|
||||
end
|
||||
|
||||
defp categories_resource do
|
||||
project = Queries.active_project!()
|
||||
{:ok, metadata} = Metadata.get_project_metadata(project.id)
|
||||
|
||||
%{
|
||||
"items" =>
|
||||
Enum.map(metadata.categories, fn category ->
|
||||
%{"name" => category, "post_count" => Queries.category_post_count(project.id, category)}
|
||||
end)
|
||||
}
|
||||
end
|
||||
|
||||
defp read_post_resource(id) do
|
||||
case Repo.get(Post, id) do
|
||||
%Post{} = post -> {:ok, Queries.post_detail(post)}
|
||||
nil -> {:error, :not_found}
|
||||
end
|
||||
end
|
||||
|
||||
defp read_media_resource(id) do
|
||||
case Repo.get(MediaAsset, id) do
|
||||
%MediaAsset{} = media -> {:ok, Util.sanitize(media)}
|
||||
nil -> {:error, :not_found}
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user