Skip to content
This repository was archived by the owner on Nov 8, 2022. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions lib/groupher_server/cms/cms.ex
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ defmodule GroupherServer.CMS do
AbuseReport,
ArticleCURD,
BlogCURD,
WorksCURD,
ArticleCommunity,
ArticleEmotion,
CitedArtiment,
Expand Down Expand Up @@ -108,6 +109,9 @@ defmodule GroupherServer.CMS do
defdelegate update_blog_rss(attrs), to: BlogCURD
defdelegate blog_rss_info(rss), to: BlogCURD

defdelegate create_works(attrs, user), to: WorksCURD
defdelegate update_works(attrs, user), to: WorksCURD

defdelegate paged_citing_contents(type, id, filter), to: CitedArtiment

defdelegate upvote_article(thread, article_id, user), to: ArticleUpvote
Expand Down
7 changes: 6 additions & 1 deletion lib/groupher_server/cms/delegates/article_curd.ex
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ defmodule GroupherServer.CMS.Delegate.ArticleCURD do
module_to_atom: 1,
get_config: 2,
ensure: 2,
module_to_upcase: 1
module_to_upcase: 1,
atom_values_to_upcase: 1
]

import GroupherServer.CMS.Delegate.Helper, only: [mark_viewer_emotion_states: 2, thread_of: 1]
Expand Down Expand Up @@ -189,6 +190,8 @@ defmodule GroupherServer.CMS.Delegate.ArticleCURD do
{:ok, %Post{}}
"""
def create_article(%Community{id: cid}, thread, attrs, %User{id: uid}) do
attrs = atom_values_to_upcase(attrs)

with {:ok, author} <- ensure_author_exists(%User{id: uid}),
{:ok, info} <- match(thread),
{:ok, community} <- ORM.find(Community, cid) do
Expand Down Expand Up @@ -258,6 +261,8 @@ defmodule GroupherServer.CMS.Delegate.ArticleCURD do
do: raise_error(:archived, "article is archived, can not be edit or delete")

def update_article(article, attrs) do
attrs = atom_values_to_upcase(attrs)

Multi.new()
|> Multi.run(:update_article, fn _, _ ->
do_update_article(article, attrs)
Expand Down
25 changes: 1 addition & 24 deletions lib/groupher_server/cms/delegates/blog_curd.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ defmodule GroupherServer.CMS.Delegate.BlogCURD do
CURD operation on post/job ...
"""
import Ecto.Query, warn: false
import Helper.Utils, only: [strip_struct: 1, done: 1]
import Helper.Utils, only: [strip_struct: 1]
import Helper.ErrorCode

import GroupherServer.CMS.Delegate.ArticleCURD, only: [create_article: 4]
Expand Down Expand Up @@ -38,17 +38,7 @@ defmodule GroupherServer.CMS.Delegate.BlogCURD do
## 1.2 如不存在,则创建一条 RSS
with {:ok, feed} <- blog_rss_info(attrs.rss) do
do_create_blog(community, attrs, user, feed)

# IO.inspect(feed, label: "create blog")
# 通过 feed 有没有 id 来 insert / update
# 通过 blog_title, 组合 attrs 传给 create_article
end

# 2. 创建 blog
## 2.1 blog +字段 rss, author
## 2.2 title, digest, xxx

# 前台获取作者信息的时候从 rss 表读取
end

# rss 记录存在, 直接创建 blog
Expand Down Expand Up @@ -102,19 +92,6 @@ defmodule GroupherServer.CMS.Delegate.BlogCURD do
end
end

# create done
# defp result({:ok, %{set_active_at_timestamp: result}}) do
# {:ok, result}
# end

# defp result({:ok, %{update_article_meta: result}}), do: {:ok, result}

# defp result({:error, :create_article, _result, _steps}) do
# {:error, [message: "create article", code: ecode(:create_fails)]}
# end

# defp result({:error, _, result, _steps}), do: {:error, result}

@doc """
get and cache feed by rss address as key
"""
Expand Down
160 changes: 160 additions & 0 deletions lib/groupher_server/cms/delegates/works_curd.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
defmodule GroupherServer.CMS.Delegate.WorksCURD do
@moduledoc """
CURD operation on post/job ...
"""
import Ecto.Query, warn: false
import Helper.Utils, only: [done: 1, atom_values_to_upcase: 1]
import Helper.ErrorCode

import GroupherServer.CMS.Delegate.ArticleCURD, only: [create_article: 4, update_article: 2]

alias GroupherServer.{Accounts, CMS, Repo}
alias CMS.Model.{Community, Techstack, City, Works}
alias Accounts.Model.User

alias Helper.ORM
alias Ecto.Multi

# works can only be published on home community
def create_works(attrs, %User{} = user) do
attrs = attrs |> atom_values_to_upcase

with {:ok, home_community} <- ORM.find_by(Community, %{raw: "home"}) do
Multi.new()
|> Multi.run(:create_works, fn _, _ ->
create_article(home_community, :works, attrs, user)
end)
|> Multi.run(:update_works_fields, fn _, %{create_works: works} ->
update_works_fields(works, attrs)
end)
|> Repo.transaction()
|> result()
end
end

def update_works(%Works{} = works, attrs) do
attrs = attrs |> atom_values_to_upcase

Multi.new()
|> Multi.run(:update_works_fields, fn _, _ ->
update_works_fields(works, attrs)
end)
|> Multi.run(:update_works, fn _, %{update_works_fields: works} ->
update_article(works, attrs)
end)
|> Repo.transaction()
|> result()
end

# update works spec fields
defp update_works_fields(%Works{} = works, attrs) do
techstacks = Map.get(attrs, :techstacks, [])
cities = Map.get(attrs, :cities, [])
social_info = Map.get(attrs, :social_info, [])
app_store = Map.get(attrs, :app_store, [])

with {:ok, techstacks} <- get_or_create_techstacks(techstacks),
{:ok, cities} <- get_or_create_cities(cities) do
works = Repo.preload(works, [:techstacks, :cities])

works
|> Ecto.Changeset.change()
|> Ecto.Changeset.put_assoc(:techstacks, works.techstacks ++ techstacks)
|> Ecto.Changeset.put_assoc(:cities, works.cities ++ cities)
|> Ecto.Changeset.put_embed(:social_info, social_info)
|> Ecto.Changeset.put_embed(:app_store, app_store)
|> Repo.update()
end
end

defp get_or_create_cities([]), do: {:ok, []}

defp get_or_create_cities(cities) do
cities
|> Enum.map(&String.downcase(&1))
|> Enum.reduce([], fn title, acc ->
with {:ok, city} <- get_city(title) do
acc ++ [city]
end
end)
|> done
end

defp get_city(title) do
case ORM.find_by(City, %{title: title}) do
{:error, _} -> create_city(title)
{:ok, city} -> {:ok, city}
end
end

defp create_city(title) do
attrs =
case ORM.find_by(Community, %{raw: title}) do
{:ok, community} ->
%{
title: community.title,
logo: community.logo,
desc: community.desc,
link: "/#{community.raw}"
}

{:error, _} ->
%{title: title}
end

ORM.create(City, attrs)
end

defp get_or_create_techstacks([]), do: {:ok, []}

defp get_or_create_techstacks(techstacks) do
techstacks
|> Enum.map(&String.downcase(&1))
|> Enum.reduce([], fn title, acc ->
with {:ok, techstack} <- get_techstack(title) do
acc ++ [techstack]
end
end)
|> done
end

defp get_techstack(title) do
case ORM.find_by(Techstack, %{title: title}) do
{:error, _} -> create_techstack(title)
{:ok, techstack} -> {:ok, techstack}
end
end

defp create_techstack(title) do
attrs =
case ORM.find_by(Community, %{raw: title}) do
{:ok, community} ->
%{
title: community.title,
logo: community.logo,
community_link: "/#{community.raw}",
desc: community.desc
}

{:error, _} ->
%{title: title}
end

ORM.create(Techstack, attrs)
end

defp result({:ok, %{create_works: result}}), do: {:ok, result}
defp result({:ok, %{update_works: result}}), do: {:ok, result}

defp result({:error, :create_works, _result, _steps}) do
{:error, [message: "create works", code: ecode(:create_fails)]}
end

defp result({:error, :update_works_fields, _result, _steps}) do
{:error, [message: "update works fields", code: ecode(:create_fails)]}
end

defp result({:error, :update_works, _result, _steps}) do
{:error, [message: "update works", code: ecode(:update_fails)]}
end
end
47 changes: 47 additions & 0 deletions lib/groupher_server/cms/models/city.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
defmodule GroupherServer.CMS.Model.City do
@moduledoc false
alias __MODULE__

use Ecto.Schema
use Accessible

import Ecto.Changeset

# alias GroupherServer.CMS

@timestamps_opts [type: :utc_datetime_usec]

@required_fields ~w(title)a
@optional_fields ~w(logo desc link)a

@type t :: %City{}
schema "cms_cities" do
## mailstone
field(:title, :string)
field(:logo, :string)
field(:desc, :string)
field(:link, :string)

timestamps()
end

@doc false
def changeset(%City{} = city, attrs) do
city
|> cast(attrs, @optional_fields ++ @required_fields)
|> validate_required(@required_fields)
|> generl_changeset
end

@doc false
def update_changeset(%City{} = city, attrs) do
city
|> cast(attrs, @optional_fields ++ @required_fields)
|> generl_changeset
end

defp generl_changeset(changeset) do
changeset
|> validate_length(:title, min: 1, max: 100)
end
end
23 changes: 23 additions & 0 deletions lib/groupher_server/cms/models/embeds/app_store.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
defmodule GroupherServer.CMS.Model.Embeds.AppStore do
@moduledoc """
general community meta
"""
use Ecto.Schema
use Accessible

import Ecto.Changeset

@required_fields ~w(platform)a
@optional_fields ~w(link)a

embedded_schema do
field(:platform, :string)
field(:link, :string)
end

def changeset(struct, attrs) do
struct
|> cast(attrs, @optional_fields ++ @required_fields)
|> validate_required(@required_fields)
end
end
23 changes: 23 additions & 0 deletions lib/groupher_server/cms/models/embeds/social_info.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
defmodule GroupherServer.CMS.Model.Embeds.SocialInfo do
@moduledoc """
general community meta
"""
use Ecto.Schema
use Accessible

import Ecto.Changeset

@required_fields ~w(platform)a
@optional_fields ~w(link)a

embedded_schema do
field(:platform, :string)
field(:link, :string)
end

def changeset(struct, attrs) do
struct
|> cast(attrs, @optional_fields ++ @required_fields)
|> validate_required(@required_fields)
end
end
Loading