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

Commit f173b09

Browse files
committed
refactor(cited-article): wip
1 parent 742969d commit f173b09

File tree

5 files changed

+79
-62
lines changed

5 files changed

+79
-62
lines changed

lib/groupher_server/cms/delegates/block_tasks.ex

Lines changed: 63 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -35,41 +35,41 @@ defmodule GroupherServer.CMS.Delegate.BlockTasks do
3535
def handle(%{body: body} = article) do
3636
with {:ok, body_map} <- Jason.decode(body) do
3737
run_tasks(:cite, article, body_map["blocks"])
38+
# run_tasks(:mention, article, body_map["blocks"])
3839
end
3940
end
4041

4142
defp run_tasks(:cite, article, blocks) do
4243
article = article |> Repo.preload(author: :user)
4344

44-
# NOTE:
45-
cited_contents =
46-
blocks
47-
|> Enum.reduce([], &(&2 ++ get_cited_contents_per_block(article, &1)))
48-
|> merge_same_cited_article_block
45+
blocks
46+
|> Enum.reduce([], &(&2 ++ get_cited_contents_per_block(article, &1)))
47+
|> merge_same_cited_article_block
48+
|> update_cited_info
49+
end
4950

50-
IO.inspect(cited_contents, label: "fuck all")
51+
defp update_cited_info(cited_contents) do
52+
# batch update CitedContent List
53+
cited_contents_fields = [:cited_by_id, :cited_by_type, :block_linker, :user_id]
54+
clean_cited_contents = Enum.map(cited_contents, &Map.take(&1, cited_contents_fields))
55+
IO.inspect(clean_cited_contents, label: "clean_cited_contents")
56+
Repo.insert_all(CitedContent, clean_cited_contents)
5157

52-
CitedContent |> Repo.insert_all(cited_contents)
58+
# update citting count meta
5359
update_citing_count(cited_contents)
54-
55-
# CitedContent |> ORM.create
5660
end
5761

5862
defp update_citing_count(cited_contents) do
5963
Enum.each(cited_contents, fn content ->
6064
count_query = from(c in CitedContent, where: c.cited_by_id == ^content.cited_by_id)
6165
count = Repo.aggregate(count_query, :count)
6266

63-
IO.inspect(count, label: "the count")
67+
cited_article = content.cited_article
68+
meta = Map.merge(cited_article.meta, %{citing_count: count})
69+
cited_article |> ORM.update_meta(meta)
6470
end)
65-
66-
# count = Repo.aggregate(count_query, :count)
67-
# IO.inspect cited_contents, label: "update_citing_count"
6871
end
6972

70-
# count_query = from(s in CommunitySubscriber, where: s.user_id == ^user.id)
71-
# count = Repo.aggregate(count_query, :count)
72-
7373
@doc """
7474
e.g:
7575
[
@@ -115,14 +115,35 @@ defmodule GroupherServer.CMS.Delegate.BlockTasks do
115115
"""
116116
defp merge_same_cited_article_block(cited_contents) do
117117
cited_contents
118-
|> Enum.chunk_by(& &1.cited_by_id)
119-
|> Enum.map(fn content_by_group ->
120-
Enum.reduce(content_by_group, fn content, acc ->
121-
Map.merge(content, %{block_linker: content.block_linker ++ acc.block_linker})
122-
end)
118+
|> Enum.reduce([], fn content, acc ->
119+
case Enum.find_index(acc, &(&1.cited_by_id == content.cited_by_id)) do
120+
nil ->
121+
acc ++ [content]
122+
123+
index ->
124+
List.update_at(
125+
acc,
126+
index,
127+
&Map.merge(&1, %{block_linker: &1.block_linker ++ content.block_linker})
128+
)
129+
end
123130
end)
124131
end
125132

133+
@doc """
134+
return fmt like:
135+
[
136+
%{
137+
block_linker: ["block-ZgKJs"],
138+
cited_by_id: 190057,
139+
cited_by_type: "POST",
140+
cited_article: #loaded,
141+
post_id: 190059,
142+
user_id: 1413053
143+
}
144+
...
145+
]
146+
"""
126147
defp get_cited_contents_per_block(article, %{
127148
"id" => block_id,
128149
"data" => %{"text" => text}
@@ -147,30 +168,43 @@ defmodule GroupherServer.CMS.Delegate.BlockTasks do
147168
%{
148169
cited_by_id: cited_article.id,
149170
cited_by_type: cited_article.meta.thread,
150-
# cited_article: cited_article,
171+
cited_article: cited_article,
151172
block_linker: [block_id],
152173
user_id: article.author.user.id
153174
}
154175
|> Map.put(info.foreign_key, article.id)
155176
end
156177

157178
defp parse_cited_article({"a", attrs, _}) do
158-
with {:ok, link} <- get_link(Enum.find(attrs, fn {a, v} -> a == "href" end)),
159-
true <- is_valid_article_link?(link) do
160-
get_cited_article(link)
179+
with {:ok, link} <- parse_link(attrs),
180+
true <- is_site_article_link?(link) do
181+
load_cited_article_from_url(link)
161182
end
162183
end
163184

164-
defp get_link({"href", link}), do: {:ok, link}
165-
defp get_link(_), do: {:error, "invalid fmt"}
185+
@doc """
186+
parse link from Floki parse result
187+
188+
e.g:
189+
[{"href", "https://coderplanets.com/post/190220", "bla", "bla"}] ->
190+
{:ok, "https://coderplanets.com/post/190220"}
191+
"""
192+
defp parse_link(attrs) do
193+
with {"href", link} <- Enum.find(attrs, fn {a, v} -> a == "href" end) do
194+
{:ok, link}
195+
else
196+
_ -> {:error, "invalid fmt"}
197+
end
198+
end
166199

167-
defp is_valid_article_link?(url) do
200+
# 检测是否是站内文章的链接
201+
defp is_site_article_link?(url) do
168202
Enum.any?(@valid_article_prefix, &String.starts_with?(url, &1))
169203
end
170204

171205
# get cited article from url
172206
# e.g: https://coderplanets.com/post/189993 -> ORM.find(Post, 189993)
173-
defp get_cited_article(url) do
207+
defp load_cited_article_from_url(url) do
174208
%{path: path} = URI.parse(url)
175209
path_list = path |> String.split("/")
176210
thread = path_list |> Enum.at(1) |> String.downcase() |> String.to_atom()
@@ -180,19 +214,4 @@ defmodule GroupherServer.CMS.Delegate.BlockTasks do
180214
ORM.find(info.model, article_id)
181215
end
182216
end
183-
184-
defp run_tasks(:mention) do
185-
#
186-
end
187-
188-
# 还是单抽一个模块吧
189-
defp run_tasks(:danger_words) do
190-
# title & body
191-
end
192-
193-
defp parse_blocks(%{body: body} = article) do
194-
with {:ok, body_map} <- Jason.decode(body) do
195-
#
196-
end
197-
end
198217
end

lib/groupher_server/cms/helper/macros.ex

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,6 @@ defmodule GroupherServer.CMS.Helper.Macros do
207207
article_comment_fields()
208208

209209
field(:active_at, :utc_datetime_usec)
210-
field(:citing_count, :integer, default: 0)
211210
# TODO:
212211
# related_articles
213212
timestamps()

lib/groupher_server/cms/models/embeds/article_meta.ex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ defmodule GroupherServer.CMS.Model.Embeds.ArticleMeta do
4040
field(:can_undo_sink, :boolean, default: false)
4141
# if undo_sink, can recover last active_at from here
4242
field(:last_active_at, :utc_datetime_usec)
43+
field(:citing_count, :integer, default: 0)
4344
end
4445

4546
def changeset(struct, params) do

priv/repo/migrations/20210611160430_add_citing_count_to_articles.exs

Lines changed: 0 additions & 10 deletions
This file was deleted.

test/groupher_server/cms/cite_content_test.exs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,34 +20,42 @@ defmodule GroupherServer.Test.CMS.CiteContent do
2020
{:ok, post} = db_insert(:post)
2121
{:ok, post2} = db_insert(:post)
2222
{:ok, post3} = db_insert(:post)
23+
{:ok, post4} = db_insert(:post)
24+
{:ok, post5} = db_insert(:post)
2325

2426
{:ok, community} = db_insert(:community)
2527

2628
post_attrs = mock_attrs(:post, %{community_id: community.id})
2729

28-
{:ok, ~m(user user2 community post post2 post3 post_attrs)a}
30+
{:ok, ~m(user user2 community post post2 post3 post4 post5 post_attrs)a}
2931
end
3032

3133
describe "[cite basic]" do
3234
@tag :wip
33-
test "basic", ~m(user community post2 post3 post_attrs)a do
34-
IO.inspect(post2.id, label: "post2.id")
35-
IO.inspect(post3.id, label: "post3.id")
36-
35+
test "basic", ~m(user community post2 post3 post4 post5 post_attrs)a do
3736
body =
3837
mock_rich_text(
3938
~s(the <a href=#{@site_host}/post/#{post2.id} /> and <a href=#{@site_host}/post/#{
4039
post2.id
4140
}>same la</a> is awesome, the <a href=#{@site_host}/post/#{post3.id}></a> is awesome too.),
4241
# second paragraph
43-
~s(the paragraph 2 <a href=#{@site_host}/post/#{post2.id}> again</a> )
42+
~s(the paragraph 2 <a href=#{@site_host}/post/#{post2.id} class=#{post2.title}> again</a>, the paragraph 2 <a href=#{
43+
@site_host
44+
}/post/#{post4.id}> again</a>, the paragraph 2 <a href=#{@site_host}/post/#{post5.id}> again</a>)
4445
)
4546

4647
post_attrs = post_attrs |> Map.merge(%{body: body})
4748

4849
{:ok, post} = CMS.create_article(community, :post, post_attrs, user)
49-
5050
BlockTasks.handle(post)
51+
52+
{:ok, post2} = ORM.find(Post, post2.id)
53+
{:ok, post3} = ORM.find(Post, post3.id)
54+
{:ok, post4} = ORM.find(Post, post4.id)
55+
56+
assert post2.meta.citing_count == 1
57+
assert post3.meta.citing_count == 1
58+
assert post4.meta.citing_count == 1
5159
end
5260
end
5361
end

0 commit comments

Comments
 (0)