Skip to content

Commit

Permalink
Merge pull request #59 from epochtalk/posts-by-thread
Browse files Browse the repository at this point in the history
Posts by thread
  • Loading branch information
unenglishable authored Sep 12, 2023
2 parents e14bee9 + bcb4db9 commit 81001a2
Show file tree
Hide file tree
Showing 49 changed files with 3,486 additions and 189 deletions.
16 changes: 15 additions & 1 deletion .iex.exs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ IEx.configure(inspect: [limit: :infinity])
alias EpochtalkServer.Repo

alias EpochtalkServer.Models.{
AutoModeration,
Ban,
BannedAddress,
Board,
Expand All @@ -14,8 +15,10 @@ alias EpochtalkServer.Models.{
Configuration,
Invitation,
Mention,
MentionIgnored,
MetadataBoard,
MetadataThread,
MetricRankMap,
Notification,
Permission,
Post,
Expand All @@ -24,11 +27,22 @@ alias EpochtalkServer.Models.{
PollResponse,
Preference,
Profile,
Rank,
Role,
RolePermission,
RoleUser,
Thread,
User
ThreadSubscription,
Trust,
TrustBoard,
TrustFeedback,
TrustMaxDepth,
User,
UserActivity,
UserIgnored,
UserThreadView,
WatchBoard,
WatchThread
}

reload = fn -> r(Enum.map(__ENV__.aliases, fn {_, module} -> module end)) end
48 changes: 47 additions & 1 deletion lib/epochtalk_server/mailer.ex
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,53 @@ defmodule EpochtalkServer.Mailer do
|> subject("[#{website_title}] Account Confirmation")
|> html_body(content)
|> deliver()
|> case do
|> handle_delivered_email()
end

@doc """
Sends thread subscription email
"""
@spec send_thread_subscription(email_data :: map) :: {:ok, term} | {:error, term}
def send_thread_subscription(%{
email: email,
id: last_post_id,
position: last_post_position,
thread_author: _thread_author,
thread_slug: thread_slug,
title: thread_title,
user_id: _user_id,
username: username
}) do
config = Application.get_env(:epochtalk_server, :frontend_config)
frontend_url = config["frontend_url"]
website_title = config["website"]["title"]
from_address = config["emailer"]["options"]["from_address"]

thread_url =
"#{frontend_url}/threads/#{thread_slug}?start=#{last_post_position}##{last_post_id}"

content =
generate_from_base_template(
"""
<h3>New replies to thread "#{thread_title}"</h3>
Hello #{username}! Please visit the link below to view new thread replies.<br /><br />
<a href="#{thread_url}">View Replies</a><br /><br />
<small>Raw thread URL: #{thread_url}</small>
""",
config
)

new()
|> to({username, email})
|> from({website_title, from_address})
|> subject("[#{website_title}] New replies to thread #{thread_title}")
|> html_body(content)
|> deliver()
|> handle_delivered_email()
end

defp handle_delivered_email(result) do
case result do
{:ok, email_metadata} ->
{:ok, email_metadata}

Expand Down
152 changes: 152 additions & 0 deletions lib/epochtalk_server/models/auto_moderation.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
defmodule EpochtalkServer.Models.AutoModeration do
use Ecto.Schema
import Ecto.Changeset
import Ecto.Query
alias EpochtalkServer.Repo
alias EpochtalkServer.Models.AutoModeration

@postgres_varchar255_max 255
@postgres_varchar1000_max 1000

@moduledoc """
`AutoModeration` model, for performing actions relating to `User` `AutoModeration`
"""
@type t :: %__MODULE__{
id: non_neg_integer | nil,
name: String.t() | nil,
description: String.t() | nil,
message: String.t() | nil,
conditions: map | nil,
actions: map | nil,
options: map | nil,
created_at: NaiveDateTime.t() | nil,
updated_at: NaiveDateTime.t() | nil
}
@derive {Jason.Encoder,
only: [
:id,
:name,
:description,
:message,
:conditions,
:actions,
:options,
:created_at,
:updated_at
]}
schema "auto_moderation" do
field :name, :string
field :description, :string
field :message, :string
field :conditions, :map
field :actions, :map
field :options, :map
field :created_at, :naive_datetime
field :updated_at, :naive_datetime
end

## === Changesets Functions ===

@doc """
Create changeset for `AutoModeration` model
"""
@spec create_changeset(
auto_moderation :: t(),
attrs :: map() | nil
) :: Ecto.Changeset.t()
def create_changeset(auto_moderation, attrs \\ %{}) do
auto_moderation
|> cast(attrs, [
:id,
:name,
:description,
:message,
:conditions,
:actions,
:options,
:created_at,
:updated_at
])
|> unique_constraint(:id, name: :auto_moderation_pkey)
|> validate_required([:name, :conditions, :actions])
|> validate_length(:name, min: 1, max: @postgres_varchar255_max)
|> validate_length(:description, max: @postgres_varchar1000_max)
|> validate_length(:message, max: @postgres_varchar1000_max)
end

@doc """
Creates an update changeset for `AutoModeration` model
"""
@spec update_changeset(auto_moderation :: t(), attrs :: map() | nil) :: Ecto.Changeset.t()
def update_changeset(auto_moderation, attrs \\ %{}) do
updated_at = NaiveDateTime.truncate(NaiveDateTime.utc_now(), :second)

auto_moderation =
auto_moderation
|> Map.put(:updated_at, updated_at)

auto_moderation
|> cast(attrs, [
:id,
:name,
:description,
:message,
:conditions,
:actions,
:options,
:created_at,
:updated_at
])
|> validate_required([
:id,
:name,
:conditions,
:actions,
:updated_at
])
end

## === Database Functions ===

@doc """
Get all `AutoModeration` rules
"""
@spec all() :: [t()]
def all() do
query = from(a in AutoModeration)
Repo.all(query)
end

@doc """
Add `AutoModeration` rule
"""
@spec add(auto_moderation_attrs :: map()) :: auto_moderation_rule :: t()
def add(auto_moderation_attrs) do
auto_moderation_cs = create_changeset(%AutoModeration{}, auto_moderation_attrs)
Repo.insert(auto_moderation_cs)
end

@doc """
Remove `AutoModeration` rule
"""
@spec remove(id :: non_neg_integer) :: {non_neg_integer(), nil | [term()]}
def remove(id) do
query =
from a in AutoModeration,
where: a.id == ^id

Repo.delete_all(query)
end

@doc """
Updates an existing `AutoModeration` rule in the database and reloads role cache
"""
@spec update(auto_moderation_attrs :: map()) ::
{:ok, auto_moderation :: Ecto.Schema.t()} | {:error, Ecto.Changeset.t()}
def update(auto_moderation_attrs) do
AutoModeration
|> Repo.get(auto_moderation_attrs["id"])
|> update_changeset(auto_moderation_attrs)
|> Repo.update()
end
end
6 changes: 3 additions & 3 deletions lib/epochtalk_server/models/ban.ex
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ defmodule EpochtalkServer.Models.Ban do
def unban_changeset(ban, attrs \\ %{}) do
now = NaiveDateTime.truncate(NaiveDateTime.utc_now(), :second)

# set ban expiration to now when unbanning
attrs =
attrs
|> Map.put(:expiration, now)
Expand Down Expand Up @@ -163,16 +164,15 @@ defmodule EpochtalkServer.Models.Ban do
def unban_by_user_id(user_id) when is_integer(user_id) do
Repo.transaction(fn ->
# delete ban role from user
RoleUser.delete_user_role(Role.get_banned_role_id(), user_id)
RoleUser.delete_banned(user_id)
# clear user malicious score
User.clear_malicious_score_by_id(user_id)

# unban the user by updating ban table
case Repo.get_by(Ban, user_id: user_id) do
nil -> {:ok, nil}
cs -> Repo.update!(unban_changeset(cs, %{user_id: user_id}))
end

# unban the user
end)
|> case do
{:ok, ban_changeset} ->
Expand Down
Loading

0 comments on commit 81001a2

Please sign in to comment.