Skip to content
This repository was archived by the owner on Nov 8, 2022. It is now read-only.

Commit 143d51b

Browse files
authored
refactor: extract article threads config (#353)
* refactor: wip * refactor: wip * refactor: wip * refactor: add some doc
1 parent 19e7df7 commit 143d51b

File tree

9 files changed

+133
-87
lines changed

9 files changed

+133
-87
lines changed

lib/groupher_server/cms/community.ex

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,14 @@ defmodule GroupherServer.CMS.Community do
1919
CommunityCheatsheet
2020
}
2121

22+
@article_threads [:post, :job, :repo]
2223
@max_pinned_article_count_per_thread 2
2324

2425
@required_fields ~w(title desc user_id logo raw)a
2526
# @required_fields ~w(title desc user_id)a
2627
@optional_fields ~w(label geo_info index aka)a
2728

29+
def article_threads, do: @article_threads
2830
def max_pinned_article_count_per_thread, do: @max_pinned_article_count_per_thread
2931

3032
schema "communities" do

lib/groupher_server/cms/delegates/abuse_report.ex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@ defmodule GroupherServer.CMS.Delegate.AbuseReport do
1313
alias GroupherServer.{Accounts, CMS, Repo}
1414

1515
alias Accounts.User
16-
alias CMS.{AbuseReport, ArticleComment, Embeds}
16+
alias CMS.{Community, AbuseReport, ArticleComment, Embeds}
1717

1818
alias Ecto.Multi
1919

2020
@report_threshold_for_fold ArticleComment.report_threshold_for_fold()
2121

22-
@article_threads [:post, :job, :repo]
22+
@article_threads Community.article_threads()
2323
@export_author_keys [:id, :login, :nickname, :avatar]
2424
@export_article_keys [:id, :title, :digest, :upvotes_count, :views]
2525
@export_report_keys [

lib/groupher_server/cms/delegates/article_comment.ex

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -96,19 +96,14 @@ defmodule GroupherServer.CMS.Delegate.ArticleComment do
9696
# make sure the article exsit
9797
# author is passed by middleware, it's exsit for sure
9898
{:ok, article} <- ORM.find(info.model, article_id, preload: [author: :user]) do
99-
IO.inspect(info, label: "bb")
100-
10199
Multi.new()
102100
|> Multi.run(:create_article_comment, fn _, _ ->
103-
IO.inspect("11")
104101
do_create_comment(content, info.foreign_key, article, user)
105102
end)
106103
|> Multi.run(:update_article_comments_count, fn _, %{create_article_comment: comment} ->
107-
IO.inspect("22")
108-
update_article_comments_count(comment, :inc) |> IO.inspect(label: "22 after")
104+
update_article_comments_count(comment, :inc)
109105
end)
110106
|> Multi.run(:add_participator, fn _, _ ->
111-
IO.inspect("33")
112107
add_participator_to_article(article, user)
113108
end)
114109
|> Repo.transaction()

lib/groupher_server/cms/delegates/article_curd.ex

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ defmodule GroupherServer.CMS.Delegate.ArticleCURD do
77
import GroupherServer.CMS.Helper.Matcher2
88
import GroupherServer.CMS.Helper.Matcher, only: [match_action: 2]
99

10-
import Helper.Utils, only: [done: 1, pick_by: 2, integerfy: 1, strip_struct: 1]
10+
import Helper.Utils,
11+
only: [done: 1, pick_by: 2, integerfy: 1, strip_struct: 1, module_to_thread: 1]
12+
1113
import GroupherServer.CMS.Delegate.Helper, only: [mark_viewer_emotion_states: 2]
1214
import Helper.ErrorCode
1315
import ShortMaps
@@ -301,19 +303,19 @@ defmodule GroupherServer.CMS.Delegate.ArticleCURD do
301303
defp domain_filter_query(queryable, _filter), do: queryable
302304

303305
defp add_pin_contents_ifneed(contents, querable, %{community: community} = filter) do
304-
with {:ok, _} <- should_add_pin?(filter),
305-
{:ok, info} <- match(querable),
306-
true <- 1 == Map.get(contents, :page_number) do
307-
{:ok, pinned_articles} =
308-
PinnedArticle
309-
|> join(:inner, [p], c in assoc(p, :community))
310-
# |> join(:inner, [p], article in assoc(p, ^filter.thread))
311-
|> join(:inner, [p], article in assoc(p, ^info.thread))
312-
|> where([p, c, article], c.raw == ^community)
313-
|> select([p, c, article], article)
314-
# 10 pined contents per community/thread, at most
315-
|> ORM.find_all(%{page: 1, size: 10})
306+
thread = module_to_thread(querable)
316307

308+
with {:ok, _} <- should_add_pin?(filter),
309+
true <- 1 == Map.get(contents, :page_number),
310+
{:ok, pinned_articles} <-
311+
PinnedArticle
312+
|> join(:inner, [p], c in assoc(p, :community))
313+
# |> join(:inner, [p], article in assoc(p, ^filter.thread))
314+
|> join(:inner, [p], article in assoc(p, ^thread))
315+
|> where([p, c, article], c.raw == ^community)
316+
|> select([p, c, article], article)
317+
# 10 pined contents per community/thread, at most
318+
|> ORM.find_all(%{page: 1, size: 10}) do
317319
concat_contents(pinned_articles, contents)
318320
else
319321
_error -> contents
Lines changed: 101 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,109 @@
1-
defmodule GroupherServer.CMS.Helper.Matcher2 do
1+
defmodule GroupherServer.CMS.Helper.Matcher2.Macros do
22
@moduledoc """
3-
this module defined the matches and handy guard ...
3+
generate match functions
44
"""
55

6-
import Ecto.Query, warn: false
6+
alias GroupherServer.CMS
7+
alias CMS.{ArticleComment, Community, Embeds}
78

8-
alias GroupherServer.{Accounts, CMS}
9+
@article_threads Community.article_threads()
910

10-
alias Accounts.User
11-
alias CMS.{ArticleComment, Post, Job, Repo}
11+
@doc """
12+
match basic threads
1213
13-
def match(:article_comment) do
14-
{:ok,
15-
%{
16-
model: ArticleComment,
17-
foreign_key: :article_comment_id,
18-
preload: :article_comment,
19-
default_meta: CMS.Embeds.ArticleCommentMeta.default_meta()
20-
}}
14+
{:ok, info} <- match(:post)
15+
info:
16+
%{
17+
model: Post,
18+
thread: :post,
19+
foreign_key: post_id,
20+
preload: :post
21+
default_meta: ...
22+
}
23+
"""
24+
defmacro thread_matches() do
25+
@article_threads
26+
|> Enum.map(fn thread ->
27+
quote do
28+
def match(unquote(thread)) do
29+
thread_module = unquote(thread) |> to_string |> Recase.to_pascal()
30+
31+
{:ok,
32+
%{
33+
model: Module.concat(CMS, thread_module),
34+
thread: unquote(thread),
35+
foreign_key: unquote(:"#{thread}_id"),
36+
preload: unquote(thread),
37+
default_meta: Embeds.ArticleMeta.default_meta()
38+
}}
39+
end
40+
end
41+
end)
2142
end
2243

23-
def match(:comment_article, %ArticleComment{post_id: post_id}) when not is_nil(post_id) do
24-
{:ok, %{model: Post, id: post_id, foreign_key: :post_id}}
25-
end
44+
@doc """
45+
match basic thread query
2646
27-
def match(:comment_article, %ArticleComment{job_id: job_id}) when not is_nil(job_id) do
28-
{:ok, %{model: Job, id: job_id, foreign_key: :job_id}}
47+
{:ok, info} <- match(:post, :query, id)
48+
info:
49+
%{dynamic([c], field(c, :post_id) == ^id)}
50+
"""
51+
defmacro thread_query_matches() do
52+
@article_threads
53+
|> Enum.map(fn thread ->
54+
quote do
55+
def match(unquote(thread), :query, id) do
56+
{:ok, dynamic([c], field(c, unquote(:"#{thread}_id")) == ^id)}
57+
end
58+
end
59+
end)
2960
end
3061

31-
def match(:comment_article, %ArticleComment{repo_id: repo_id}) when not is_nil(repo_id) do
32-
{:ok, %{model: Repo, id: repo_id, foreign_key: :repo_id}}
33-
end
62+
@doc """
63+
mapping basic article_comment -> thread
3464
35-
def match(:comment_article, %ArticleComment{}) do
36-
{:error, "match error, not supported"}
65+
{:ok, info} <- match(:comment_article, %ArticleComment{post_id: id} = comment)
66+
info:
67+
%{
68+
id: id,
69+
model: CMS.Post,
70+
foreign_key: :post_id,
71+
}
72+
"""
73+
defmacro comment_article_matches() do
74+
@article_threads
75+
|> Enum.map(fn thread ->
76+
# def match(:comment_article, %ArticleComment{post_id: id})
77+
quote do
78+
# see https://elixirforum.com/t/generate-map-pattern-matching-functions/21928/2
79+
def match(:comment_article, %ArticleComment{unquote(:"#{thread}_id") => id})
80+
when not is_nil(id) do
81+
thread_module = unquote(thread) |> to_string |> Recase.to_pascal()
82+
83+
{:ok,
84+
%{
85+
id: id,
86+
model: Module.concat(CMS, thread_module),
87+
foreign_key: unquote(:"#{thread}_id")
88+
}}
89+
end
90+
end
91+
end)
3792
end
93+
end
94+
95+
defmodule GroupherServer.CMS.Helper.Matcher2 do
96+
@moduledoc """
97+
this module defined the matches and handy guard ...
98+
"""
99+
100+
import Ecto.Query, warn: false
101+
import GroupherServer.CMS.Helper.Matcher2.Macros
102+
103+
alias GroupherServer.{Accounts, CMS}
104+
105+
alias Accounts.User
106+
alias CMS.{ArticleComment}
38107

39108
def match(:account) do
40109
{:ok,
@@ -46,49 +115,17 @@ defmodule GroupherServer.CMS.Helper.Matcher2 do
46115
}}
47116
end
48117

49-
# used for paged pin articles
50-
def match(Post) do
51-
{:ok, %{thread: :post}}
52-
end
53-
54-
def match(:post) do
55-
{:ok,
56-
%{
57-
model: Post,
58-
foreign_key: :post_id,
59-
preload: :post,
60-
default_meta: CMS.Embeds.ArticleMeta.default_meta()
61-
}}
62-
end
63-
64-
def match(Job) do
65-
{:ok, %{thread: :job}}
66-
end
67-
68-
def match(:job) do
69-
{:ok,
70-
%{
71-
model: Job,
72-
foreign_key: :job_id,
73-
preload: :job,
74-
default_meta: CMS.Embeds.ArticleMeta.default_meta()
75-
}}
76-
end
77-
78-
def match(Repo) do
79-
{:ok, %{thread: :repo}}
80-
end
81-
82-
def match(:repo) do
118+
def match(:article_comment) do
83119
{:ok,
84120
%{
85-
model: Repo,
86-
foreign_key: :repo_id,
87-
preload: :repo,
88-
default_meta: CMS.Embeds.ArticleMeta.default_meta()
121+
model: ArticleComment,
122+
foreign_key: :article_comment_id,
123+
preload: :article_comment,
124+
default_meta: CMS.Embeds.ArticleCommentMeta.default_meta()
89125
}}
90126
end
91127

92-
def match(:post, :query, id), do: {:ok, dynamic([c], c.post_id == ^id)}
93-
def match(:job, :query, id), do: {:ok, dynamic([c], c.job_id == ^id)}
128+
thread_matches()
129+
thread_query_matches()
130+
comment_article_matches()
94131
end

lib/helper/utils/utils.ex

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,16 @@ defmodule Helper.Utils do
175175

176176
def strip_struct(map) when is_map(map), do: map
177177

178+
@doc "turn GroupherServer.CMS.Post -> :post"
179+
def module_to_thread(module) do
180+
module
181+
|> to_string
182+
|> String.split(".")
183+
|> List.last()
184+
|> String.downcase()
185+
|> String.to_atom()
186+
end
187+
178188
@doc "html uniq id generator for editorjs"
179189
@spec uid(:html, map) :: String.t()
180190
def uid(:html, %{"id" => id}) when g_none_empty_str(id), do: id

priv/mock/tag_patch_seeds.exs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,6 @@ Enum.each(patch_communities, fn raw ->
3232
case community.raw not in ["cps-support"] do
3333
true ->
3434
# create_tags(community, :repo)
35-
IO.inspect(community.raw, label: "patching community")
36-
3735
Enum.each(patch_tags, fn attr ->
3836
{:ok, _} = CMS.create_tag(community, :repo, attr, bot)
3937
end)

test/groupher_server/cms/abuse_reports/post_report_test.exs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ defmodule GroupherServer.Test.CMS.AbuseReports.PostReport do
7979
assert user.id not in post.meta.reported_user_ids
8080
end
8181

82+
@tag :wip2
8283
test "can undo a report with other user report it too",
8384
~m(community user user2 post_attrs)a do
8485
{:ok, post} = CMS.create_content(community, :post, post_attrs, user)

test/groupher_server_web/query/cms/flags/posts_flags_test.exs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ defmodule GroupherServer.Test.Query.Flags.PostsFlags do
8989
assert results["entries"] |> Enum.any?(&(&1["id"] !== random_id))
9090
end
9191

92+
@tag :wip2
9293
test "if have trashed posts, the trashed posts should not appears in result",
9394
~m(guest_conn community)a do
9495
variables = %{filter: %{community: community.raw}}

0 commit comments

Comments
 (0)