diff --git a/.formatter.exs b/.formatter.exs new file mode 100644 index 0000000..a45ccc3 --- /dev/null +++ b/.formatter.exs @@ -0,0 +1,10 @@ +[ + inputs: [ + "{lib,test,priv}/**/*.{ex,exs}", + "mix.exs", + ".formatter.exs", + ".iex.exs", + ".credo.exs" + ], + import_deps: [:ecto, :plug, :phoenix] +] diff --git a/lib/mipha/accounts/accounts.ex b/lib/mipha/accounts/accounts.ex index 7c2e699..82acb12 100644 --- a/lib/mipha/accounts/accounts.ex +++ b/lib/mipha/accounts/accounts.ex @@ -132,7 +132,7 @@ defmodule Mipha.Accounts do case check_user_password(user, attrs.password) do true -> {:ok, user} - _ -> {:error, "Failed auth."} + _ -> {:error, "Failed auth."} end end @@ -181,7 +181,7 @@ defmodule Mipha.Accounts do defp check_user_password(user, password) do case user do nil -> false - _ -> !is_nil(user.password_hash) && Bcrypt.checkpw(password, user.password_hash) + _ -> !is_nil(user.password_hash) && Bcrypt.checkpw(password, user.password_hash) end end @@ -220,7 +220,8 @@ defmodule Mipha.Accounts do |> User.update_password_changeset(attrs) |> Repo.update() - _ -> {:error, "Invalid current password"} + _ -> + {:error, "Invalid current password"} end end @@ -228,7 +229,7 @@ defmodule Mipha.Accounts do Mark the current user verified """ def mark_as_verified(user) do - attrs = %{"email_verified_at" => Timex.now} + attrs = %{"email_verified_at" => Timex.now()} update_user(user, attrs) end @@ -284,14 +285,14 @@ defmodule Mipha.Accounts do def github_repositories(%User{} = user) do user |> github_repos_cache_key - |> Store.get! + |> Store.get!() |> fetch_github_repos(user) end def github_repositories(%Team{} = team) do team |> github_repos_cache_key - |> Store.get! + |> Store.get!() |> fetch_github_repos(team) end @@ -300,12 +301,13 @@ defmodule Mipha.Accounts do repos = target |> github_repos_url - |> HTTPoison.get! + |> HTTPoison.get!() |> handle_response Store.put!(github_repos_cache_key(target), repos) repos end + defp fetch_github_repos(items, _) do items end @@ -313,11 +315,12 @@ defmodule Mipha.Accounts do # 拉取数据,并且 Json 处理 defp handle_response(%HTTPoison.Response{body: body, status_code: 200}) do body - |> Jason.decode! - |> Enum.map(&(Map.take(&1, ~w(name html_url watchers language description)))) + |> Jason.decode!() + |> Enum.map(&Map.take(&1, ~w(name html_url watchers language description))) |> Enum.sort(&(&1["watchers"] >= &2["watchers"])) |> Enum.take(10) end + defp handle_response(%HTTPoison.Response{body: _, status_code: 404}) do [] end @@ -329,7 +332,9 @@ defmodule Mipha.Accounts do # 请求获取 github 用户的 repos 的 Url defp github_repos_url(target) do - "https://api.github.com/users/#{github_handle(target)}/repos?type=owner&sort=pushed&client_id=#{System.get_env("GITHUB_CLIENT_ID")}&client_secret=#{System.get_env("GITHUB_CLIENT_SECRET")}" + "https://api.github.com/users/#{github_handle(target)}/repos?type=owner&sort=pushed&client_id=#{ + System.get_env("GITHUB_CLIENT_ID") + }&client_secret=#{System.get_env("GITHUB_CLIENT_SECRET")}" end @doc """ @@ -338,6 +343,7 @@ defmodule Mipha.Accounts do def github_handle(%User{} = user) do user.github_handle || user.username end + def github_handle(%Team{} = team) do team.github_handle || team.name end @@ -375,13 +381,15 @@ defmodule Mipha.Accounts do Returns the user update_password changeset """ @spec user_update_password_changeset(Map.t()) :: Ecto.Changeset.t() - def user_update_password_changeset(attrs \\ %{}), do: User.update_password_changeset(%User{}, attrs) + def user_update_password_changeset(attrs \\ %{}), + do: User.update_password_changeset(%User{}, attrs) @doc """ Returns the change user reset password. """ @spec change_user_reset_password(User.t(), Map.t()) :: Ecto.Changeset.t() - def change_user_reset_password(%User{} = user, attrs \\ %{}), do: User.reset_password_changeset(user, attrs) + def change_user_reset_password(%User{} = user, attrs \\ %{}), + do: User.reset_password_changeset(user, attrs) alias Mipha.Accounts.Location diff --git a/lib/mipha/accounts/user.ex b/lib/mipha/accounts/user.ex index bdffa5d..fbd5411 100644 --- a/lib/mipha/accounts/user.ex +++ b/lib/mipha/accounts/user.ex @@ -127,10 +127,10 @@ defmodule Mipha.Accounts.User do |> cast(attrs, permitted_attrs) |> validate_required(register_attrs) |> validate_length(:username, min: 3, max: 12) - |> validate_format(:username, Regexp.username) + |> validate_format(:username, Regexp.username()) |> unique_constraint(:username) |> validate_length(:email, min: 1, max: 20) - |> validate_format(:email, Regexp.email) + |> validate_format(:email, Regexp.email()) |> unique_constraint(:email) |> put_pass_hash() end @@ -188,6 +188,7 @@ defmodule Mipha.Accounts.User do case changeset do %Ecto.Changeset{valid?: true, changes: %{password: password}} -> put_change(changeset, :password_hash, Bcrypt.hashpwsalt(password)) + _ -> changeset end diff --git a/lib/mipha/collections/queries.ex b/lib/mipha/collections/queries.ex index de6d1d5..6c4391e 100644 --- a/lib/mipha/collections/queries.ex +++ b/lib/mipha/collections/queries.ex @@ -22,8 +22,8 @@ defmodule Mipha.Collections.Queries do defp filter_from_clauses(opts) do cond do - Keyword.has_key?(opts, :user) -> opts |> Keyword.get(:user) |> Collection.by_user - Keyword.has_key?(opts, :topic) -> opts |> Keyword.get(:topic) |> Collection.by_topic + Keyword.has_key?(opts, :user) -> opts |> Keyword.get(:user) |> Collection.by_user() + Keyword.has_key?(opts, :topic) -> opts |> Keyword.get(:topic) |> Collection.by_topic() true -> Collection end end diff --git a/lib/mipha/follows/follows.ex b/lib/mipha/follows/follows.ex index a7a0d80..f40f33f 100644 --- a/lib/mipha/follows/follows.ex +++ b/lib/mipha/follows/follows.ex @@ -5,12 +5,14 @@ defmodule Mipha.Follows do import Ecto.Query, warn: false alias Ecto.Multi + alias Mipha.{ Repo, Follows, Accounts, Notifications } + alias Follows.Follow alias Accounts.User @@ -124,7 +126,7 @@ defmodule Mipha.Follows do def delete_follow(clauses) when length(clauses) == 2 do clauses |> get_follow - |> Repo.delete + |> Repo.delete() end @doc """ @@ -155,6 +157,7 @@ defmodule Mipha.Follows do @spec unfollow_user(Keyword.t()) :: {:ok, Follow.t()} | {:error, any()} def unfollow_user(follower: follower, user: user) do opts = [follower: follower, user: user] + if can_follow?(opts) do if has_followed?(opts) do delete_follow(user_id: user.id, follower_id: follower.id) @@ -180,6 +183,7 @@ defmodule Mipha.Follows do @spec follow_user(Keyword.t()) :: {:ok, Follow.t()} | {:error, any()} def follow_user(follower: follower, user: user) do opts = [follower: follower, user: user] + if can_follow?(opts) do if has_followed?(opts) do {:error, "Follow already."} @@ -200,7 +204,7 @@ defmodule Mipha.Follows do %User{id: follower_id} = Keyword.get(clauses, :follower) %User{id: user_id} = Keyword.get(clauses, :user) - user_id == follower_id && false || true + (user_id == follower_id && false) || true end @doc """ @@ -292,7 +296,7 @@ defmodule Mipha.Follows do query = clauses |> Keyword.get(:user) - |> Follow.by_user + |> Follow.by_user() query |> join(:inner, [c], u in assoc(c, :follower)) diff --git a/lib/mipha/follows/queries.ex b/lib/mipha/follows/queries.ex index 63731d4..6777e56 100644 --- a/lib/mipha/follows/queries.ex +++ b/lib/mipha/follows/queries.ex @@ -29,8 +29,8 @@ defmodule Mipha.Follows.Queries do defp filter_from_clauses(opts) do cond do - Keyword.has_key?(opts, :follower) -> opts |> Keyword.get(:follower) |> Follow.by_follower - Keyword.has_key?(opts, :user) -> opts |> Keyword.get(:user) |> Follow.by_user + Keyword.has_key?(opts, :follower) -> opts |> Keyword.get(:follower) |> Follow.by_follower() + Keyword.has_key?(opts, :user) -> opts |> Keyword.get(:user) |> Follow.by_user() true -> Follow end end diff --git a/lib/mipha/markdown/embed_video_replacer.ex b/lib/mipha/markdown/embed_video_replacer.ex index d17c561..caea857 100644 --- a/lib/mipha/markdown/embed_video_replacer.ex +++ b/lib/mipha/markdown/embed_video_replacer.ex @@ -1,14 +1,14 @@ defmodule Mipha.Markdown.EmbedVideoReplacer do @moduledoc false - @youtube_url_regex ~r{(\s|^|
|
)(https?://)(www.)?(youtube\.com/watch\?v=|youtu\.be/|youtube\.com/watch\?feature=player_embedded&v=)([A-Za-z0-9_\-]*)(\&\S+)?(\?\S+)?} - @youku_url_regex ~r{(\s|^|
|
)(http?://)(v\.youku\.com/v_show/id_)([a-zA-Z0-9\-_\=]*)(\.html)(\&\S+)?(\?\S+)?} - @youku_base_url "//player.youku.com/embed/" - @youtube_base_url "//www.youtube.com/embed/" + @youtube_url_regex ~r{(\s|^|
|
)(https?://)(www.)?(youtube\.com/watch\?v=|youtu\.be/|youtube\.com/watch\?feature=player_embedded&v=)([A-Za-z0-9_\-]*)(\&\S+)?(\?\S+)?} + @youku_url_regex ~r{(\s|^|
|
)(http?://)(v\.youku\.com/v_show/id_)([a-zA-Z0-9\-_\=]*)(\.html)(\&\S+)?(\?\S+)?} + @youku_base_url "//player.youku.com/embed/" + @youtube_base_url "//www.youtube.com/embed/" def run(body) do cond do - Regex.match?(@youtube_url_regex, body) == true -> + Regex.match?(@youtube_url_regex, body) == true -> @youtube_url_regex |> Regex.replace(body, &youtube_replacer/1) diff --git a/lib/mipha/markdown/html_renderer.ex b/lib/mipha/markdown/html_renderer.ex index c91b70b..9b78f88 100644 --- a/lib/mipha/markdown/html_renderer.ex +++ b/lib/mipha/markdown/html_renderer.ex @@ -9,9 +9,9 @@ defmodule Mipha.Markdown.HtmlRenderer do @moduledoc false - alias Earmark.Block - alias Earmark.Context - alias Earmark.Options + alias Earmark.Block + alias Earmark.Context + alias Earmark.Options import Earmark.Inline, only: [convert: 3] import Earmark.Helpers, only: [escape: 2] import Earmark.Helpers.HtmlHelpers @@ -25,12 +25,12 @@ defmodule Mipha.Markdown.HtmlRenderer do {contexts, html} = blocks - |> mapper.(&(render_block(&1, put_in(context.options.messages, [])))) + |> mapper.(&render_block(&1, put_in(context.options.messages, []))) |> Enum.unzip() all_messages = contexts - |> Enum.reduce(messages, fn (ctx, messages1) -> messages1 ++ get_messages(ctx) end) + |> Enum.reduce(messages, fn ctx, messages1 -> messages1 ++ get_messages(ctx) end) {put_in(context.options.messages, all_messages), html |> IO.iodata_to_binary()} end @@ -71,7 +71,10 @@ defmodule Mipha.Markdown.HtmlRenderer do end # Heading - defp render_block(%Block.Heading{lnb: lnb, level: level, content: content, attrs: attrs}, context) do + defp render_block( + %Block.Heading{lnb: lnb, level: level, content: content, attrs: attrs}, + context + ) do converted = convert(content, lnb, context) html = "#{converted.value}\n" add_attrs!(converted, html, attrs, [], lnb) @@ -85,27 +88,36 @@ defmodule Mipha.Markdown.HtmlRenderer do end # Table - defp render_block(%Block.Table{lnb: lnb, header: header, rows: rows, alignments: aligns, attrs: attrs}, context) do + defp render_block( + %Block.Table{lnb: lnb, header: header, rows: rows, alignments: aligns, attrs: attrs}, + context + ) do cols = for _align <- aligns, do: "\n" {context1, html} = add_attrs!(context, "\n", attrs, [], lnb) - html = [html , "\n", cols, "\n"] + html = [html, "\n", cols, "\n"] context2 = set_value(context1, html) - context3 = if header do - append(add_trs(append(context2, "\n"), [header], "th", aligns, lnb), "\n") - else - # Maybe an error, needed append(context, html) - context2 - end + context3 = + if header do + append(add_trs(append(context2, "\n"), [header], "th", aligns, lnb), "\n") + else + # Maybe an error, needed append(context, html) + context2 + end - context4 = add_trs(context3, rows, "td", aligns, lnb) + context4 = add_trs(context3, rows, "td", aligns, lnb) {context4, [context4.value, "
\n"]} end # Code - defp render_block(%Block.Code{lnb: lnb, language: language, attrs: attrs} = block, %Context{options: options} = context) do - class = if language, do: ~s{ class="#{code_classes( language, options.code_class_prefix)}"}, else: "" + defp render_block( + %Block.Code{lnb: lnb, language: language, attrs: attrs} = block, + %Context{options: options} = context + ) do + class = + if language, do: ~s{ class="#{code_classes(language, options.code_class_prefix)}"}, else: "" + tag = ~s[
]
     lines = options.render_code.(block)
     html = ~s[#{tag}#{lines}
\n] @@ -113,15 +125,21 @@ defmodule Mipha.Markdown.HtmlRenderer do end # Lists - defp render_block(%Block.List{lnb: lnb, type: type, blocks: items, attrs: attrs, start: start}, context) do + defp render_block( + %Block.List{lnb: lnb, type: type, blocks: items, attrs: attrs, start: start}, + context + ) do {context1, content} = render(items, context) html = "<#{type}#{start}>\n#{content}\n" add_attrs!(context1, html, attrs, [], lnb) end # format a single paragraph list item, and remove the para tags - defp render_block(%Block.ListItem{lnb: lnb, blocks: blocks, spaced: false, attrs: attrs}, context) - when length(blocks) == 1 do + defp render_block( + %Block.ListItem{lnb: lnb, blocks: blocks, spaced: false, attrs: attrs}, + context + ) + when length(blocks) == 1 do {context1, content} = render(blocks, context) content = Regex.replace(~r{}, content, "") html = "
  • #{content}
  • \n" @@ -137,10 +155,12 @@ defmodule Mipha.Markdown.HtmlRenderer do # Footnote Block defp render_block(%Block.FnList{blocks: footnotes}, context) do - items = Enum.map(footnotes, fn(note) -> - blocks = append_footnote_link(note) - %Block.ListItem{attrs: "#fn:#{note.number}", type: :ol, blocks: blocks} - end) + items = + Enum.map(footnotes, fn note -> + blocks = append_footnote_link(note) + %Block.ListItem{attrs: "#fn:#{note.number}", type: :ol, blocks: blocks} + end) + {context1, html} = render_block(%Block.List{type: :ol, blocks: items}, context) {context1, Enum.join([~s[
    ], "
    ", html, "
    "], "\n")} end @@ -156,20 +176,20 @@ defmodule Mipha.Markdown.HtmlRenderer do defp render_block(%Block.Plugin{lines: lines, handler: handler}, context) do case handler.as_html(lines) do html when is_list(html) -> {context, html} - {html, errors} -> {add_messages(context, errors), html} - html -> {context, [html]} + {html, errors} -> {add_messages(context, errors), html} + html -> {context, [html]} end end # And here are the inline renderers # - def br, do: "
    " - def codespan(text), do: ~s[#{text}] - def em(text), do: "#{text}" - def strong(text), do: "#{text}" + def br, do: "
    " + def codespan(text), do: ~s[#{text}] + def em(text), do: "#{text}" + def strong(text), do: "#{text}" def strikethrough(text), do: "#{text}" - def link(url, text), do: ~s[#{text}] - def link(url, text, nil), do: ~s[#{text}] + def link(url, text), do: ~s[#{text}] + def link(url, text, nil), do: ~s[#{text}] def link(url, text, title), do: ~s[#{text}] def image(path, alt, nil) do @@ -180,17 +200,20 @@ defmodule Mipha.Markdown.HtmlRenderer do ~s[#{alt}] end - def footnote_link(ref, backref, number), do: ~s[#{number}] + def footnote_link(ref, backref, number), + do: ~s[#{number}] # Table rows def add_trs(context, rows, tag, aligns, lnb) do - numbered_rows = rows - |> Enum.zip(Stream.iterate(lnb, &(&1 + 1))) + numbered_rows = + rows + |> Enum.zip(Stream.iterate(lnb, &(&1 + 1))) + # for {row, lnb1} <- numbered_rows, do: "\n#{add_tds(context, row, tag, aligns, lnb1)}\n\n" numbered_rows - |> Enum.reduce(context, fn {row, lnb}, ctx -> - append(add_tds(append(ctx, "\n"), row, tag, aligns, lnb), "\n\n") - end) + |> Enum.reduce(context, fn {row, lnb}, ctx -> + append(add_tds(append(ctx, "\n"), row, tag, aligns, lnb), "\n\n") + end) end defp add_tds(context, row, tag, aligns, lnb) do @@ -202,22 +225,26 @@ defmodule Mipha.Markdown.HtmlRenderer do style = case Enum.at(aligns, n - 1, :default) do :default -> "" - align -> " style=\"text-align: #{align}\"" + align -> " style=\"text-align: #{align}\"" end + col = Enum.at(row, n - 1) - converted = convert(col, lnb, ctx) + converted = convert(col, lnb, ctx) append(add_messages_from(ctx, converted), "<#{tag}#{style}>#{converted.value}") end end # Append Footnote Return Link def append_footnote_link(%Block.FnDef{} = note) do - fnlink = ~s[] + fnlink = + ~s[] + [last_block | blocks] = Enum.reverse(note.blocks) last_block = append_footnote_link(last_block, fnlink) + [last_block | blocks] |> Enum.reverse() - |> List.flatten + |> List.flatten() end def append_footnote_link(%Block.Para{lines: lines} = block, fnlink) do diff --git a/lib/mipha/notifications/notification.ex b/lib/mipha/notifications/notification.ex index 948088a..55a4939 100644 --- a/lib/mipha/notifications/notification.ex +++ b/lib/mipha/notifications/notification.ex @@ -24,7 +24,7 @@ defmodule Mipha.Notifications.Notification do # Follow user action # :topic_added # :topic_reply_added - defenum NotificationAction, :notification_action, [ + defenum(NotificationAction, :notification_action, [ :topic_reply_added, :topic_starred, :reply_starred, @@ -33,7 +33,7 @@ defmodule Mipha.Notifications.Notification do :reply_mentioned, :followed, :topic_added - ] + ]) schema "notifications" do field :action, NotificationAction diff --git a/lib/mipha/notifications/notifications.ex b/lib/mipha/notifications/notifications.ex index de12df7..f18d24b 100644 --- a/lib/mipha/notifications/notifications.ex +++ b/lib/mipha/notifications/notifications.ex @@ -5,6 +5,7 @@ defmodule Mipha.Notifications do import Ecto.Query, warn: false alias Ecto.Multi + alias Mipha.{ Repo, Topics, @@ -117,9 +118,10 @@ defmodule Mipha.Notifications do @doc """ 标记单个已读 """ - @spec read_notification(UserNotification.t()) :: {:ok, UserNotification.t()} | {:error, %Ecto.Changeset{}} + @spec read_notification(UserNotification.t()) :: + {:ok, UserNotification.t()} | {:error, %Ecto.Changeset{}} def read_notification(%UserNotification{} = user_notification) do - attrs = %{read_at: Timex.now} + attrs = %{read_at: Timex.now()} user_notification |> UserNotification.update_changeset(attrs) @@ -134,7 +136,7 @@ defmodule Mipha.Notifications do user |> UserNotification.by_user() |> UserNotification.unread() - |> Repo.update_all(set: [read_at: Timex.now]) + |> Repo.update_all(set: [read_at: Timex.now()]) end @doc """ @@ -166,7 +168,7 @@ defmodule Mipha.Notifications do |> Map.get(:actor) end - @doc """ + @doc """ 获取通知对象 topic || reply || user ## Examples diff --git a/lib/mipha/qiniu.ex b/lib/mipha/qiniu.ex index 034d28e..9c3d1cc 100644 --- a/lib/mipha/qiniu.ex +++ b/lib/mipha/qiniu.ex @@ -6,7 +6,7 @@ defmodule Mipha.Qiniu do def upload(path) do @bucket - |> Qiniu.PutPolicy.build + |> Qiniu.PutPolicy.build() |> Qiniu.Uploader.upload(path, key: generate_key()) end @@ -16,11 +16,12 @@ defmodule Mipha.Qiniu do def q_url(value) when is_nil(value) do @base_url <> "default.jpg" end + def q_url(value) do @base_url <> value end defp generate_key do - "#{Timex.to_unix(Timex.now)}/#{Enum.random(1..1_000)}.jpg" + "#{Timex.to_unix(Timex.now())}/#{Enum.random(1..1_000)}.jpg" end end diff --git a/lib/mipha/replies/queries.ex b/lib/mipha/replies/queries.ex index cf11e73..fa2178c 100644 --- a/lib/mipha/replies/queries.ex +++ b/lib/mipha/replies/queries.ex @@ -31,8 +31,8 @@ defmodule Mipha.Replies.Queries do defp filter_from_clauses(opts) do cond do - Keyword.has_key?(opts, :user) -> opts |> Keyword.get(:user) |> Reply.by_user - Keyword.has_key?(opts, :topic) -> opts |> Keyword.get(:topic) |> Reply.by_topic + Keyword.has_key?(opts, :user) -> opts |> Keyword.get(:user) |> Reply.by_user() + Keyword.has_key?(opts, :topic) -> opts |> Keyword.get(:topic) |> Reply.by_topic() true -> Reply end end diff --git a/lib/mipha/replies/replies.ex b/lib/mipha/replies/replies.ex index 107449e..462b64b 100644 --- a/lib/mipha/replies/replies.ex +++ b/lib/mipha/replies/replies.ex @@ -112,7 +112,7 @@ defmodule Mipha.Replies do |> Reply.preload_topic() |> Map.fetch!(:topic) - attrs = %{reply_count: (topic.reply_count - 1)} + attrs = %{reply_count: topic.reply_count - 1} Topics.update_topic(topic, attrs) end @@ -222,7 +222,7 @@ defmodule Mipha.Replies do notified_users = @username_regex |> Regex.scan(attrs["content"]) - |> Enum.map(fn([_, match]) -> Accounts.get_user_by_username(match) end) + |> Enum.map(fn [_, match] -> Accounts.get_user_by_username(match) end) |> Enum.filter(&(not is_nil(&1))) attrs = %{ @@ -252,7 +252,7 @@ defmodule Mipha.Replies do attrs = %{ last_reply_id: reply.id, last_reply_user_id: reply.user_id, - reply_count: (topic.reply_count + 1) + reply_count: topic.reply_count + 1 } case Topics.update_topic(topic, attrs) do @@ -287,11 +287,13 @@ defmodule Mipha.Replies do {:error, _, reason, _} -> {:error, reason} end end + Multi.run(multi, :notify_topic_owner_of_new_reply, insert_notification_fn) end # 如果是回复其他人的评论,回复该评论的作者, 有新的回复。 - defp maybe_notify_parent_reply_owner_of_new_reply(multi, %{"parent_id" => parent_id}) when parent_id != "" do + defp maybe_notify_parent_reply_owner_of_new_reply(multi, %{"parent_id" => parent_id}) + when parent_id != "" do insert_notification_fn = fn %{reply: reply} -> notified_users = reply @@ -315,6 +317,7 @@ defmodule Mipha.Replies do Multi.run(multi, :notify_parent_reply_owner_of_new_reply, insert_notification_fn) end + defp maybe_notify_parent_reply_owner_of_new_reply(multi, _), do: multi # 发起评论时,通知关注评论作者的 follower diff --git a/lib/mipha/stars/stars.ex b/lib/mipha/stars/stars.ex index e636469..17cea16 100644 --- a/lib/mipha/stars/stars.ex +++ b/lib/mipha/stars/stars.ex @@ -5,6 +5,7 @@ defmodule Mipha.Stars do import Ecto.Query, warn: false alias Ecto.Multi + alias Mipha.{ Repo, Stars, @@ -112,25 +113,27 @@ defmodule Mipha.Stars do end # unstar, decrease topic star_count - defp decrease_related_count(multi, [user_id: _, topic_id: topic_id]) when topic_id != "" do + defp decrease_related_count(multi, user_id: _, topic_id: topic_id) when topic_id != "" do update_topic_fn = fn %{star: star} -> topic = starrable(star) - attrs = %{star_count: (topic.star_count - 1)} + attrs = %{star_count: topic.star_count - 1} Topics.update_topic(topic, attrs) end Multi.run(multi, :decrease_related_count, update_topic_fn) end + # unstar, decrease reply star_count - defp decrease_related_count(multi, [user_id: _, reply_id: reply_id]) when reply_id != "" do + defp decrease_related_count(multi, user_id: _, reply_id: reply_id) when reply_id != "" do update_reply_fn = fn %{star: star} -> reply = starrable(star) - attrs = %{star_count: (reply.star_count - 1)} + attrs = %{star_count: reply.star_count - 1} Replies.update_reply(reply, attrs) end Multi.run(multi, :decrease_related_count, update_reply_fn) end + defp decrease_related_count(multi, _), do: multi @doc """ @@ -204,22 +207,24 @@ defmodule Mipha.Stars do defp increase_related_count(multi, %{topic_id: topic_id}) when topic_id != "" do update_topic_fn = fn %{star: star} -> topic = starrable(star) - attrs = %{star_count: (topic.star_count + 1)} + attrs = %{star_count: topic.star_count + 1} Topics.update_topic(topic, attrs) end Multi.run(multi, :increase_related_count, update_topic_fn) end + # star, increase reply star_count defp increase_related_count(multi, %{reply_id: reply_id}) when reply_id != "" do update_reply_fn = fn %{star: star} -> reply = starrable(star) - attrs = %{star_count: (reply.star_count + 1)} + attrs = %{star_count: reply.star_count + 1} Replies.update_reply(reply, attrs) end Multi.run(multi, :increase_related_count, update_reply_fn) end + defp increase_related_count(multi, _), do: multi defp notify_author_of_starrable(multi) do diff --git a/lib/mipha/topics/queries.ex b/lib/mipha/topics/queries.ex index ad780b0..ac03c5b 100644 --- a/lib/mipha/topics/queries.ex +++ b/lib/mipha/topics/queries.ex @@ -21,7 +21,7 @@ defmodule Mipha.Topics.Queries do """ @spec job_topics :: Ecto.Query.t() def job_topics do - Topic.job + Topic.job() |> preload([:user, :node, :last_reply_user]) end @@ -47,16 +47,16 @@ defmodule Mipha.Topics.Queries do def cond_topics(opts) do opts |> filter_from_clauses - |> Topic.base_order + |> Topic.base_order() |> preload([:user, :node, :last_reply_user]) end defp filter_from_clauses(opts), do: do_filter_from_clauses(opts) - defp do_filter_from_clauses(type: :educational), do: Topic.educational - defp do_filter_from_clauses(type: :featured), do: Topic.featured - defp do_filter_from_clauses(type: :no_reply), do: Topic.no_reply - defp do_filter_from_clauses(type: :popular), do: Topic.popular + defp do_filter_from_clauses(type: :educational), do: Topic.educational() + defp do_filter_from_clauses(type: :featured), do: Topic.featured() + defp do_filter_from_clauses(type: :no_reply), do: Topic.no_reply() + defp do_filter_from_clauses(type: :popular), do: Topic.popular() defp do_filter_from_clauses(node: node), do: Topic.by_node(node) defp do_filter_from_clauses(user: user), do: Topic.by_user(user) defp do_filter_from_clauses(user_ids: user_ids), do: Topic.by_user_ids(user_ids) diff --git a/lib/mipha/topics/topic.ex b/lib/mipha/topics/topic.ex index 95d7205..8b3c4b7 100644 --- a/lib/mipha/topics/topic.ex +++ b/lib/mipha/topics/topic.ex @@ -17,12 +17,12 @@ defmodule Mipha.Topics.Topic do @type t :: %Topic{} - defenum TopicType, :topic_type, [ + defenum(TopicType, :topic_type, [ :normal, :featured, :educational, :job - ] + ]) schema "topics" do field :title, :string diff --git a/lib/mipha/topics/topics.ex b/lib/mipha/topics/topics.ex index ee26dd6..bd56e53 100644 --- a/lib/mipha/topics/topics.ex +++ b/lib/mipha/topics/topics.ex @@ -172,7 +172,7 @@ defmodule Mipha.Topics do notified_users = @username_regex |> Regex.scan(attrs["body"]) - |> Enum.map(fn([_, match]) -> Accounts.get_user_by_username(match) end) + |> Enum.map(fn [_, match] -> Accounts.get_user_by_username(match) end) |> Enum.filter(&(not is_nil(&1))) attrs = %{ @@ -212,7 +212,7 @@ defmodule Mipha.Topics do """ def list_featured_topics do - Topic.featured + Topic.featured() |> Repo.all() |> Repo.preload([:node, :user, :last_reply_user]) end @@ -242,9 +242,9 @@ defmodule Mipha.Topics do @spec recent_topics(User.t()) :: [Topic.t()] | nil def recent_topics(%User{} = user) do user - |> Topic.by_user - |> Topic.recent - |> Repo.all + |> Topic.by_user() + |> Topic.recent() + |> Repo.all() |> Repo.preload([:node, :user, :last_reply_user]) end @@ -260,7 +260,7 @@ defmodule Mipha.Topics do @spec author(Topic.t()) :: User.t() def author(%Topic{} = topic) do topic - |> Topic.preload_user + |> Topic.preload_user() |> Map.fetch!(:user) end @@ -364,8 +364,8 @@ defmodule Mipha.Topics do """ @spec list_parent_nodes :: [Node.t()] | nil def list_parent_nodes do - Node.is_parent - |> Repo.all - |> Node.preload_children + Node.is_parent() + |> Repo.all() + |> Node.preload_children() end end diff --git a/lib/mipha_web.ex b/lib/mipha_web.ex index 70b7420..239e6c9 100644 --- a/lib/mipha_web.ex +++ b/lib/mipha_web.ex @@ -29,8 +29,9 @@ defmodule MiphaWeb do def view do quote do - use Phoenix.View, root: "lib/mipha_web/templates", - namespace: MiphaWeb + use Phoenix.View, + root: "lib/mipha_web/templates", + namespace: MiphaWeb # Import convenience functions from controllers import Phoenix.Controller, only: [get_flash: 2, view_module: 1, get_csrf_token: 0] diff --git a/lib/mipha_web/channels/presence.ex b/lib/mipha_web/channels/presence.ex index 3a44631..dd4f4e7 100644 --- a/lib/mipha_web/channels/presence.ex +++ b/lib/mipha_web/channels/presence.ex @@ -68,6 +68,7 @@ defmodule MiphaWeb.Presence do information, while maintaining the required `:metas` field from the original presence data. """ - use Phoenix.Presence, otp_app: :mipha, - pubsub_server: Mipha.PubSub + use Phoenix.Presence, + otp_app: :mipha, + pubsub_server: Mipha.PubSub end diff --git a/lib/mipha_web/channels/room_channel.ex b/lib/mipha_web/channels/room_channel.ex index 8023337..8e7418d 100644 --- a/lib/mipha_web/channels/room_channel.ex +++ b/lib/mipha_web/channels/room_channel.ex @@ -27,19 +27,20 @@ defmodule MiphaWeb.RoomChannel do # It is also common to receive messages from the client and # broadcast to everyone in the current topic (room:lobby). def handle_in("shout", payload, socket) do - broadcast socket, "shout", payload + broadcast(socket, "shout", payload) {:noreply, socket} end def handle_info(:after_join, socket) do - push socket, "presence_state", Presence.list(socket) + push(socket, "presence_state", Presence.list(socket)) user = Repo.get(User, socket.assigns[:user_id]) - {:ok, _} = Presence.track(socket, "user:#{user.id}", %{ - user_id: user.id, - username: user.username - }) + {:ok, _} = + Presence.track(socket, "user:#{user.id}", %{ + user_id: user.id, + username: user.username + }) {:noreply, socket} end diff --git a/lib/mipha_web/channels/topic_channel.ex b/lib/mipha_web/channels/topic_channel.ex index 2aad845..383a4f5 100644 --- a/lib/mipha_web/channels/topic_channel.ex +++ b/lib/mipha_web/channels/topic_channel.ex @@ -22,7 +22,7 @@ defmodule MiphaWeb.TopicChannel do # It is also common to receive messages from the client and # broadcast to everyone in the current topic (topic:lobby). def handle_in("shout", payload, socket) do - broadcast socket, "shout", payload + broadcast(socket, "shout", payload) {:noreply, socket} end diff --git a/lib/mipha_web/channels/user_socket.ex b/lib/mipha_web/channels/user_socket.ex index ee674e0..1b6301e 100644 --- a/lib/mipha_web/channels/user_socket.ex +++ b/lib/mipha_web/channels/user_socket.ex @@ -3,10 +3,10 @@ defmodule MiphaWeb.UserSocket do ## Channels # channel "room:*", MiphaWeb.RoomChannel - channel "topic:*", MiphaWeb.TopicChannel + channel("topic:*", MiphaWeb.TopicChannel) ## Transports - transport :websocket, Phoenix.Transports.WebSocket, timeout: 45_000 + transport(:websocket, Phoenix.Transports.WebSocket, timeout: 45_000) # transport :longpoll, Phoenix.Transports.LongPoll # Socket params are passed from the client and can @@ -25,6 +25,7 @@ defmodule MiphaWeb.UserSocket do case Phoenix.Token.verify(socket, "user socket", token, max_age: 86_400) do {:ok, user_id} -> {:ok, assign(socket, :user_id, user_id)} + {:error, _reason} -> :error end diff --git a/lib/mipha_web/controllers/admin/company_controller.ex b/lib/mipha_web/controllers/admin/company_controller.ex index fda7619..731dd1d 100644 --- a/lib/mipha_web/controllers/admin/company_controller.ex +++ b/lib/mipha_web/controllers/admin/company_controller.ex @@ -6,7 +6,7 @@ defmodule MiphaWeb.Admin.CompanyController do def index(conn, params) do result = Queries.list_companies() |> Turbo.Ecto.turbo(params) - render conn, :index, companies: result.datas, paginate: result.paginate + render(conn, :index, companies: result.datas, paginate: result.paginate) end def delete(conn, %{"id" => id}) do diff --git a/lib/mipha_web/controllers/admin/node_controller.ex b/lib/mipha_web/controllers/admin/node_controller.ex index b6ae1d5..dfa02bd 100644 --- a/lib/mipha_web/controllers/admin/node_controller.ex +++ b/lib/mipha_web/controllers/admin/node_controller.ex @@ -6,7 +6,7 @@ defmodule MiphaWeb.Admin.NodeController do def index(conn, params) do result = Queries.list_nodes() |> Turbo.Ecto.turbo(params) - render conn, :index, nodes: result.datas, paginate: result.paginate + render(conn, :index, nodes: result.datas, paginate: result.paginate) end def new(conn, _params) do @@ -20,6 +20,7 @@ defmodule MiphaWeb.Admin.NodeController do conn |> put_flash(:info, "Node created successfully.") |> redirect(to: admin_node_path(conn, :show, node)) + {:error, %Ecto.Changeset{} = changeset} -> render(conn, "new.html", changeset: changeset) end @@ -44,6 +45,7 @@ defmodule MiphaWeb.Admin.NodeController do conn |> put_flash(:info, "Node updated successfully.") |> redirect(to: admin_node_path(conn, :show, node)) + {:error, %Ecto.Changeset{} = changeset} -> render(conn, "edit.html", node: node, changeset: changeset) end diff --git a/lib/mipha_web/controllers/admin/page_controller.ex b/lib/mipha_web/controllers/admin/page_controller.ex index 8cd9aed..ef17c2e 100644 --- a/lib/mipha_web/controllers/admin/page_controller.ex +++ b/lib/mipha_web/controllers/admin/page_controller.ex @@ -2,6 +2,6 @@ defmodule MiphaWeb.Admin.PageController do use MiphaWeb, :controller def index(conn, _) do - render conn, :index + render(conn, :index) end end diff --git a/lib/mipha_web/controllers/admin/reply_controller.ex b/lib/mipha_web/controllers/admin/reply_controller.ex index 562497b..0aafdc1 100644 --- a/lib/mipha_web/controllers/admin/reply_controller.ex +++ b/lib/mipha_web/controllers/admin/reply_controller.ex @@ -6,7 +6,7 @@ defmodule MiphaWeb.Admin.ReplyController do def index(conn, params) do result = Queries.list_replies() |> Turbo.Ecto.turbo(params) - render conn, :index, replies: result.datas, paginate: result.paginate + render(conn, :index, replies: result.datas, paginate: result.paginate) end def show(conn, %{"id" => id}) do diff --git a/lib/mipha_web/controllers/admin/team_controller.ex b/lib/mipha_web/controllers/admin/team_controller.ex index 546473d..f2ca5f3 100644 --- a/lib/mipha_web/controllers/admin/team_controller.ex +++ b/lib/mipha_web/controllers/admin/team_controller.ex @@ -6,7 +6,7 @@ defmodule MiphaWeb.Admin.TeamController do def index(conn, params) do result = Queries.list_teams() |> Turbo.Ecto.turbo(params) - render conn, :index, teams: result.datas, paginate: result.paginate + render(conn, :index, teams: result.datas, paginate: result.paginate) end def delete(conn, %{"id" => id}) do diff --git a/lib/mipha_web/controllers/admin/topic_controller.ex b/lib/mipha_web/controllers/admin/topic_controller.ex index 53bb596..542bece 100644 --- a/lib/mipha_web/controllers/admin/topic_controller.ex +++ b/lib/mipha_web/controllers/admin/topic_controller.ex @@ -5,6 +5,6 @@ defmodule MiphaWeb.Admin.TopicController do def index(conn, params) do result = Queries.list_topics() |> Turbo.Ecto.turbo(params) - render conn, :index, topics: result.datas, paginate: result.paginate + render(conn, :index, topics: result.datas, paginate: result.paginate) end end diff --git a/lib/mipha_web/controllers/admin/user_controller.ex b/lib/mipha_web/controllers/admin/user_controller.ex index ae9fd07..93752b1 100644 --- a/lib/mipha_web/controllers/admin/user_controller.ex +++ b/lib/mipha_web/controllers/admin/user_controller.ex @@ -6,7 +6,7 @@ defmodule MiphaWeb.Admin.UserController do def index(conn, params) do result = Queries.list_users() |> Turbo.Ecto.turbo(params) - render conn, :index, users: result.datas, paginate: result.paginate + render(conn, :index, users: result.datas, paginate: result.paginate) end def delete(conn, %{"id" => id}) do diff --git a/lib/mipha_web/controllers/auth_controller.ex b/lib/mipha_web/controllers/auth_controller.ex index d6dae01..8a6d904 100644 --- a/lib/mipha_web/controllers/auth_controller.ex +++ b/lib/mipha_web/controllers/auth_controller.ex @@ -37,6 +37,7 @@ defmodule MiphaWeb.AuthController do login: params["user"]["login"], password: params["user"]["password"] } + case Accounts.authenticate(attrs) do {:ok, user} -> conn |> ok_login(user) @@ -48,17 +49,19 @@ defmodule MiphaWeb.AuthController do {:error, reason} -> changeset = Accounts.user_login_changeset() + conn |> put_flash(:danger, reason) |> render(:login, callback_url: Helpers.callback_url(conn), changeset: changeset) end + :github -> with %{name: name, nickname: nickname, email: email} <- auth.info do case Accounts.login_or_register_from_github(%{ - name: name, - nickname: nickname, - email: email - }) do + name: name, + nickname: nickname, + email: email + }) do {:ok, user} -> conn |> ok_login(user) diff --git a/lib/mipha_web/controllers/company_controller.ex b/lib/mipha_web/controllers/company_controller.ex index 97c5d08..6db6976 100644 --- a/lib/mipha_web/controllers/company_controller.ex +++ b/lib/mipha_web/controllers/company_controller.ex @@ -2,6 +2,6 @@ defmodule MiphaWeb.CompanyController do use MiphaWeb, :controller def action(conn, _) do - render conn, action_name(conn) + render(conn, action_name(conn)) end end diff --git a/lib/mipha_web/controllers/location_controller.ex b/lib/mipha_web/controllers/location_controller.ex index 16faade..1ffaa20 100644 --- a/lib/mipha_web/controllers/location_controller.ex +++ b/lib/mipha_web/controllers/location_controller.ex @@ -4,11 +4,11 @@ defmodule MiphaWeb.LocationController do alias Mipha.Accounts def index(conn, _) do - render conn, :index + render(conn, :index) end def show(conn, %{"id" => id}) do location = Accounts.get_location!(id) - render conn, :show, location: location + render(conn, :show, location: location) end end diff --git a/lib/mipha_web/controllers/notification_controller.ex b/lib/mipha_web/controllers/notification_controller.ex index 8d03ff9..96c03ba 100644 --- a/lib/mipha_web/controllers/notification_controller.ex +++ b/lib/mipha_web/controllers/notification_controller.ex @@ -12,9 +12,10 @@ defmodule MiphaWeb.NotificationController do |> Notifications.Queries.cond_user_notifications() |> Turbo.Ecto.turbo(params) - render conn, :index, + render(conn, :index, notifications: result.datas, paginate: result.paginate + ) end def make_read(conn, _params) do diff --git a/lib/mipha_web/controllers/page_controller.ex b/lib/mipha_web/controllers/page_controller.ex index bf445ec..057ef03 100644 --- a/lib/mipha_web/controllers/page_controller.ex +++ b/lib/mipha_web/controllers/page_controller.ex @@ -4,11 +4,11 @@ defmodule MiphaWeb.PageController do alias Mipha.Markdown def index(conn, _params) do - render conn, :index + render(conn, :index) end def markdown(conn, _) do - markdown_ex = Markdown.example - render conn, :markdown, markdown_ex: markdown_ex + markdown_ex = Markdown.example() + render(conn, :markdown, markdown_ex: markdown_ex) end end diff --git a/lib/mipha_web/controllers/reply_controller.ex b/lib/mipha_web/controllers/reply_controller.ex index 7ba8800..d4756f6 100644 --- a/lib/mipha_web/controllers/reply_controller.ex +++ b/lib/mipha_web/controllers/reply_controller.ex @@ -16,6 +16,7 @@ defmodule MiphaWeb.ReplyController do {:ok, %{reply: reply}} -> # broadcast topic:id broadcast!("topic:#{topic.id}", "topic:#{topic.id}:new_reply", %{reply_id: reply.id}) + conn |> put_flash(:success, "Reply created successfully.") |> redirect(to: topic_path(conn, :show, topic)) @@ -31,15 +32,17 @@ defmodule MiphaWeb.ReplyController do reply = Replies.get_reply!(id) changeset = Replies.change_reply(reply) - render conn, :edit, + render(conn, :edit, topic: topic, changeset: changeset, reply: reply, topic: topic + ) end def update(conn, %{"id" => id, "reply" => reply_params}, topic) do reply = Replies.get_reply!(id) + case Replies.update_reply(reply, reply_params) do {:ok, _} -> conn @@ -64,10 +67,12 @@ defmodule MiphaWeb.ReplyController do def star(conn, %{"reply_id" => reply_id}, topic) do reply = Replies.get_reply!(reply_id) + attrs = %{ user_id: current_user(conn).id, reply_id: reply.id } + case Stars.insert_star(attrs) do {:ok, _} -> conn @@ -83,10 +88,12 @@ defmodule MiphaWeb.ReplyController do def unstar(conn, %{"reply_id" => reply_id}, topic) do reply = Replies.get_reply!(reply_id) + attrs = [ user_id: current_user(conn).id, reply_id: reply.id ] + case Stars.delete_star(attrs) do {:ok, _} -> conn diff --git a/lib/mipha_web/controllers/search_controller.ex b/lib/mipha_web/controllers/search_controller.ex index e864052..7129e3e 100644 --- a/lib/mipha_web/controllers/search_controller.ex +++ b/lib/mipha_web/controllers/search_controller.ex @@ -4,7 +4,7 @@ defmodule MiphaWeb.SearchController do alias Mipha.{Accounts, Qiniu} def index(conn, _) do - render conn, :index + render(conn, :index) end @doc """ @@ -15,7 +15,7 @@ defmodule MiphaWeb.SearchController do conn |> current_user() |> Accounts.search_mention_user(params["q"]) - |> Enum.map(&(%{login: &1.username, avatar_url: Qiniu.q_url(&1.avatar)})) + |> Enum.map(&%{login: &1.username, avatar_url: Qiniu.q_url(&1.avatar)}) json(conn, users) end diff --git a/lib/mipha_web/controllers/session_controller.ex b/lib/mipha_web/controllers/session_controller.ex index 7451284..dce08cf 100644 --- a/lib/mipha_web/controllers/session_controller.ex +++ b/lib/mipha_web/controllers/session_controller.ex @@ -8,7 +8,7 @@ defmodule MiphaWeb.SessionController do def new(conn, _params) do changeset = Accounts.user_register_changeset() - render conn, :new, changeset: changeset + render(conn, :new, changeset: changeset) end def excaptcha(conn, _) do @@ -40,6 +40,7 @@ defmodule MiphaWeb.SessionController do case Accounts.register_user(user_params) do {:ok, user} -> sent_welcome_email(user) + conn |> ok_login(user) diff --git a/lib/mipha_web/controllers/setting_controller.ex b/lib/mipha_web/controllers/setting_controller.ex index 150dc2d..e428337 100644 --- a/lib/mipha_web/controllers/setting_controller.ex +++ b/lib/mipha_web/controllers/setting_controller.ex @@ -10,7 +10,7 @@ defmodule MiphaWeb.SettingController do def action(conn, _) do if Enum.member?(@intercepted_action, action_name(conn)) do changeset = Accounts.change_user(current_user(conn)) - render conn, action_name(conn), changeset: changeset + render(conn, action_name(conn), changeset: changeset) else apply(__MODULE__, action_name(conn), [conn, conn.params]) end @@ -18,10 +18,10 @@ defmodule MiphaWeb.SettingController do def update(conn, %{"user" => user_params}) do case user_params["by"] do - "show" -> update_account(conn, user_params) - "profile" -> update_profile(conn, user_params) - "password" -> update_password(conn, user_params) - "reward" -> update_reward(conn, user_params) + "show" -> update_account(conn, user_params) + "profile" -> update_profile(conn, user_params) + "password" -> update_password(conn, user_params) + "reward" -> update_reward(conn, user_params) end end @@ -74,6 +74,7 @@ defmodule MiphaWeb.SettingController do {:error, reason} -> changeset = Accounts.user_update_password_changeset() + conn |> put_flash(:danger, reason) |> render(:password, changeset: changeset) @@ -104,6 +105,7 @@ defmodule MiphaWeb.SettingController do end defp build_attrs({nil, params}, _), do: params + defp build_attrs({%Plug.Upload{} = avatar, params}, field) do # FIXME need set global callback with %HTTPoison.Response{status_code: 200, body: body} <- Qiniu.upload(avatar.path) do diff --git a/lib/mipha_web/controllers/team_controller.ex b/lib/mipha_web/controllers/team_controller.ex index 21ef810..00be6c2 100644 --- a/lib/mipha_web/controllers/team_controller.ex +++ b/lib/mipha_web/controllers/team_controller.ex @@ -5,26 +5,27 @@ defmodule MiphaWeb.TeamController do alias Topics.Queries def index(conn, _params) do - render conn, :index + render(conn, :index) end def show(conn, %{"id" => id} = params) do team = Accounts.get_team!(id) - team_user_ids = Enum.map(team.users, &(&1.id)) + team_user_ids = Enum.map(team.users, & &1.id) result = [user_ids: team_user_ids] - |> Queries.cond_topics + |> Queries.cond_topics() |> Turbo.Ecto.turbo(params) - render conn, :show, + render(conn, :show, team: team, topics: result.datas, paginate: result.paginate + ) end def people(conn, %{"id" => id}) do team = Accounts.get_team!(id) - render conn, :people, team: team + render(conn, :people, team: team) end end diff --git a/lib/mipha_web/controllers/topic_controller.ex b/lib/mipha_web/controllers/topic_controller.ex index 3f0ef55..d178984 100644 --- a/lib/mipha_web/controllers/topic_controller.ex +++ b/lib/mipha_web/controllers/topic_controller.ex @@ -26,25 +26,29 @@ defmodule MiphaWeb.TopicController do [type: action_name(conn)] end - parent_nodes = Topics.list_parent_nodes + parent_nodes = Topics.list_parent_nodes() + result = opts - |> Queries.cond_topics + |> Queries.cond_topics() |> Turbo.Ecto.turbo(conn.params) - render conn, action_name(conn), + render(conn, action_name(conn), asset: "topics", topics: result.datas, paginate: result.paginate, parent_nodes: parent_nodes + ) end + defp do_fragment(:suggest, conn) do topic = Topics.get_topic!(conn.params["id"]) - attrs = %{"suggested_at" => Timex.now} + attrs = %{"suggested_at" => Timex.now()} flash = gettext("Pin") do_update(conn, topic, attrs, flash) end + defp do_fragment(:unsuggest, conn) do topic = Topics.get_topic!(conn.params["id"]) attrs = %{"suggested_at" => nil} @@ -52,13 +56,15 @@ defmodule MiphaWeb.TopicController do do_update(conn, topic, attrs, flash) end + defp do_fragment(:close, conn) do topic = Topics.get_topic!(conn.params["id"]) - attrs = %{"closed_at" => Timex.now} + attrs = %{"closed_at" => Timex.now()} flash = gettext("Closed") do_update(conn, topic, attrs, flash) end + defp do_fragment(:open, conn) do topic = Topics.get_topic!(conn.params["id"]) attrs = %{"closed_at" => nil} @@ -66,6 +72,7 @@ defmodule MiphaWeb.TopicController do do_update(conn, topic, attrs, flash) end + defp do_fragment(:excellent, conn) do topic = Topics.get_topic!(conn.params["id"]) attrs = %{"type" => "featured"} @@ -73,6 +80,7 @@ defmodule MiphaWeb.TopicController do do_update(conn, topic, attrs, flash) end + defp do_fragment(:normal, conn) do topic = Topics.get_topic!(conn.params["id"]) attrs = %{"type" => "normal"} @@ -80,6 +88,7 @@ defmodule MiphaWeb.TopicController do do_update(conn, topic, attrs, flash) end + defp do_fragment(_, conn) do apply(__MODULE__, action_name(conn), [conn, conn.params]) end @@ -94,33 +103,36 @@ defmodule MiphaWeb.TopicController do end def jobs(conn, params) do - parent_nodes = Topics.list_parent_nodes - result = Turbo.Ecto.turbo(Queries.job_topics, params) + parent_nodes = Topics.list_parent_nodes() + result = Turbo.Ecto.turbo(Queries.job_topics(), params) - render conn, :jobs, + render(conn, :jobs, parent_nodes: parent_nodes, topics: result.datas, paginate: result.paginate + ) end def new(conn, _params) do changeset = Topics.change_topic() - parent_nodes = Topics.list_parent_nodes + parent_nodes = Topics.list_parent_nodes() - render conn, :new, + render(conn, :new, changeset: changeset, parent_nodes: parent_nodes + ) end def edit(conn, %{"id" => id}) do topic = Topics.get_topic!(id) changeset = Topics.change_topic(topic) - parent_nodes = Topics.list_parent_nodes + parent_nodes = Topics.list_parent_nodes() - render conn, :edit, + render(conn, :edit, topic: topic, changeset: changeset, parent_nodes: parent_nodes + ) end def create(conn, %{"topic" => topic_params}) do @@ -131,7 +143,8 @@ defmodule MiphaWeb.TopicController do |> redirect(to: topic_path(conn, :show, topic)) {:error, :topic, %Ecto.Changeset{} = changeset, _} -> - parent_nodes = Topics.list_parent_nodes + parent_nodes = Topics.list_parent_nodes() + conn |> put_flash(:danger, gettext("Create topic failed, pls select node_id.")) |> render(:new, changeset: changeset, parent_nodes: parent_nodes) @@ -140,6 +153,7 @@ defmodule MiphaWeb.TopicController do def update(conn, %{"id" => id, "topic" => topic_params}) do topic = Topics.get_topic!(id) + case Topics.update_topic(topic, topic_params) do {:ok, topic} -> conn @@ -147,8 +161,8 @@ defmodule MiphaWeb.TopicController do |> redirect(to: topic_path(conn, :show, topic)) {:error, %Ecto.Changeset{} = changeset} -> - parent_nodes = Topics.list_parent_nodes - render conn, :edit, topic: topic, changeset: changeset, parent_nodes: parent_nodes + parent_nodes = Topics.list_parent_nodes() + render(conn, :edit, topic: topic, changeset: changeset, parent_nodes: parent_nodes) end end @@ -159,6 +173,7 @@ defmodule MiphaWeb.TopicController do if is_nil(get_session(conn, "visited_topic_#{topic.id}")) do # increment topic visit count. Topics.topic_visit_counter(topic) + conn |> put_session("visited_topic_#{topic.id}", topic.id) |> render(:show, topic: topic) @@ -182,10 +197,12 @@ defmodule MiphaWeb.TopicController do def star(conn, %{"id" => id}) do topic = Topics.get_topic!(id) + attrs = %{ user_id: current_user(conn).id, topic_id: topic.id } + case Stars.insert_star(attrs) do {:ok, _} -> conn @@ -201,15 +218,18 @@ defmodule MiphaWeb.TopicController do def unstar(conn, %{"id" => id}) do topic = Topics.get_topic!(id) + attrs = [ user_id: current_user(conn).id, topic_id: topic.id ] + case Stars.delete_star(attrs) do {:ok, _} -> conn |> put_flash(:info, gettext("Unstar successfully")) |> redirect(to: topic_path(conn, :show, topic)) + {:error, _} -> conn |> put_flash(:danger, gettext("Unstar failed")) @@ -219,10 +239,12 @@ defmodule MiphaWeb.TopicController do def collection(conn, %{"id" => id}) do topic = Topics.get_topic!(id) + attrs = %{ user_id: current_user(conn).id, topic_id: topic.id } + case Collections.insert_collection(attrs) do {:ok, _} -> conn @@ -238,10 +260,12 @@ defmodule MiphaWeb.TopicController do def uncollection(conn, %{"id" => id}) do topic = Topics.get_topic!(id) + attrs = [ user_id: current_user(conn).id, topic_id: topic.id ] + case Collections.delete_collection(attrs) do {:ok, _} -> conn diff --git a/lib/mipha_web/controllers/user_controller.ex b/lib/mipha_web/controllers/user_controller.ex index dcc4bc7..5613638 100644 --- a/lib/mipha_web/controllers/user_controller.ex +++ b/lib/mipha_web/controllers/user_controller.ex @@ -14,7 +14,8 @@ defmodule MiphaWeb.UserController do |> put_flash(:danger, gettext("User not exist.")) |> redirect(to: "/") - user -> apply(__MODULE__, action_name(conn), [conn, conn.params, user]) + user -> + apply(__MODULE__, action_name(conn), [conn, conn.params, user]) end else apply(__MODULE__, action_name(conn), [conn, conn.params]) @@ -25,64 +26,71 @@ defmodule MiphaWeb.UserController do users = Accounts.Queries.list_users() |> Turbo.Ecto.search(params) user_count = Accounts.get_user_count() - render conn, :index, + render(conn, :index, users: users, user_count: user_count + ) end def show(conn, _params, user) do topics = Topics.recent_topics(user) replies = Replies.recent_replies(user) - render conn, :show, + render(conn, :show, user: user, topics: topics, replies: replies + ) end def topics(conn, params, user) do - result = Topics.Queries.cond_topics([user: user]) |> Turbo.Ecto.turbo(params) + result = Topics.Queries.cond_topics(user: user) |> Turbo.Ecto.turbo(params) - render conn, :topics, + render(conn, :topics, user: user, paginate: result.paginate, topics: result.datas + ) end def replies(conn, params, user) do - result = Replies.Queries.cond_replies([user: user]) |> Turbo.Ecto.turbo(params) + result = Replies.Queries.cond_replies(user: user) |> Turbo.Ecto.turbo(params) - render conn, :replies, + render(conn, :replies, user: user, paginate: result.paginate, replies: result.datas + ) end def following(conn, params, user) do - result = Follows.Queries.cond_follows([follower: user]) |> Turbo.Ecto.turbo(params) + result = Follows.Queries.cond_follows(follower: user) |> Turbo.Ecto.turbo(params) - render conn, :following, + render(conn, :following, user: user, paginate: result.paginate, following: result.datas + ) end def followers(conn, params, user) do - result = Follows.Queries.cond_follows([user: user]) |> Turbo.Ecto.turbo(params) + result = Follows.Queries.cond_follows(user: user) |> Turbo.Ecto.turbo(params) - render conn, :followers, + render(conn, :followers, user: user, paginate: result.paginate, followers: result.datas + ) end def collections(conn, params, user) do - result = Collections.Queries.cond_collections([user: user]) |> Turbo.Ecto.turbo(params) + result = Collections.Queries.cond_collections(user: user) |> Turbo.Ecto.turbo(params) - render conn, :collections, + render(conn, :collections, user: user, paginate: result.paginate, collections: result.datas + ) end def follow(conn, _params, user) do @@ -125,8 +133,7 @@ defmodule MiphaWeb.UserController do def sent_forgot_password_email(conn, %{"user" => user_params}) do with {:ok, email} <- parse(user_params["email"]), - {:ok, user} <- parse(Accounts.get_user_by_email(email)) - do + {:ok, user} <- parse(Accounts.get_user_by_email(email)) do # Send email user |> Token.generate_token() @@ -145,7 +152,7 @@ defmodule MiphaWeb.UserController do end def forgot_password(conn, _) do - render conn, :forgot_password + render(conn, :forgot_password) end def reset_password(conn, %{"token" => token}) do @@ -153,12 +160,13 @@ defmodule MiphaWeb.UserController do user = Accounts.get_user!(user_id) changeset = Accounts.change_user_reset_password(user) - render conn, :reset_password, + render(conn, :reset_password, user: user, token: token, changeset: changeset + ) else - _ -> render conn, :invalid_token + _ -> render(conn, :invalid_token) end end @@ -170,9 +178,9 @@ defmodule MiphaWeb.UserController do def update_password(conn, %{"user" => user_params}) do with {:ok, token} <- parse(user_params["reset_password_token"]), - {:ok, user_id} <- Token.verify_token(token) - do + {:ok, user_id} <- Token.verify_token(token) do user = Accounts.get_user!(user_id) + case Accounts.update_reset_password(user, user_params) do {:ok, _} -> conn @@ -180,13 +188,14 @@ defmodule MiphaWeb.UserController do |> redirect(to: "/login") {:error, %Ecto.Changeset{} = changeset} -> - render conn, :reset_password, + render(conn, :reset_password, changeset: changeset, user: user, token: token + ) end else - _ -> render conn, :invalid_token + _ -> render(conn, :invalid_token) end end diff --git a/lib/mipha_web/endpoint.ex b/lib/mipha_web/endpoint.ex index 5462e30..2069167 100644 --- a/lib/mipha_web/endpoint.ex +++ b/lib/mipha_web/endpoint.ex @@ -1,20 +1,22 @@ defmodule MiphaWeb.Endpoint do use Phoenix.Endpoint, otp_app: :mipha - socket "/socket", MiphaWeb.UserSocket + socket("/socket", MiphaWeb.UserSocket) # Serve at "/" the static files from "priv/static" directory. # # You should set gzip to true if you are running phoenix.digest # when deploying your static files in production. plug Plug.Static, - at: "/", from: :mipha, gzip: false, + at: "/", + from: :mipha, + gzip: false, only: ~w(css fonts images js favicon.ico robots.txt) # Code reloading can be explicitly enabled under the # :code_reloader configuration of your endpoint. if code_reloading? do - socket "/phoenix/live_reload/socket", Phoenix.LiveReloader.Socket + socket("/phoenix/live_reload/socket", Phoenix.LiveReloader.Socket) plug Phoenix.LiveReloader plug Phoenix.CodeReloader end diff --git a/lib/mipha_web/plugs/attack.ex b/lib/mipha_web/plugs/attack.ex index 88f24f0..96b41c9 100644 --- a/lib/mipha_web/plugs/attack.ex +++ b/lib/mipha_web/plugs/attack.ex @@ -8,25 +8,31 @@ defmodule MiphaWeb.Plug.Attack do rule("throttle by ip every 2 minutes only allow register 10 person", conn) do if conn.method == "POST" and conn.path_info == ["join"] do - throttle conn.remote_ip, - period: 120_000, limit: 10, + throttle(conn.remote_ip, + period: 120_000, + limit: 10, storage: {PlugAttack.Storage.Ets, Mipha.PlugAttack.Storage} + ) end end rule("throttle by ip every 1 hours only allow create 20 topic", conn) do if conn.method == "POST" and conn.path_info == ["topics"] do - throttle conn.remote_ip, - period: 3_600_000, limit: 20, + throttle(conn.remote_ip, + period: 3_600_000, + limit: 20, storage: {PlugAttack.Storage.Ets, Mipha.PlugAttack.Storage} + ) end end rule("throttle by ip every 2 minutes only allow create 20 reply", conn) do if conn.method == "POST" and conn.path_info == ["topics"] do - throttle conn.remote_ip, - period: 120_000, limit: 20, + throttle(conn.remote_ip, + period: 120_000, + limit: 20, storage: {PlugAttack.Storage.Ets, Mipha.PlugAttack.Storage} + ) end end diff --git a/lib/mipha_web/plugs/locale.ex b/lib/mipha_web/plugs/locale.ex index c412b17..0b742cd 100644 --- a/lib/mipha_web/plugs/locale.ex +++ b/lib/mipha_web/plugs/locale.ex @@ -9,8 +9,10 @@ defmodule MiphaWeb.Plug.Locale do def call(conn, _opts) do case conn.params["locale"] || get_session(conn, :locale) do - nil -> conn - locale -> + nil -> + conn + + locale -> Gettext.put_locale(MiphaWeb.Gettext, locale) conn |> put_session(:locale, locale) end diff --git a/lib/mipha_web/router.ex b/lib/mipha_web/router.ex index d94a8df..b43c12f 100644 --- a/lib/mipha_web/router.ex +++ b/lib/mipha_web/router.ex @@ -24,7 +24,7 @@ defmodule MiphaWeb.Router do end scope "/auth", MiphaWeb do - pipe_through :browser + pipe_through(:browser) get "/:provider", AuthController, :request get "/:provider/callback", AuthController, :callback @@ -33,28 +33,28 @@ defmodule MiphaWeb.Router do scope "/", MiphaWeb do # Use the default browser stack - pipe_through :browser - - get "/", TopicController, :index - get "/search", SearchController, :index - get "/search/users", SearchController, :users - get "/markdown", PageController, :markdown - get "/join", SessionController, :new, as: :join - post "/join", SessionController, :create, as: :join - get "/excaptcha", SessionController, :excaptcha - get "/login", AuthController, :login - get "/logout", AuthController, :delete, as: :logout - - get "/u/:name", UserController, :show - get "/u/:name/topics", UserController, :topics, as: :user_topics - get "/u/:name/replies", UserController, :replies, as: :user_replies - get "/u/:name/stars", UserController, :stars, as: :user_stars - get "/u/:name/collections", UserController, :collections, as: :user_collections - post "/u/:name/follow", UserController, :follow, as: :user_follow - post "/u/:name/unfollow", UserController, :unfollow, as: :user_unfollow - get "/u/:name/followers", UserController, :followers, as: :user_followers - get "/u/:name/following", UserController, :following, as: :user_following - get "/u/:name/reward", UserController, :reward, as: :user_reward + pipe_through(:browser) + + get "/", TopicController, :index + get "/search", SearchController, :index + get "/search/users", SearchController, :users + get "/markdown", PageController, :markdown + get("/join", SessionController, :new, as: :join) + post("/join", SessionController, :create, as: :join) + get "/excaptcha", SessionController, :excaptcha + get "/login", AuthController, :login + get("/logout", AuthController, :delete, as: :logout) + + get "/u/:name", UserController, :show + get("/u/:name/topics", UserController, :topics, as: :user_topics) + get("/u/:name/replies", UserController, :replies, as: :user_replies) + get("/u/:name/stars", UserController, :stars, as: :user_stars) + get("/u/:name/collections", UserController, :collections, as: :user_collections) + post("/u/:name/follow", UserController, :follow, as: :user_follow) + post("/u/:name/unfollow", UserController, :unfollow, as: :user_unfollow) + get("/u/:name/followers", UserController, :followers, as: :user_followers) + get("/u/:name/following", UserController, :following, as: :user_following) + get("/u/:name/reward", UserController, :reward, as: :user_reward) get "/users", UserController, :index get "/forgot_password", UserController, :forgot_password @@ -63,7 +63,7 @@ defmodule MiphaWeb.Router do put "/users/update_password", UserController, :update_password post "/users/sent_forgot_password_email", UserController, :sent_forgot_password_email post "/users/sent_verify_email", UserController, :sent_verify_email - resources "/teams", TeamController + resources("/teams", TeamController) get "/teams/:id/people", TeamController, :people # topic @@ -91,44 +91,44 @@ defmodule MiphaWeb.Router do end end - resources "/notifications", NotificationController, only: ~w(index)a + resources("/notifications", NotificationController, only: ~w(index)a) post "/notifications/make_read", NotificationController, :make_read delete "/notifications/clean", NotificationController, :clean - resources "/locations", LocationController, only: ~w(index show)a - resources "/companies", CompanyController, only: ~w(index show)a + resources("/locations", LocationController, only: ~w(index show)a) + resources("/companies", CompanyController, only: ~w(index show)a) # User profile resources "/setting", SettingController, only: ~w(show update)a, singleton: true do - get "/account", SettingController, :account, as: :account - get "/password", SettingController, :password, as: :password - get "/profile", SettingController, :profile, as: :profile - get "/reward", SettingController, :reward, as: :reward + get("/account", SettingController, :account, as: :account) + get("/password", SettingController, :password, as: :password) + get("/profile", SettingController, :profile, as: :profile) + get("/reward", SettingController, :reward, as: :reward) end end scope "/admin", MiphaWeb.Admin, as: :admin do - pipe_through ~w(browser admin)a + pipe_through(~w(browser admin)a) get "/", PageController, :index - resources "/users", UserController, only: ~w(index delete)a - resources "/nodes", NodeController - resources "/topics", TopicController, only: ~w(index)a - resources "/replies", ReplyController, only: ~w(index show delete)a - resources "/companies", CompanyController, only: ~w(index delete)a - resources "/teams", TeamController, only: ~w(index delete)a - resources "/notifications", NotificationController, only: ~w(index show delete)a + resources("/users", UserController, only: ~w(index delete)a) + resources("/nodes", NodeController) + resources("/topics", TopicController, only: ~w(index)a) + resources("/replies", ReplyController, only: ~w(index show delete)a) + resources("/companies", CompanyController, only: ~w(index delete)a) + resources("/teams", TeamController, only: ~w(index delete)a) + resources("/notifications", NotificationController, only: ~w(index show delete)a) end # Other scopes may use custom stacks. scope "/api", MiphaWeb do - pipe_through :api + pipe_through(:api) post "/topics/preview", TopicController, :preview post "/callback/qiniu", CallbackController, :qiniu end - if Mix.env == :dev do + if Mix.env() == :dev do forward "/sent_emails", Bamboo.SentEmailViewerPlug end end diff --git a/lib/mipha_web/session.ex b/lib/mipha_web/session.ex index e3b135f..b61d631 100644 --- a/lib/mipha_web/session.ex +++ b/lib/mipha_web/session.ex @@ -11,7 +11,7 @@ defmodule MiphaWeb.Session do def current_user(conn) do case get_current_user(conn) do nil -> nil - id -> Accounts.get_user(id) + id -> Accounts.get_user(id) end end @@ -27,7 +27,7 @@ defmodule MiphaWeb.Session do def admin?(conn) do case current_user(conn) do nil -> false - u -> u.is_admin + u -> u.is_admin end end @@ -35,7 +35,7 @@ defmodule MiphaWeb.Session do if get_session_from_cookies() do case conn.cookies["current_user"] do nil -> Conn.get_session(conn, :current_user) - u -> u + u -> u end else Conn.get_session(conn, :current_user) diff --git a/lib/mipha_web/views/error_helpers.ex b/lib/mipha_web/views/error_helpers.ex index 2f235db..0ab55c7 100644 --- a/lib/mipha_web/views/error_helpers.ex +++ b/lib/mipha_web/views/error_helpers.ex @@ -9,8 +9,8 @@ defmodule MiphaWeb.ErrorHelpers do Generates tag for inlined form input errors. """ def error_tag(form, field) do - Enum.map(Keyword.get_values(form.errors, field), fn (error) -> - content_tag :span, translate_error(error), class: "help-block" + Enum.map(Keyword.get_values(form.errors, field), fn error -> + content_tag(:span, translate_error(error), class: "help-block") end) end diff --git a/lib/mipha_web/views/notification_view.ex b/lib/mipha_web/views/notification_view.ex index 60bbfd7..c8eade1 100644 --- a/lib/mipha_web/views/notification_view.ex +++ b/lib/mipha_web/views/notification_view.ex @@ -5,13 +5,17 @@ defmodule MiphaWeb.NotificationView do def group_by(notifications) do notifications - |> Enum.group_by(&(Timex.format!(&1.updated_at, "{YYYY}-{0M}-{D}"))) + |> Enum.group_by(&Timex.format!(&1.updated_at, "{YYYY}-{0M}-{D}")) end def transfer_action(notification) do target_object = Notifications.object(notification) actor = Notifications.actor(notification) - render("_#{Atom.to_string(notification.action)}.html", actor: actor, target_object: target_object) + + render("_#{Atom.to_string(notification.action)}.html", + actor: actor, + target_object: target_object + ) end def hour_format(notification) do diff --git a/lib/mipha_web/views/setting_view.ex b/lib/mipha_web/views/setting_view.ex index d152243..10def03 100644 --- a/lib/mipha_web/views/setting_view.ex +++ b/lib/mipha_web/views/setting_view.ex @@ -7,7 +7,7 @@ defmodule MiphaWeb.SettingView do location select option """ def location_option do - Accounts.list_locations + Accounts.list_locations() |> Enum.map(&{&1.name, &1.id}) end end diff --git a/lib/mipha_web/views/tag_helpers.ex b/lib/mipha_web/views/tag_helpers.ex index 7576a14..5e68dda 100644 --- a/lib/mipha_web/views/tag_helpers.ex +++ b/lib/mipha_web/views/tag_helpers.ex @@ -24,8 +24,8 @@ defmodule MiphaWeb.TagHelpers do Returns user level. """ def user_level_tag(user) do - level_name = user.is_admin && "管理员" || "会员" - level_class = user.is_admin && "badge-alert" || "badge-success" + level_name = (user.is_admin && "管理员") || "会员" + level_class = (user.is_admin && "badge-alert") || "badge-success" content_tag(:span, level_name, class: "badge #{level_class} role") end @@ -33,7 +33,7 @@ defmodule MiphaWeb.TagHelpers do Return if rem(number) == 0, return odd, else return even. """ def cycle_tag(number) do - Integer.is_odd(number) && "odd" || "even" + (Integer.is_odd(number) && "odd") || "even" end @doc """ @@ -50,7 +50,9 @@ defmodule MiphaWeb.TagHelpers do end def topic_title_tag(topic, reply \\ nil) do - ahref = if is_nil(reply), do: "/topics/#{topic.id}", else: "/topics/#{topic.id}#reply#{reply.id}" + ahref = + if is_nil(reply), do: "/topics/#{topic.id}", else: "/topics/#{topic.id}#reply#{reply.id}" + content_tag(:a, topic.title, href: ahref, title: topic.title) end diff --git a/lib/mipha_web/views/view_helpers.ex b/lib/mipha_web/views/view_helpers.ex index 8d77563..d7a4476 100644 --- a/lib/mipha_web/views/view_helpers.ex +++ b/lib/mipha_web/views/view_helpers.ex @@ -7,7 +7,7 @@ defmodule MiphaWeb.ViewHelpers do def markdown(body) do body - |> Markdown.render + |> Markdown.render() |> raw() end end diff --git a/mix.exs b/mix.exs index 8e3837d..fffacb8 100644 --- a/mix.exs +++ b/mix.exs @@ -6,13 +6,18 @@ defmodule Mipha.Mixfile do app: :mipha, version: "0.0.1", elixir: "~> 1.4", - elixirc_paths: elixirc_paths(Mix.env), - compilers: [:phoenix, :gettext] ++ Mix.compilers, - start_permanent: Mix.env == :prod, + elixirc_paths: elixirc_paths(Mix.env()), + compilers: [:phoenix, :gettext] ++ Mix.compilers(), + start_permanent: Mix.env() == :prod, aliases: aliases(), deps: deps(), test_coverage: [tool: ExCoveralls], - preferred_cli_env: [coveralls: :test, "coveralls.detail": :test, "coveralls.post": :test, "coveralls.html": :test] + preferred_cli_env: [ + coveralls: :test, + "coveralls.detail": :test, + "coveralls.post": :test, + "coveralls.html": :test + ] ] end @@ -28,7 +33,7 @@ defmodule Mipha.Mixfile do # Specifies which paths to compile per environment. defp elixirc_paths(:test), do: ["lib", "test/support"] - defp elixirc_paths(_), do: ["lib"] + defp elixirc_paths(_), do: ["lib"] # Specifies your project dependencies. # @@ -68,7 +73,7 @@ defmodule Mipha.Mixfile do {:plug_attack, "~> 0.3.1"}, {:sentry, "~> 6.4"}, {:ex_machina, "~> 2.2"}, - {:excoveralls, "~> 0.10", only: :test}, + {:excoveralls, "~> 0.10", only: :test} ] end diff --git a/priv/repo/migrations/20180629095811_create_users.exs b/priv/repo/migrations/20180629095811_create_users.exs index 1fbeb97..43838b4 100644 --- a/priv/repo/migrations/20180629095811_create_users.exs +++ b/priv/repo/migrations/20180629095811_create_users.exs @@ -3,27 +3,27 @@ defmodule Mipha.Repo.Migrations.CreateUsers do def change do create table(:users) do - add :username, :string - add :email, :string - add :email_public, :boolean - add :email_verified_at, :naive_datetime - add :password_hash, :string - add :avatar, :string - add :bio, :string - add :tagline, :string - add :website, :string - add :github_handle, :string - add :is_admin, :boolean, default: false, null: false - add :location_id, :integer - add :company_id, :integer - add :wechat, :string - add :alipay, :string - add :locked_at, :naive_datetime + add(:username, :string) + add(:email, :string) + add(:email_public, :boolean) + add(:email_verified_at, :naive_datetime) + add(:password_hash, :string) + add(:avatar, :string) + add(:bio, :string) + add(:tagline, :string) + add(:website, :string) + add(:github_handle, :string) + add(:is_admin, :boolean, default: false, null: false) + add(:location_id, :integer) + add(:company_id, :integer) + add(:wechat, :string) + add(:alipay, :string) + add(:locked_at, :naive_datetime) timestamps() end - create unique_index(:users, [:username]) - create unique_index(:users, [:email]) + create(unique_index(:users, [:username])) + create(unique_index(:users, [:email])) end end diff --git a/priv/repo/migrations/20180702075249_create_topics.exs b/priv/repo/migrations/20180702075249_create_topics.exs index 27406e8..25f3919 100644 --- a/priv/repo/migrations/20180702075249_create_topics.exs +++ b/priv/repo/migrations/20180702075249_create_topics.exs @@ -3,23 +3,23 @@ defmodule Mipha.Repo.Migrations.CreateTopics do def change do create table(:topics) do - add :title, :string - add :body, :text - add :closed_at, :naive_datetime - add :user_id, :integer - add :type, :string - add :node_id, :integer - add :visit_count, :integer - add :reply_count, :integer - add :last_reply_id, :integer - add :last_reply_user_id, :integer - add :replied_at, :naive_datetime - add :suggested_at, :naive_datetime - add :star_count, :integer + add(:title, :string) + add(:body, :text) + add(:closed_at, :naive_datetime) + add(:user_id, :integer) + add(:type, :string) + add(:node_id, :integer) + add(:visit_count, :integer) + add(:reply_count, :integer) + add(:last_reply_id, :integer) + add(:last_reply_user_id, :integer) + add(:replied_at, :naive_datetime) + add(:suggested_at, :naive_datetime) + add(:star_count, :integer) timestamps() end - create index(:topics, [:user_id]) + create(index(:topics, [:user_id])) end end diff --git a/priv/repo/migrations/20180702081217_create_replies.exs b/priv/repo/migrations/20180702081217_create_replies.exs index e3b4988..9bb7a7e 100644 --- a/priv/repo/migrations/20180702081217_create_replies.exs +++ b/priv/repo/migrations/20180702081217_create_replies.exs @@ -3,14 +3,13 @@ defmodule Mipha.Repo.Migrations.CreateReplies do def change do create table(:replies) do - add :topic_id, :integer - add :user_id, :integer - add :parent_id, :integer - add :content, :text - add :star_count, :integer + add(:topic_id, :integer) + add(:user_id, :integer) + add(:parent_id, :integer) + add(:content, :text) + add(:star_count, :integer) timestamps() end - end end diff --git a/priv/repo/migrations/20180702081845_create_nodes.exs b/priv/repo/migrations/20180702081845_create_nodes.exs index 96e5c8b..ade2246 100644 --- a/priv/repo/migrations/20180702081845_create_nodes.exs +++ b/priv/repo/migrations/20180702081845_create_nodes.exs @@ -3,13 +3,12 @@ defmodule Mipha.Repo.Migrations.CreateNodes do def change do create table(:nodes) do - add :name, :string - add :summary, :string - add :position, :integer - add :parent_id, :integer + add(:name, :string) + add(:summary, :string) + add(:position, :integer) + add(:parent_id, :integer) timestamps() end - end end diff --git a/priv/repo/migrations/20180703094024_create_locations.exs b/priv/repo/migrations/20180703094024_create_locations.exs index 640cbff..009defb 100644 --- a/priv/repo/migrations/20180703094024_create_locations.exs +++ b/priv/repo/migrations/20180703094024_create_locations.exs @@ -3,10 +3,9 @@ defmodule Mipha.Repo.Migrations.CreateLocations do def change do create table(:locations) do - add :name, :string + add(:name, :string) timestamps() end - end end diff --git a/priv/repo/migrations/20180704024042_create_collections.exs b/priv/repo/migrations/20180704024042_create_collections.exs index bb41baf..89045d1 100644 --- a/priv/repo/migrations/20180704024042_create_collections.exs +++ b/priv/repo/migrations/20180704024042_create_collections.exs @@ -3,11 +3,10 @@ defmodule Mipha.Repo.Migrations.CreateCollections do def change do create table(:collections) do - add :user_id, :integer - add :topic_id, :integer + add(:user_id, :integer) + add(:topic_id, :integer) timestamps() end - end end diff --git a/priv/repo/migrations/20180704024600_create_follows.exs b/priv/repo/migrations/20180704024600_create_follows.exs index be6757a..851874c 100644 --- a/priv/repo/migrations/20180704024600_create_follows.exs +++ b/priv/repo/migrations/20180704024600_create_follows.exs @@ -3,12 +3,12 @@ defmodule Mipha.Repo.Migrations.CreateFollows do def change do create table(:follows) do - add :user_id, :integer - add :follower_id, :integer + add(:user_id, :integer) + add(:follower_id, :integer) timestamps() end - create unique_index(:follows, [:follower_id, :user_id]) + create(unique_index(:follows, [:follower_id, :user_id])) end end diff --git a/priv/repo/migrations/20180704025308_create_stars.exs b/priv/repo/migrations/20180704025308_create_stars.exs index 602defc..bed69ad 100644 --- a/priv/repo/migrations/20180704025308_create_stars.exs +++ b/priv/repo/migrations/20180704025308_create_stars.exs @@ -3,14 +3,14 @@ defmodule Mipha.Repo.Migrations.CreateStars do def change do create table(:stars) do - add :user_id, :integer - add :reply_id, :integer - add :topic_id, :integer + add(:user_id, :integer) + add(:reply_id, :integer) + add(:topic_id, :integer) timestamps() end - create unique_index(:stars, [:user_id, :topic_id]) - create unique_index(:stars, [:user_id, :reply_id]) + create(unique_index(:stars, [:user_id, :topic_id])) + create(unique_index(:stars, [:user_id, :reply_id])) end end diff --git a/priv/repo/migrations/20180704032212_create_companies.exs b/priv/repo/migrations/20180704032212_create_companies.exs index 65100e8..8eeedc6 100644 --- a/priv/repo/migrations/20180704032212_create_companies.exs +++ b/priv/repo/migrations/20180704032212_create_companies.exs @@ -3,9 +3,9 @@ defmodule Mipha.Repo.Migrations.CreateCompanies do def change do create table(:companies) do - add :name, :string - add :avatar, :string - add :location_id, :integer + add(:name, :string) + add(:avatar, :string) + add(:location_id, :integer) timestamps() end diff --git a/priv/repo/migrations/20180704053120_create_teams.exs b/priv/repo/migrations/20180704053120_create_teams.exs index f5b7580..9062b29 100644 --- a/priv/repo/migrations/20180704053120_create_teams.exs +++ b/priv/repo/migrations/20180704053120_create_teams.exs @@ -3,19 +3,18 @@ defmodule Mipha.Repo.Migrations.CreateTeams do def change do create table(:teams) do - add :owner_id, :integer - add :github_handle, :string - add :name, :string - add :summary, :string - add :avatar, :string - add :email, :string - add :email_public, :boolean - add :twitter_handle, :string - add :slug, :string - add :website, :string + add(:owner_id, :integer) + add(:github_handle, :string) + add(:name, :string) + add(:summary, :string) + add(:avatar, :string) + add(:email, :string) + add(:email_public, :boolean) + add(:twitter_handle, :string) + add(:slug, :string) + add(:website, :string) timestamps() end - end end diff --git a/priv/repo/migrations/20180704053159_create_users_teams.exs b/priv/repo/migrations/20180704053159_create_users_teams.exs index 6cbf5c2..82b6077 100644 --- a/priv/repo/migrations/20180704053159_create_users_teams.exs +++ b/priv/repo/migrations/20180704053159_create_users_teams.exs @@ -3,13 +3,12 @@ defmodule Mipha.Repo.Migrations.CreateUsersTeams do def change do create table(:users_teams) do - add :user_id, :integer - add :team_id, :integer - add :role, :string - add :status, :string + add(:user_id, :integer) + add(:team_id, :integer) + add(:role, :string) + add(:status, :string) timestamps() end - end end diff --git a/priv/repo/migrations/20180712015550_create_notifications.exs b/priv/repo/migrations/20180712015550_create_notifications.exs index d664195..84ad3e0 100644 --- a/priv/repo/migrations/20180712015550_create_notifications.exs +++ b/priv/repo/migrations/20180712015550_create_notifications.exs @@ -3,14 +3,13 @@ defmodule Mipha.Repo.Migrations.CreateNotifications do def change do create table(:notifications) do - add :action, :string - add :actor_id, :integer - add :reply_id, :integer - add :user_id, :integer - add :topic_id, :integer + add(:action, :string) + add(:actor_id, :integer) + add(:reply_id, :integer) + add(:user_id, :integer) + add(:topic_id, :integer) timestamps() end - end end diff --git a/priv/repo/migrations/20180712015614_create_users_notifications.exs b/priv/repo/migrations/20180712015614_create_users_notifications.exs index 294eec8..cbffb95 100644 --- a/priv/repo/migrations/20180712015614_create_users_notifications.exs +++ b/priv/repo/migrations/20180712015614_create_users_notifications.exs @@ -3,12 +3,11 @@ defmodule Mipha.Repo.Migrations.CreateUsersNotifications do def change do create table(:users_notifications) do - add :user_id, :integer - add :notification_id, :integer - add :read_at, :naive_datetime + add(:user_id, :integer) + add(:notification_id, :integer) + add(:read_at, :naive_datetime) timestamps() end - end end diff --git a/priv/repo/seeds.exs b/priv/repo/seeds.exs index 611f60c..26e70ca 100644 --- a/priv/repo/seeds.exs +++ b/priv/repo/seeds.exs @@ -8,83 +8,92 @@ alias Accounts.{User, Location, Company, Team} alias Topics.{Topic, Node} # Gen three locations -beijing = Repo.insert! %Location{name: "北京"} -hangzhou = Repo.insert! %Location{name: "杭州"} +beijing = Repo.insert!(%Location{name: "北京"}) +hangzhou = Repo.insert!(%Location{name: "杭州"}) -helijia = Repo.insert! %Company{ - name: "河狸家", - location: beijing -} +helijia = + Repo.insert!(%Company{ + name: "河狸家", + location: beijing + }) -qhwa = User.register_changeset(%User{}, %{ - username: "qhwa", - email: "qhwa@mipha.com", - password: "123123123", - is_admin: true, - bio: Faker.Lorem.sentence(10), - website: Faker.Internet.domain_name, - github_handle: "qhwa", - location_id: beijing.id, - company_id: helijia.id -}) |> Repo.insert! +qhwa = + User.register_changeset(%User{}, %{ + username: "qhwa", + email: "qhwa@mipha.com", + password: "123123123", + is_admin: true, + bio: Faker.Lorem.sentence(10), + website: Faker.Internet.domain_name(), + github_handle: "qhwa", + location_id: beijing.id, + company_id: helijia.id + }) + |> Repo.insert!() -zven = User.register_changeset(%User{}, %{ - username: "zven", - email: "zven@mipha.com", - password: "123123123", - bio: Faker.Lorem.sentence(10), - website: Faker.Internet.domain_name, - github_handle: "zven21", - location_id: beijing.id, - company_id: helijia.id -}) |> Repo.insert! +zven = + User.register_changeset(%User{}, %{ + username: "zven", + email: "zven@mipha.com", + password: "123123123", + bio: Faker.Lorem.sentence(10), + website: Faker.Internet.domain_name(), + github_handle: "zven21", + location_id: beijing.id, + company_id: helijia.id + }) + |> Repo.insert!() -bencode = User.register_changeset(%User{}, %{ - username: "bencode", - email: "bencode@mipha.com", - password: "123123123", - bio: Faker.Lorem.sentence(10), - website: Faker.Internet.domain_name, - github_handle: "bencode", - location_id: hangzhou.id -}) |> Repo.insert! +bencode = + User.register_changeset(%User{}, %{ + username: "bencode", + email: "bencode@mipha.com", + password: "123123123", + bio: Faker.Lorem.sentence(10), + website: Faker.Internet.domain_name(), + github_handle: "bencode", + location_id: hangzhou.id + }) + |> Repo.insert!() # Gen teams helijia_web -Repo.insert! %Team{ +Repo.insert!(%Team{ name: "helijia-web", summary: Faker.Lorem.sentence(10), owner: zven, github_handle: "helijia-web", - avatar: Faker.Avatar.image_url, + avatar: Faker.Avatar.image_url(), users: [qhwa, zven, bencode] -} +}) for parent_node <- ~w(ruby elixir erlang) do - node = Repo.insert! %Node{ - name: parent_node, - summary: Faker.Lorem.sentence(10), - position: 1..10 |> Enum.random - } + node = + Repo.insert!(%Node{ + name: parent_node, + summary: Faker.Lorem.sentence(10), + position: 1..10 |> Enum.random() + }) + for idx <- 1..3 do - Repo.insert! %Node{ + Repo.insert!(%Node{ name: "#{node.name}-node#{idx}", summary: Faker.Lorem.sentence(10), parent: node, - position: 1..10 |> Enum.random - } + position: 1..10 |> Enum.random() + }) end end for _ <- 1..10 do - sample_user = Repo.all(User) |> Enum.random - sample_node = Repo.all(Node.is_child) |> Enum.random + sample_user = Repo.all(User) |> Enum.random() + sample_node = Repo.all(Node.is_child()) |> Enum.random() - Repo.insert! %Topic{ + Repo.insert!(%Topic{ title: Faker.Lorem.sentence(10), body: Faker.Lorem.sentence(10), last_reply_user: sample_user, node: sample_node, type: Enum.random(~w(normal featured educational job)), - user: Repo.all(User) |> Enum.random - } -end \ No newline at end of file + user: Repo.all(User) |> Enum.random() + }) +end diff --git a/test/mipha/accounts/accounts_test.exs b/test/mipha/accounts/accounts_test.exs index f3be4a6..ae4686e 100644 --- a/test/mipha/accounts/accounts_test.exs +++ b/test/mipha/accounts/accounts_test.exs @@ -120,7 +120,7 @@ defmodule Mipha.AccountsTest do test "get_location!/1 returns the location with given id" do location = location_fixture() - assert Accounts.get_location!(location.id) == (location |> Repo.preload([:users])) + assert Accounts.get_location!(location.id) == location |> Repo.preload([:users]) end test "create_location/1 with valid data creates a location" do @@ -142,7 +142,7 @@ defmodule Mipha.AccountsTest do test "update_location/2 with invalid data returns error changeset" do location = location_fixture() assert {:error, %Ecto.Changeset{}} = Accounts.update_location(location, @invalid_attrs) - assert (location |> Repo.preload([:users])) == Accounts.get_location!(location.id) + assert location |> Repo.preload([:users]) == Accounts.get_location!(location.id) end test "delete_location/1 deletes the location" do @@ -217,8 +217,20 @@ defmodule Mipha.AccountsTest do describe "teams" do alias Mipha.Accounts.Team - @valid_attrs %{avatar: "some avatar", github_handle: "some github_handle", name: "some name", owner_id: 42, summary: "some summary"} - @update_attrs %{avatar: "some updated avatar", github_handle: "some updated github_handle", name: "some updated name", owner_id: 43, summary: "some updated summary"} + @valid_attrs %{ + avatar: "some avatar", + github_handle: "some github_handle", + name: "some name", + owner_id: 42, + summary: "some summary" + } + @update_attrs %{ + avatar: "some updated avatar", + github_handle: "some updated github_handle", + name: "some updated name", + owner_id: 43, + summary: "some updated summary" + } @invalid_attrs %{avatar: nil, github_handle: nil, name: nil, owner_id: nil, summary: nil} def team_fixture(attrs \\ %{}) do @@ -237,7 +249,7 @@ defmodule Mipha.AccountsTest do test "get_team!/1 returns the team with given id" do team = team_fixture() - assert Accounts.get_team!(team.id) == (team |> Repo.preload([:users, :owner])) + assert Accounts.get_team!(team.id) == team |> Repo.preload([:users, :owner]) end test "create_team/1 with valid data creates a team" do @@ -267,7 +279,7 @@ defmodule Mipha.AccountsTest do test "update_team/2 with invalid data returns error changeset" do team = team_fixture() assert {:error, %Ecto.Changeset{}} = Accounts.update_team(team, @invalid_attrs) - assert (team |> Repo.preload([:users, :owner])) == Accounts.get_team!(team.id) + assert team |> Repo.preload([:users, :owner]) == Accounts.get_team!(team.id) end test "delete_team/1 deletes the team" do diff --git a/test/mipha/collections/collections_test.exs b/test/mipha/collections/collections_test.exs index d8801b3..1267470 100644 --- a/test/mipha/collections/collections_test.exs +++ b/test/mipha/collections/collections_test.exs @@ -49,7 +49,10 @@ defmodule Mipha.CollectionsTest do test "update_collection/2 with invalid data returns error changeset" do collection = collection_fixture() - assert {:error, %Ecto.Changeset{}} = Collections.update_collection(collection, @invalid_attrs) + + assert {:error, %Ecto.Changeset{}} = + Collections.update_collection(collection, @invalid_attrs) + assert collection == Collections.get_collection!(collection.id) end diff --git a/test/mipha/topics/topics_test.exs b/test/mipha/topics/topics_test.exs index e7468ff..e4b38ad 100644 --- a/test/mipha/topics/topics_test.exs +++ b/test/mipha/topics/topics_test.exs @@ -62,7 +62,15 @@ defmodule Mipha.TopicsTest do test "get_topic!/1 returns the topic with given id" do topic = topic_fixture() - assert Topics.get_topic!(topic.id) == (topic |> Repo.preload([:node, :user, :last_reply_user, [replies: [:user, [parent: :user]]]])) + + assert Topics.get_topic!(topic.id) == + topic + |> Repo.preload([ + :node, + :user, + :last_reply_user, + [replies: [:user, [parent: :user]]] + ]) end test "create_topic/1 with valid data creates a topic" do @@ -104,7 +112,10 @@ defmodule Mipha.TopicsTest do test "update_topic/2 with invalid data returns error changeset" do topic = topic_fixture() assert {:error, %Ecto.Changeset{}} = Topics.update_topic(topic, @invalid_attrs) - assert (topic |> Repo.preload([:node, :user, :last_reply_user, [replies: [:user, [parent: :user]]]])) == Topics.get_topic!(topic.id) + + assert topic + |> Repo.preload([:node, :user, :last_reply_user, [replies: [:user, [parent: :user]]]]) == + Topics.get_topic!(topic.id) end test "delete_topic/1 deletes the topic" do @@ -123,7 +134,12 @@ defmodule Mipha.TopicsTest do alias Mipha.Topics.Node @valid_attrs %{name: "some name", parent_id: 42, position: 42, summary: "some summary"} - @update_attrs %{name: "some updated name", parent_id: 43, position: 43, summary: "some updated summary"} + @update_attrs %{ + name: "some updated name", + parent_id: 43, + position: 43, + summary: "some updated summary" + } @invalid_attrs %{name: nil, parent_id: nil, position: nil, summary: nil} def node_fixture(attrs \\ %{}) do diff --git a/test/mipha_web/controllers/topic_controller_test.exs b/test/mipha_web/controllers/topic_controller_test.exs index ff1cf9b..07c78d6 100644 --- a/test/mipha_web/controllers/topic_controller_test.exs +++ b/test/mipha_web/controllers/topic_controller_test.exs @@ -226,28 +226,34 @@ defmodule MiphaWeb.TopicControllerTest do test "requires user auth on any acitons", %{conn: conn} do t = insert(:topic) - Enum.each([ - get(conn, topic_path(conn, :new)), - post(conn, topic_path(conn, :create), topic: @valid_attrs), - get(conn, topic_path(conn, :edit, t.id)), - put(conn, topic_path(conn, :update, t.id), topic: @valid_attrs), - delete(conn, topic_path(conn, :delete, t.id)), - ], fn conn -> - assert html_response(conn, 302) - end) + Enum.each( + [ + get(conn, topic_path(conn, :new)), + post(conn, topic_path(conn, :create), topic: @valid_attrs), + get(conn, topic_path(conn, :edit, t.id)), + put(conn, topic_path(conn, :update, t.id), topic: @valid_attrs), + delete(conn, topic_path(conn, :delete, t.id)) + ], + fn conn -> + assert html_response(conn, 302) + end + ) end @tag :as_user test "requires admin auth on any acitons", %{conn: conn} do t = insert(:topic) - Enum.each([ - post(conn, topic_path(conn, :unsuggest, t.id)), - post(conn, topic_path(conn, :suggest, t.id)), - post(conn, topic_path(conn, :normal, t.id)), - post(conn, topic_path(conn, :excellent, t.id)) - ], fn conn -> - assert html_response(conn, 302) - end) + Enum.each( + [ + post(conn, topic_path(conn, :unsuggest, t.id)), + post(conn, topic_path(conn, :suggest, t.id)), + post(conn, topic_path(conn, :normal, t.id)), + post(conn, topic_path(conn, :excellent, t.id)) + ], + fn conn -> + assert html_response(conn, 302) + end + ) end end diff --git a/test/mipha_web/views/error_view_test.exs b/test/mipha_web/views/error_view_test.exs index e1cead9..618ded2 100644 --- a/test/mipha_web/views/error_view_test.exs +++ b/test/mipha_web/views/error_view_test.exs @@ -5,12 +5,10 @@ defmodule MiphaWeb.ErrorViewTest do import Phoenix.View test "renders 404.html" do - assert render_to_string(MiphaWeb.ErrorView, "404.html", []) == - "Not Found" + assert render_to_string(MiphaWeb.ErrorView, "404.html", []) == "Not Found" end test "renders 500.html" do - assert render_to_string(MiphaWeb.ErrorView, "500.html", []) == - "Internal Server Error" + assert render_to_string(MiphaWeb.ErrorView, "500.html", []) == "Internal Server Error" end end diff --git a/test/support/channel_case.ex b/test/support/channel_case.ex index cdb57cc..7a9f3f0 100644 --- a/test/support/channel_case.ex +++ b/test/support/channel_case.ex @@ -27,9 +27,11 @@ defmodule MiphaWeb.ChannelCase do setup tags do :ok = Ecto.Adapters.SQL.Sandbox.checkout(Mipha.Repo) + unless tags[:async] do Ecto.Adapters.SQL.Sandbox.mode(Mipha.Repo, {:shared, self()}) end + :ok end end