|
| 1 | +defmodule GroupherServer.CMS.Delegate.BlogCURD do |
| 2 | + @moduledoc """ |
| 3 | + CURD operation on post/job ... |
| 4 | + """ |
| 5 | + import Ecto.Query, warn: false |
| 6 | + import Helper.Utils, only: [strip_struct: 1, done: 1] |
| 7 | + import Helper.ErrorCode |
| 8 | + |
| 9 | + import GroupherServer.CMS.Delegate.ArticleCURD, only: [create_article: 4] |
| 10 | + # import Helper.Utils, only: [done: 1] |
| 11 | + |
| 12 | + # import Helper.ErrorCode |
| 13 | + # import ShortMaps |
| 14 | + |
| 15 | + # alias Helper.{ORM} |
| 16 | + alias GroupherServer.{Accounts, CMS, Repo} |
| 17 | + alias CMS.Model.{BlogRSS, Community} |
| 18 | + alias Accounts.Model.User |
| 19 | + |
| 20 | + alias Helper.{ORM, Cache, RSS} |
| 21 | + |
| 22 | + @cache_pool :blog_rss |
| 23 | + |
| 24 | + # alias Ecto.Multi |
| 25 | + def blog_rss_info(rss) when is_binary(rss) do |
| 26 | + with {:ok, feed} <- ORM.find_by(BlogRSS, %{rss: rss}) do |
| 27 | + {:ok, feed} |
| 28 | + else |
| 29 | + _ -> fetch_fresh_rssinfo_and_cache(rss) |
| 30 | + end |
| 31 | + end |
| 32 | + |
| 33 | + # attrs 包含 rss, blog_title |
| 34 | + # def create_article(%Community{id: cid}, thread, attrs, %User{id: uid}) do |
| 35 | + def create_blog(%Community{} = community, attrs, %User{} = user) do |
| 36 | + # 1. 先判断 rss 是否存在 |
| 37 | + ## 1.1 如果存在,从 cache 中获取 |
| 38 | + ## 1.2 如不存在,则创建一条 RSS |
| 39 | + with {:ok, feed} <- blog_rss_info(attrs.rss) do |
| 40 | + do_create_blog(community, attrs, user, feed) |
| 41 | + |
| 42 | + # IO.inspect(feed, label: "create blog") |
| 43 | + # 通过 feed 有没有 id 来 insert / update |
| 44 | + # 通过 blog_title, 组合 attrs 传给 create_article |
| 45 | + end |
| 46 | + |
| 47 | + # 2. 创建 blog |
| 48 | + ## 2.1 blog +字段 rss, author |
| 49 | + ## 2.2 title, digest, xxx |
| 50 | + |
| 51 | + # 前台获取作者信息的时候从 rss 表读取 |
| 52 | + end |
| 53 | + |
| 54 | + # rss 记录存在, 直接创建 blog |
| 55 | + defp do_create_blog(%Community{} = community, attrs, %User{} = user, %{id: _} = feed) do |
| 56 | + blog_author = if is_nil(feed.author), do: nil, else: Map.from_struct(feed.author) |
| 57 | + selected_feed = Enum.find(feed.history_feed, &(&1.title == attrs.title)) |
| 58 | + |
| 59 | + # TODO: feed_digest, feed_content |
| 60 | + attrs = |
| 61 | + attrs |
| 62 | + |> Map.merge(%{ |
| 63 | + link_addr: selected_feed.link_addr, |
| 64 | + published: selected_feed.published, |
| 65 | + blog_author: blog_author |
| 66 | + }) |
| 67 | + |> Enum.reject(fn {_, v} -> is_nil(v) end) |
| 68 | + |> Map.new() |
| 69 | + |
| 70 | + create_article(community, :blog, attrs, user) |
| 71 | + end |
| 72 | + |
| 73 | + # rss 记录不存在, 先创建 rss, 再创建 blog |
| 74 | + defp do_create_blog(%Community{} = community, attrs, %User{} = user, feed) do |
| 75 | + with {:ok, feed} <- CMS.blog_rss_info(attrs.rss), |
| 76 | + {:ok, feed} <- create_blog_rss(feed) do |
| 77 | + do_create_blog(community, attrs, user, feed) |
| 78 | + end |
| 79 | + end |
| 80 | + |
| 81 | + def create_blog_rss(attrs) do |
| 82 | + history_feed = Map.get(attrs, :history_feed) |
| 83 | + attrs = attrs |> Map.drop([:history_feed]) |
| 84 | + |
| 85 | + %BlogRSS{} |
| 86 | + |> Ecto.Changeset.change(attrs) |
| 87 | + |> Ecto.Changeset.put_embed(:history_feed, history_feed) |
| 88 | + |> Repo.insert() |
| 89 | + end |
| 90 | + |
| 91 | + def update_blog_rss(%{rss: rss} = attrs) do |
| 92 | + with {:ok, blog_rss} <- ORM.find_by(BlogRSS, rss: rss) do |
| 93 | + history_feed = |
| 94 | + Map.get(attrs, :history_feed, Enum.map(blog_rss.history_feed, &strip_struct(&1))) |
| 95 | + |
| 96 | + attrs = attrs |> Map.drop([:history_feed]) |
| 97 | + |
| 98 | + %BlogRSS{} |
| 99 | + |> Ecto.Changeset.change(attrs) |
| 100 | + |> Ecto.Changeset.put_embed(:history_feed, history_feed) |
| 101 | + |> Repo.insert() |
| 102 | + end |
| 103 | + end |
| 104 | + |
| 105 | + # create done |
| 106 | + # defp result({:ok, %{set_active_at_timestamp: result}}) do |
| 107 | + # {:ok, result} |
| 108 | + # end |
| 109 | + |
| 110 | + # defp result({:ok, %{update_article_meta: result}}), do: {:ok, result} |
| 111 | + |
| 112 | + # defp result({:error, :create_article, _result, _steps}) do |
| 113 | + # {:error, [message: "create article", code: ecode(:create_fails)]} |
| 114 | + # end |
| 115 | + |
| 116 | + # defp result({:error, _, result, _steps}), do: {:error, result} |
| 117 | + |
| 118 | + @doc """ |
| 119 | + get and cache feed by rss address as key |
| 120 | + """ |
| 121 | + def fetch_fresh_rssinfo_and_cache(rss) do |
| 122 | + case Cache.get(@cache_pool, rss) do |
| 123 | + {:ok, rssinfo} -> {:ok, rssinfo} |
| 124 | + {:error, _} -> get_rssinfo_and_cache(rss) |
| 125 | + end |
| 126 | + end |
| 127 | + |
| 128 | + defp get_rssinfo_and_cache(rss) do |
| 129 | + # {:ok, feed} = RSS.get(rss) |
| 130 | + with {:ok, rssinfo} <- RSS.get(rss) do |
| 131 | + Cache.put(@cache_pool, rss, rssinfo) |
| 132 | + {:ok, rssinfo} |
| 133 | + else |
| 134 | + {:error, _} -> {:error, [message: "blog rss is invalid", code: ecode(:invalid_blog_rss)]} |
| 135 | + end |
| 136 | + end |
| 137 | +end |
0 commit comments