Use JSON views for API (#64)

* AwardJson, LinkJson, UserJson to views

* FilterJson -> view

* ForumJson -> view

* TopicJson -> view

* PostJson -> view

* TagJson -> view

* CommentJson -> view

* GalleryJson -> view
This commit is contained in:
liamwhite 2020-03-29 21:11:38 -04:00 committed by GitHub
parent 196c5e14b6
commit 723bfa213f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
27 changed files with 245 additions and 169 deletions

View file

@ -1,7 +1,6 @@
defmodule PhilomenaWeb.Api.Json.CommentController do
use PhilomenaWeb, :controller
alias PhilomenaWeb.CommentJson
alias Philomena.Comments.Comment
alias Philomena.Repo
import Ecto.Query
@ -25,7 +24,7 @@ defmodule PhilomenaWeb.Api.Json.CommentController do
|> text("")
true ->
json(conn, %{comment: CommentJson.as_json(comment)})
render(conn, "show.json", comment: comment)
end
end
end

View file

@ -1,7 +1,6 @@
defmodule PhilomenaWeb.Api.Json.Filter.SystemFilterController do
use PhilomenaWeb, :controller
alias PhilomenaWeb.FilterJson
alias Philomena.Filters.Filter
alias Philomena.Repo
import Ecto.Query
@ -13,9 +12,8 @@ defmodule PhilomenaWeb.Api.Json.Filter.SystemFilterController do
|> order_by(asc: :id)
|> Repo.paginate(conn.assigns.scrivener)
json(conn, %{
filters: Enum.map(system_filters, &FilterJson.as_json/1),
total: system_filters.total_entries
})
conn
|> put_view(PhilomenaWeb.Api.Json.FilterView)
|> render("index.json", filters: system_filters, total: system_filters.total_entries)
end
end

View file

@ -1,7 +1,6 @@
defmodule PhilomenaWeb.Api.Json.Filter.UserFilterController do
use PhilomenaWeb, :controller
alias PhilomenaWeb.FilterJson
alias Philomena.Filters.Filter
alias Philomena.Repo
import Ecto.Query
@ -22,10 +21,9 @@ defmodule PhilomenaWeb.Api.Json.Filter.UserFilterController do
|> order_by(asc: :id)
|> Repo.paginate(conn.assigns.scrivener)
json(conn, %{
filters: Enum.map(user_filters, &FilterJson.as_json/1),
total: user_filters.total_entries
})
conn
|> put_view(PhilomenaWeb.Api.Json.FilterView)
|> render("index.json", filters: user_filters, total: user_filters.total_entries)
end
end
end

View file

@ -1,7 +1,6 @@
defmodule PhilomenaWeb.Api.Json.FilterController do
use PhilomenaWeb, :controller
alias PhilomenaWeb.FilterJson
alias Philomena.Filters.Filter
alias Philomena.Repo
import Ecto.Query
@ -17,7 +16,7 @@ defmodule PhilomenaWeb.Api.Json.FilterController do
case Canada.Can.can?(user, :show, filter) do
true ->
json(conn, %{filter: FilterJson.as_json(filter)})
render(conn, "show.json", filter: filter)
_ ->
conn

View file

@ -1,11 +1,29 @@
defmodule PhilomenaWeb.Api.Json.Forum.Topic.PostController do
use PhilomenaWeb, :controller
alias PhilomenaWeb.PostJson
alias Philomena.Posts.Post
alias Philomena.Repo
import Ecto.Query
def index(conn, %{"forum_id" => forum_id, "topic_id" => topic_id}) do
page = conn.assigns.pagination.page_number
posts =
Post
|> join(:inner, [p], _ in assoc(p, :topic))
|> join(:inner, [_p, t], _ in assoc(t, :forum))
|> where(destroyed_content: false)
|> where([_p, t], t.hidden_from_users == false and t.slug == ^topic_id)
|> where([_p, _t, f], f.access_level == "normal" and f.short_name == ^forum_id)
|> where([p], p.topic_position >= ^(25 * (page - 1)) and p.topic_position < ^(25 * page))
|> order_by(asc: :topic_position)
|> preload([:user, :topic])
|> preload([_p, t, _f], topic: t)
|> Repo.all()
render(conn, "index.json", posts: posts, total: hd(posts).topic.post_count)
end
def show(conn, %{"forum_id" => forum_id, "topic_id" => topic_id, "id" => post_id}) do
post =
Post
@ -25,35 +43,7 @@ defmodule PhilomenaWeb.Api.Json.Forum.Topic.PostController do
|> text("")
true ->
json(conn, %{post: PostJson.as_json(post)})
end
end
def index(conn, %{"forum_id" => forum_id, "topic_id" => topic_id}) do
page = conn.assigns.pagination.page_number
posts =
Post
|> join(:inner, [p], _ in assoc(p, :topic))
|> join(:inner, [_p, t], _ in assoc(t, :forum))
|> where(destroyed_content: false)
|> where([_p, t], t.hidden_from_users == false and t.slug == ^topic_id)
|> where([_p, _t, f], f.access_level == "normal" and f.short_name == ^forum_id)
|> where([p], p.topic_position >= ^(25 * (page - 1)) and p.topic_position < ^(25 * page))
|> order_by(asc: :topic_position)
|> preload([:user, :topic])
|> preload([_p, t, _f], topic: t)
|> Repo.all()
case posts do
[] ->
json(conn, %{posts: Enum.map(posts, &PostJson.as_json/1), page: page})
_ ->
json(conn, %{
posts: Enum.map(posts, &PostJson.as_json/1),
total: hd(posts).topic.post_count
})
render(conn, "show.json", post: post)
end
end
end

View file

@ -1,11 +1,23 @@
defmodule PhilomenaWeb.Api.Json.Forum.TopicController do
use PhilomenaWeb, :controller
alias PhilomenaWeb.TopicJson
alias Philomena.Topics.Topic
alias Philomena.Repo
import Ecto.Query
def index(conn, %{"forum_id" => id}) do
topics =
Topic
|> join(:inner, [t], _ in assoc(t, :forum))
|> where(hidden_from_users: false)
|> where([_t, f], f.access_level == "normal" and f.short_name == ^id)
|> order_by(desc: :sticky, desc: :last_replied_to_at)
|> preload([:user])
|> Repo.paginate(conn.assigns.scrivener)
render(conn, "index.json", topics: topics, total: topics.total_entries)
end
def show(conn, %{"forum_id" => forum_id, "id" => id}) do
topic =
Topic
@ -24,23 +36,7 @@ defmodule PhilomenaWeb.Api.Json.Forum.TopicController do
|> text("")
true ->
json(conn, %{topic: TopicJson.as_json(topic)})
render(conn, "show.json", topic: topic)
end
end
def index(conn, %{"forum_id" => id}) do
topics =
Topic
|> join(:inner, [t], _ in assoc(t, :forum))
|> where(hidden_from_users: false)
|> where([_t, f], f.access_level == "normal" and f.short_name == ^id)
|> order_by(desc: :sticky, desc: :last_replied_to_at)
|> preload([:user])
|> Repo.paginate(conn.assigns.scrivener)
json(conn, %{
topic: Enum.map(topics, &TopicJson.as_json/1),
total: topics.total_entries
})
end
end

View file

@ -1,11 +1,20 @@
defmodule PhilomenaWeb.Api.Json.ForumController do
use PhilomenaWeb, :controller
alias PhilomenaWeb.ForumJson
alias Philomena.Forums.Forum
alias Philomena.Repo
import Ecto.Query
def index(conn, _params) do
forums =
Forum
|> where(access_level: "normal")
|> order_by(asc: :name)
|> Repo.paginate(conn.assigns.scrivener)
render(conn, forums: forums, total: forums.total_entries)
end
def show(conn, %{"id" => id}) do
forum =
Forum
@ -20,20 +29,7 @@ defmodule PhilomenaWeb.Api.Json.ForumController do
|> text("")
true ->
json(conn, %{forum: ForumJson.as_json(forum)})
render(conn, forum: forum)
end
end
def index(conn, _params) do
forums =
Forum
|> where(access_level: "normal")
|> order_by(asc: :name)
|> Repo.paginate(conn.assigns.scrivener)
json(conn, %{
forums: Enum.map(forums, &ForumJson.as_json/1),
total: forums.total_entries
})
end
end

View file

@ -1,7 +1,6 @@
defmodule PhilomenaWeb.Api.Json.PostController do
use PhilomenaWeb, :controller
alias PhilomenaWeb.PostJson
alias Philomena.Posts.Post
alias Philomena.Repo
import Ecto.Query
@ -25,7 +24,9 @@ defmodule PhilomenaWeb.Api.Json.PostController do
|> text("")
true ->
json(conn, %{post: PostJson.as_json(post)})
conn
|> put_view(PhilomenaWeb.Api.Json.Forum.Topic.PostView)
|> render("show.json", post: post)
end
end
end

View file

@ -1,26 +1,25 @@
defmodule PhilomenaWeb.Api.Json.ProfileController do
use PhilomenaWeb, :controller
alias PhilomenaWeb.UserJson
alias Philomena.Users.User
alias Philomena.Repo
import Ecto.Query
def show(conn, %{"id" => id}) do
profile =
user =
User
|> where(id: ^id)
|> preload(public_links: :tag, awards: :badge)
|> Repo.one()
cond do
is_nil(profile) or profile.deleted_at ->
is_nil(user) or user.deleted_at ->
conn
|> put_status(:not_found)
|> text("")
true ->
json(conn, %{user: UserJson.as_json(conn, profile)})
render(conn, "show.json", user: user)
end
end
end

View file

@ -1,7 +1,6 @@
defmodule PhilomenaWeb.Api.Json.Search.CommentController do
use PhilomenaWeb, :controller
alias PhilomenaWeb.CommentJson
alias Philomena.Elasticsearch
alias Philomena.Comments.Comment
alias Philomena.Comments.Query
@ -34,7 +33,9 @@ defmodule PhilomenaWeb.Api.Json.Search.CommentController do
preload(Comment, [:image, :user])
)
json(conn, %{comments: Enum.map(comments, &CommentJson.as_json/1)})
conn
|> put_view(PhilomenaWeb.Api.Json.CommentView)
|> render("index.json", comments: comments, total: comments.total_entries)
{:error, msg} ->
conn

View file

@ -1,7 +1,6 @@
defmodule PhilomenaWeb.Api.Json.Search.GalleryController do
use PhilomenaWeb, :controller
alias PhilomenaWeb.GalleryJson
alias Philomena.Elasticsearch
alias Philomena.Galleries.Gallery
alias Philomena.Galleries.Query
@ -21,7 +20,9 @@ defmodule PhilomenaWeb.Api.Json.Search.GalleryController do
preload(Gallery, [:creator])
)
json(conn, %{galleries: Enum.map(galleries, &GalleryJson.as_json/1)})
conn
|> put_view(PhilomenaWeb.Api.Json.GalleryView)
|> render("index.json", galleries: galleries, total: galleries.total_entries)
{:error, msg} ->
conn

View file

@ -1,7 +1,6 @@
defmodule PhilomenaWeb.Api.Json.Search.PostController do
use PhilomenaWeb, :controller
alias PhilomenaWeb.PostJson
alias Philomena.Elasticsearch
alias Philomena.Posts.Post
alias Philomena.Posts.Query
@ -31,7 +30,9 @@ defmodule PhilomenaWeb.Api.Json.Search.PostController do
preload(Post, [:user, :topic])
)
json(conn, %{posts: Enum.map(posts, &PostJson.as_json/1)})
conn
|> put_view(PhilomenaWeb.Api.Json.Forum.Topic.PostView)
|> render("index.json", posts: posts, total: posts.total_entries)
{:error, msg} ->
conn

View file

@ -1,7 +1,6 @@
defmodule PhilomenaWeb.Api.Json.Search.TagController do
use PhilomenaWeb, :controller
alias PhilomenaWeb.TagJson
alias Philomena.Elasticsearch
alias Philomena.Tags.Tag
alias Philomena.Tags.Query
@ -18,7 +17,9 @@ defmodule PhilomenaWeb.Api.Json.Search.TagController do
preload(Tag, [:aliased_tag, :aliases, :implied_tags, :implied_by_tags, :dnp_entries])
)
json(conn, %{tags: Enum.map(tags, &TagJson.as_json/1)})
conn
|> put_view(PhilomenaWeb.Api.Json.TagView)
|> render("index.json", tags: tags, total: tags.total_entries)
{:error, msg} ->
conn

View file

@ -1,7 +1,6 @@
defmodule PhilomenaWeb.Api.Json.TagController do
use PhilomenaWeb, :controller
alias PhilomenaWeb.TagJson
alias Philomena.Tags.Tag
alias Philomena.Repo
import Ecto.Query
@ -22,7 +21,7 @@ defmodule PhilomenaWeb.Api.Json.TagController do
|> text("")
_ ->
json(conn, %{tag: TagJson.as_json(tag)})
render(conn, "show.json", tag: tag)
end
end
end

View file

@ -1,17 +0,0 @@
defmodule PhilomenaWeb.FilterJson do
def as_json(filter) do
%{
id: filter.id,
name: filter.name,
description: filter.description,
public: filter.public,
system: filter.system,
user_count: filter.user_count,
user_id: filter.user_id,
hidden_tag_ids: filter.hidden_tag_ids,
spoilered_tag_ids: filter.spoilered_tag_ids,
hidden_complex: filter.hidden_complex_str,
spoilered_complex: filter.spoilered_complex_str
}
end
end

View file

@ -1,21 +0,0 @@
defmodule PhilomenaWeb.ForumJson do
def as_json(%{access_level: "normal"} = forum) do
%{
name: forum.name,
short_name: forum.short_name,
description: forum.description,
topic_count: forum.topic_count,
post_count: forum.post_count
}
end
def as_json(_forum) do
%{
name: nil,
short_name: nil,
description: nil,
topic_count: nil,
post_count: nil
}
end
end

View file

@ -1,13 +0,0 @@
defmodule PhilomenaWeb.GalleryJson do
def as_json(gallery) do
%{
id: gallery.id,
title: gallery.title,
thumbnail_id: gallery.thumbnail_id,
spoiler_warning: gallery.spoiler_warning,
description: gallery.description,
user: gallery.creator.name,
user_id: gallery.creator_id
}
end
end

View file

@ -1,5 +1,7 @@
defmodule PhilomenaWeb.AwardsJson do
def as_json(_conn, award) do
defmodule PhilomenaWeb.Api.Json.AwardView do
use PhilomenaWeb, :view
def render("award.json", %{award: award}) do
%{
image_url: badge_url_root() <> "/" <> award.badge.image,
title: award.badge.title,

View file

@ -1,11 +1,23 @@
defmodule PhilomenaWeb.CommentJson do
defmodule PhilomenaWeb.Api.Json.CommentView do
use PhilomenaWeb, :view
alias PhilomenaWeb.UserAttributionView
def as_json(%{destroyed_content: true}) do
def render("index.json", %{comments: comments, total: total} = assigns) do
%{
comments: render_many(comments, PhilomenaWeb.Api.Json.CommentView, "comment.json", assigns),
total: total
}
end
def render("show.json", %{comment: comment} = assigns) do
%{comment: render_one(comment, PhilomenaWeb.Api.Json.CommentView, "comment.json", assigns)}
end
def render("comment.json", %{comment: %{destroyed_content: true}}) do
nil
end
def as_json(%{image: %{hidden_from_users: true}} = comment) do
def render("comment.json", %{comment: %{image: %{hidden_from_users: true}} = comment}) do
%{
id: comment.id,
image_id: comment.image_id,
@ -15,7 +27,7 @@ defmodule PhilomenaWeb.CommentJson do
}
end
def as_json(%{hidden_from_users: true} = comment) do
def render("comment.json", %{comment: %{hidden_from_users: true} = comment}) do
%{
id: comment.id,
image_id: comment.image_id,
@ -29,7 +41,7 @@ defmodule PhilomenaWeb.CommentJson do
}
end
def as_json(comment) do
def render("comment.json", %{comment: comment}) do
%{
id: comment.id,
image_id: comment.image_id,

View file

@ -0,0 +1,30 @@
defmodule PhilomenaWeb.Api.Json.FilterView do
use PhilomenaWeb, :view
def render("index.json", %{filters: filters, total: total} = assigns) do
%{
filters: render_many(filters, PhilomenaWeb.Api.Json.FilterView, "filter.json", assigns),
total: total
}
end
def render("show.json", %{filter: filter} = assigns) do
%{filter: render_one(filter, PhilomenaWeb.Api.Json.FilterView, "filter.json", assigns)}
end
def render("filter.json", %{filter: filter}) do
%{
id: filter.id,
name: filter.name,
description: filter.description,
public: filter.public,
system: filter.system,
user_count: filter.user_count,
user_id: filter.user_id,
hidden_tag_ids: filter.hidden_tag_ids,
spoilered_tag_ids: filter.spoilered_tag_ids,
hidden_complex: filter.hidden_complex_str,
spoilered_complex: filter.spoilered_complex_str
}
end
end

View file

@ -1,7 +1,19 @@
defmodule PhilomenaWeb.PostJson do
defmodule PhilomenaWeb.Api.Json.Forum.Topic.PostView do
use PhilomenaWeb, :view
alias PhilomenaWeb.UserAttributionView
def as_json(%{topic: %{hidden_from_users: true}} = post) do
def render("index.json", %{posts: posts, total: total} = assigns) do
%{
posts: render_many(posts, PhilomenaWeb.Api.Json.Forum.Topic.PostView, "post.json", assigns),
total: total
}
end
def render("show.json", %{post: post} = assigns) do
%{post: render_one(post, PhilomenaWeb.Api.Json.Forum.Topic.PostView, "post.json", assigns)}
end
def render("post.json", %{post: %{topic: %{hidden_from_users: true}} = post}) do
%{
id: post.id,
user_id: nil,
@ -10,7 +22,7 @@ defmodule PhilomenaWeb.PostJson do
}
end
def as_json(%{hidden_from_users: true} = post) do
def render("post.json", %{post: %{hidden_from_users: true} = post}) do
%{
id: post.id,
user_id: if(not post.anonymous, do: post.user_id),
@ -23,7 +35,7 @@ defmodule PhilomenaWeb.PostJson do
}
end
def as_json(post) do
def render("post.json", %{post: post}) do
%{
id: post.id,
user_id: if(not post.anonymous, do: post.user_id),

View file

@ -1,7 +1,19 @@
defmodule PhilomenaWeb.TopicJson do
defmodule PhilomenaWeb.Api.Json.Forum.TopicView do
use PhilomenaWeb, :view
alias PhilomenaWeb.UserAttributionView
def as_json(%{hidden_from_users: true}) do
def render("index.json", %{topics: topics, total: total} = assigns) do
%{
topics: render_many(topics, PhilomenaWeb.Api.Json.Forum.TopicView, "topic.json", assigns),
total: total
}
end
def render("show.json", %{topic: topic} = assigns) do
%{topic: render_one(topic, PhilomenaWeb.Api.Json.Forum.TopicView, "topic.json", assigns)}
end
def render("topic.json", %{topic: %{hidden_from_users: true}}) do
%{
slug: nil,
title: nil,
@ -15,7 +27,7 @@ defmodule PhilomenaWeb.TopicJson do
}
end
def as_json(topic) do
def render("topic.json", %{topic: topic}) do
%{
slug: topic.slug,
title: topic.title,

View file

@ -0,0 +1,34 @@
defmodule PhilomenaWeb.Api.Json.ForumView do
use PhilomenaWeb, :view
def render("index.json", %{forums: forums, total: total} = assigns) do
%{
forums: render_many(forums, PhilomenaWeb.Api.Json.ForumView, "forum.json", assigns),
total: total
}
end
def render("show.json", %{forum: forum} = assigns) do
%{forum: render_one(forum, PhilomenaWeb.Api.Json.ForumView, "forum.json", assigns)}
end
def render("forum.json", %{forum: %{access_level: "normal"} = forum}) do
%{
name: forum.name,
short_name: forum.short_name,
description: forum.description,
topic_count: forum.topic_count,
post_count: forum.post_count
}
end
def render("forum.json", _assigns) do
%{
name: nil,
short_name: nil,
description: nil,
topic_count: nil,
post_count: nil
}
end
end

View file

@ -0,0 +1,26 @@
defmodule PhilomenaWeb.Api.Json.GalleryView do
use PhilomenaWeb, :view
def render("index.json", %{galleries: galleries, total: total} = assigns) do
%{
galleries: render_many(galleries, PhilomenaWeb.Api.Json.GalleryView, "gallery.json", assigns),
total: total
}
end
def render("show.json", %{gallery: gallery} = assigns) do
%{gallery: render_one(gallery, PhilomenaWeb.Api.Json.GalleryView, "gallery.json", assigns)}
end
def render("gallery.json", %{gallery: gallery}) do
%{
id: gallery.id,
title: gallery.title,
thumbnail_id: gallery.thumbnail_id,
spoiler_warning: gallery.spoiler_warning,
description: gallery.description,
user: gallery.creator.name,
user_id: gallery.creator_id
}
end
end

View file

@ -1,8 +1,11 @@
defmodule PhilomenaWeb.UserJson do
alias PhilomenaWeb.LinksJson
alias PhilomenaWeb.AwardsJson
defmodule PhilomenaWeb.Api.Json.ProfileView do
use PhilomenaWeb, :view
def as_json(conn, user) do
def render("show.json", %{user: user} = assigns) do
%{user: render_one(user, PhilomenaWeb.Api.Json.ProfileView, "profile.json", assigns)}
end
def render("profile.json", %{user: user} = assigns) do
%{
id: user.id,
name: user.name,
@ -15,8 +18,8 @@ defmodule PhilomenaWeb.UserJson do
uploads_count: user.uploads_count,
posts_count: user.forum_posts_count,
topics_count: user.topic_count,
links: Enum.map(user.public_links, &LinksJson.as_json(conn, &1)),
awards: Enum.map(user.awards, &AwardsJson.as_json(conn, &1))
links: render_many(user.public_links, PhilomenaWeb.Api.Json.UserLinkView, "user_link.json", assigns),
awards: render_many(user.awards, PhilomenaWeb.Api.Json.AwardView, "award.json", assigns)
}
end

View file

@ -1,5 +1,18 @@
defmodule PhilomenaWeb.TagJson do
def as_json(tag) do
defmodule PhilomenaWeb.Api.Json.TagView do
use PhilomenaWeb, :view
def render("index.json", %{tags: tags, total: total} = assigns) do
%{
tags: render_many(tags, PhilomenaWeb.Api.Json.TagView, "tag.json", assigns),
total: total
}
end
def render("show.json", %{tag: tag} = assigns) do
%{tag: render_one(tag, PhilomenaWeb.Api.Json.TagView, "tag.json", assigns)}
end
def render("tag.json", %{tag: tag}) do
%{
id: tag.id,
name: tag.name,

View file

@ -1,7 +1,11 @@
defmodule PhilomenaWeb.LinksJson do
def as_json(_conn, %{public: false}), do: nil
defmodule PhilomenaWeb.Api.Json.UserLinkView do
use PhilomenaWeb, :view
def as_json(_conn, link) do
def render("user_link.json", %{user_link: %{public: false}}) do
nil
end
def render("user_link.json", %{user_link: link}) do
%{
user_id: link.user_id,
created_at: link.created_at,